@weapp-tailwindcss/postcss 3.3.6 → 3.3.7

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.
@@ -1,2630 +0,0 @@
1
- import { parseCssImportSpecifier } from "./resolve-DQiOQfoY.js";
2
- import { internalCssSelectorReplacer } from "./shared-CfQUwapA.js";
3
- import { postcss as postcss$1 } from "./postcss-runtime-i5rHe_mj.js";
4
- import postcssCalc from "@weapp-tailwindcss/postcss-calc";
5
- import postcss, { Declaration, rule } from "postcss";
6
- import valueParser from "postcss-value-parser";
7
- import selectorParser from "postcss-selector-parser";
8
- import { color, serializeRGB } from "@csstools/css-color-parser";
9
- import { parseComponentValue } from "@csstools/css-parser-algorithms";
10
- import { tokenize } from "@csstools/css-tokenizer";
11
- import postcssPresetEnv from "postcss-preset-env";
12
- //#region src/compat/lynx-css.ts
13
- const tailwindThemePropertyPatterns = [
14
- /^--aspect-/,
15
- /^--animate-/,
16
- /^--blur-/,
17
- /^--breakpoint-/,
18
- /^--color-/,
19
- /^--container-/,
20
- /^--drop-shadow-/,
21
- /^--ease-/,
22
- /^--default-font-/,
23
- /^--font-/,
24
- /^--font-weight-/,
25
- /^--inset-shadow-/,
26
- /^--leading-/,
27
- /^--perspective-/,
28
- /^--radius-/,
29
- /^--shadow-/,
30
- /^--text-/,
31
- /^--tracking-/,
32
- /^--spacing$/
33
- ];
34
- function isTailwindThemeProperty(property) {
35
- return tailwindThemePropertyPatterns.some((pattern) => pattern.test(property));
36
- }
37
- function isThemeScopeSelector(selector) {
38
- return selector.split(",").some((part) => {
39
- const normalized = part.trim();
40
- return normalized === ":root" || normalized === ":host";
41
- });
42
- }
43
- function collectTailwindThemeProperties(root) {
44
- const values = /* @__PURE__ */ new Map();
45
- root.walkRules((rule) => {
46
- if (!isThemeScopeSelector(rule.selector)) return;
47
- rule.walkDecls((decl) => {
48
- if (isTailwindThemeProperty(decl.prop)) values.set(decl.prop, decl.value.trim());
49
- });
50
- });
51
- return values;
52
- }
53
- function resolveThemeValue(value, properties, resolving = /* @__PURE__ */ new Set()) {
54
- if (!value.includes("var(")) return value;
55
- const parsed = valueParser(value);
56
- parsed.walk((node) => {
57
- if (node.type !== "function" || node.value.toLowerCase() !== "var") return;
58
- const property = node.nodes.find((child) => child.type === "word" && child.value.startsWith("--"))?.value;
59
- if (!property || resolving.has(property)) return;
60
- const propertyValue = properties.get(property);
61
- if (!propertyValue) return;
62
- const nextResolving = new Set(resolving);
63
- nextResolving.add(property);
64
- const resolved = resolveThemeValue(propertyValue, properties, nextResolving);
65
- const mutableNode = node;
66
- mutableNode.type = "word";
67
- mutableNode.value = resolved;
68
- delete mutableNode.nodes;
69
- });
70
- return parsed.toString();
71
- }
72
- function removeConsumedThemeProperties(root) {
73
- root.walkRules((rule) => {
74
- if (!isThemeScopeSelector(rule.selector)) return;
75
- rule.walkDecls((decl) => {
76
- if (isTailwindThemeProperty(decl.prop)) decl.remove();
77
- });
78
- if (rule.nodes.length === 0) rule.remove();
79
- });
80
- }
81
- /** 将 Lynx 原生无法继承的 Tailwind theme 变量静态化。 */
82
- function transformLynxCssCompat(css) {
83
- try {
84
- const root = postcss.parse(css);
85
- const properties = collectTailwindThemeProperties(root);
86
- if (properties.size === 0) return css;
87
- root.walkDecls((decl) => {
88
- decl.value = resolveThemeValue(decl.value, properties);
89
- });
90
- removeConsumedThemeProperties(root);
91
- postcss([postcssCalc()]).process(root, { from: void 0 }).sync();
92
- return root.toString();
93
- } catch {
94
- return css;
95
- }
96
- }
97
- //#endregion
98
- //#region src/compat/mini-program-css/cascade-layers.ts
99
- const LAYER_PATH_SEPARATOR = "";
100
- const LAYER_INSERTION_ANCHOR = "__weapp_tailwindcss_layer_anchor__";
101
- function splitLayerNames(params) {
102
- return params.split(",").map((name) => name.trim()).filter(Boolean);
103
- }
104
- function splitLayerPath(name) {
105
- return name.split(".").map((segment) => segment.trim()).filter(Boolean);
106
- }
107
- function createLayerPath(segments) {
108
- return {
109
- key: segments.join(LAYER_PATH_SEPARATOR),
110
- segments
111
- };
112
- }
113
- function isContainer(node) {
114
- return "nodes" in node && Array.isArray(node.nodes);
115
- }
116
- function cloneWrapper(node, children) {
117
- const wrapper = node.clone({ nodes: [] });
118
- wrapper.append(...children);
119
- return wrapper;
120
- }
121
- function wrapLayerNodes(atRule, nodes, root) {
122
- let wrapped = nodes;
123
- let parent = atRule.parent;
124
- while (parent && parent !== root) {
125
- if (parent.type !== "atrule" || parent.name !== "layer") {
126
- if (isContainer(parent)) wrapped = [cloneWrapper(parent, wrapped)];
127
- }
128
- parent = parent.parent;
129
- }
130
- return wrapped;
131
- }
132
- function removeEmptyLayerAncestors(node, root) {
133
- let parent = node.parent;
134
- node.remove();
135
- while (parent && parent !== root && parent.type === "atrule" && parent.nodes?.length === 0) {
136
- const nextParent = parent.parent;
137
- parent.remove();
138
- parent = nextParent;
139
- }
140
- }
141
- function isLayerDescendant(candidate, parent) {
142
- return candidate.length > parent.length && parent.every((segment, index) => candidate[index] === segment);
143
- }
144
- function findParentLayerPath(atRule, paths) {
145
- let parent = atRule.parent;
146
- while (parent) {
147
- if (parent.type === "atrule" && parent.name === "layer") return paths.get(parent)?.segments ?? [];
148
- parent = parent.parent;
149
- }
150
- return [];
151
- }
152
- function createLayerInsertionAnchor(root, atRule) {
153
- let topLevelNode = atRule;
154
- while (topLevelNode.parent && topLevelNode.parent !== root) topLevelNode = topLevelNode.parent;
155
- const anchor = postcss.comment({ text: LAYER_INSERTION_ANCHOR });
156
- topLevelNode.before(anchor);
157
- return anchor;
158
- }
159
- function insertLayeredNodes(root, anchor, nodes) {
160
- if (!anchor.parent) {
161
- root.append(nodes);
162
- return;
163
- }
164
- if (nodes.length === 0) {
165
- anchor.remove();
166
- return;
167
- }
168
- anchor.replaceWith(nodes);
169
- }
170
- /**
171
- * 按 cascade layer 声明顺序重排规则并移除 `@layer` 语法。
172
- *
173
- * 该转换只模拟 layer 的顺序语义,不通过提高选择器权重模拟完整 specificity 规则。
174
- */
175
- function consumeCascadeLayers(root) {
176
- const layerAtRules = [];
177
- const paths = /* @__PURE__ */ new WeakMap();
178
- const siblingOrders = /* @__PURE__ */ new Map();
179
- const buckets = /* @__PURE__ */ new Map();
180
- const topLayerOccurrences = /* @__PURE__ */ new Map();
181
- let anonymousLayerIndex = 0;
182
- const registerPath = (segments, occurrence) => {
183
- let parentKey = "";
184
- for (const [index, segment] of segments.entries()) {
185
- let siblings = siblingOrders.get(parentKey);
186
- if (!siblings) {
187
- siblings = /* @__PURE__ */ new Map();
188
- siblingOrders.set(parentKey, siblings);
189
- }
190
- if (!siblings.has(segment)) siblings.set(segment, siblings.size);
191
- if (index === 0 && !topLayerOccurrences.has(segment)) topLayerOccurrences.set(segment, occurrence);
192
- parentKey = parentKey ? `${parentKey}${LAYER_PATH_SEPARATOR}${segment}` : segment;
193
- }
194
- const path = createLayerPath(segments);
195
- if (!buckets.has(path.key)) buckets.set(path.key, {
196
- ...path,
197
- nodes: []
198
- });
199
- return path;
200
- };
201
- root.walkAtRules("layer", (atRule) => {
202
- layerAtRules.push(atRule);
203
- const parentLayer = findParentLayerPath(atRule, paths);
204
- const names = splitLayerNames(atRule.params);
205
- if (!atRule.nodes) {
206
- for (const name of names) registerPath([...parentLayer, ...splitLayerPath(name)], atRule);
207
- return;
208
- }
209
- const ownSegments = names[0] ? splitLayerPath(names[0]) : [`\u0000anonymous-${anonymousLayerIndex++}`];
210
- paths.set(atRule, registerPath([...parentLayer, ...ownSegments], atRule));
211
- });
212
- if (layerAtRules.length === 0) return;
213
- const insertionAnchors = /* @__PURE__ */ new Map();
214
- for (const [segment, occurrence] of topLayerOccurrences) insertionAnchors.set(segment, createLayerInsertionAnchor(root, occurrence));
215
- for (const atRule of [...layerAtRules].reverse()) {
216
- if (!atRule.parent) continue;
217
- const path = paths.get(atRule);
218
- if (!path || !atRule.nodes) {
219
- removeEmptyLayerAncestors(atRule, root);
220
- continue;
221
- }
222
- const nodes = atRule.nodes.map((node) => node.clone());
223
- if (nodes.length > 0) buckets.get(path.key)?.nodes.unshift(...wrapLayerNodes(atRule, nodes, root));
224
- removeEmptyLayerAncestors(atRule, root);
225
- }
226
- const compareBuckets = (left, right) => {
227
- if (isLayerDescendant(left.segments, right.segments)) return -1;
228
- if (isLayerDescendant(right.segments, left.segments)) return 1;
229
- const size = Math.min(left.segments.length, right.segments.length);
230
- let parentKey = "";
231
- for (let index = 0; index < size; index++) {
232
- const leftSegment = left.segments[index];
233
- const rightSegment = right.segments[index];
234
- if (leftSegment !== rightSegment) {
235
- const siblings = siblingOrders.get(parentKey);
236
- return (siblings?.get(leftSegment) ?? 0) - (siblings?.get(rightSegment) ?? 0);
237
- }
238
- parentKey = parentKey ? `${parentKey}${LAYER_PATH_SEPARATOR}${leftSegment}` : leftSegment;
239
- }
240
- return left.segments.length - right.segments.length;
241
- };
242
- const bucketsByTopLayer = /* @__PURE__ */ new Map();
243
- for (const bucket of buckets.values()) {
244
- const topLayer = bucket.segments[0];
245
- if (!topLayer || bucket.nodes.length === 0) continue;
246
- const group = bucketsByTopLayer.get(topLayer) ?? [];
247
- group.push(bucket);
248
- bucketsByTopLayer.set(topLayer, group);
249
- }
250
- for (const [segment, anchor] of insertionAnchors) insertLayeredNodes(root, anchor, (bucketsByTopLayer.get(segment) ?? []).sort(compareBuckets).flatMap((bucket) => bucket.nodes));
251
- }
252
- //#endregion
253
- //#region src/compat/mini-program-css/at-rules.ts
254
- const MINI_PROGRAM_UNSUPPORTED_AT_RULES = /* @__PURE__ */ new Set(["property", "supports"]);
255
- function removeAtRulesByScan(css, names) {
256
- let index = 0;
257
- let result = "";
258
- const atRulePattern = new RegExp(`@(?:${[...names].join("|")})\\b`, "i");
259
- while (index < css.length) {
260
- const match = atRulePattern.exec(css.slice(index));
261
- if (!match || match.index === void 0) {
262
- result += css.slice(index);
263
- break;
264
- }
265
- const start = index + match.index;
266
- result += css.slice(index, start);
267
- const blockStart = css.indexOf("{", start);
268
- if (blockStart === -1) {
269
- result += css.slice(start);
270
- break;
271
- }
272
- let depth = 0;
273
- let cursor = blockStart;
274
- for (; cursor < css.length; cursor++) {
275
- const char = css[cursor];
276
- if (char === "{") depth++;
277
- else if (char === "}") {
278
- depth--;
279
- if (depth === 0) {
280
- cursor++;
281
- break;
282
- }
283
- }
284
- }
285
- index = cursor;
286
- }
287
- return result;
288
- }
289
- function removeUnsupportedMiniProgramAtRules(css) {
290
- try {
291
- const root = postcss.parse(css);
292
- root.walkAtRules((atRule) => {
293
- if (MINI_PROGRAM_UNSUPPORTED_AT_RULES.has(atRule.name)) atRule.remove();
294
- });
295
- root.walkAtRules((atRule) => {
296
- if (atRule.nodes && atRule.nodes.length === 0) atRule.remove();
297
- });
298
- return root.toString();
299
- } catch {
300
- return removeAtRulesByScan(css, MINI_PROGRAM_UNSUPPORTED_AT_RULES);
301
- }
302
- }
303
- function removeUnsupportedAtSupports(css) {
304
- return removeUnsupportedMiniProgramAtRules(css);
305
- }
306
- /**
307
- * 移除小程序不支持的 cascade layer 语法,同时保留 layer 内的实际规则。
308
- */
309
- function removeUnsupportedCascadeLayers(root) {
310
- consumeCascadeLayers(root);
311
- }
312
- function unwrapUnsupportedCascadeLayers(css) {
313
- if (!css.includes("@layer")) return css;
314
- try {
315
- const root = postcss.parse(css);
316
- removeUnsupportedCascadeLayers(root);
317
- return root.toString();
318
- } catch {
319
- return css;
320
- }
321
- }
322
- //#endregion
323
- //#region src/compat/mini-program-css/selectors.ts
324
- const MINI_PROGRAM_THEME_SCOPE_SELECTOR = ":host,page,.tw-root,wx-root-portal-content";
325
- const MINI_PROGRAM_ELEMENT_SCOPE_SELECTOR = "view,text,::after,::before";
326
- const MINI_PROGRAM_ELEMENT_SCOPE_SELECTORS = /* @__PURE__ */ new Set([
327
- "view",
328
- "text",
329
- ":before",
330
- ":after",
331
- "::before",
332
- "::after"
333
- ]);
334
- const MINI_PROGRAM_NATIVE_ELEMENT_SELECTORS = /* @__PURE__ */ new Set([
335
- ...MINI_PROGRAM_ELEMENT_SCOPE_SELECTORS,
336
- "button",
337
- "input",
338
- "textarea",
339
- "canvas",
340
- "video",
341
- "audio"
342
- ]);
343
- const MINI_PROGRAM_PREFLIGHT_SELECTORS = /* @__PURE__ */ new Set(["*", ...MINI_PROGRAM_ELEMENT_SCOPE_SELECTORS]);
344
- const MINI_PROGRAM_THEME_SCOPE_SELECTORS = /* @__PURE__ */ new Set([
345
- ":host",
346
- ":root",
347
- "page",
348
- ".tw-root",
349
- "wx-root-portal-content"
350
- ]);
351
- function normalizeMiniProgramThemeScopeSelector(root) {
352
- if (root === false) return ":host";
353
- if (root === void 0) return MINI_PROGRAM_THEME_SCOPE_SELECTOR;
354
- const selectors = Array.isArray(root) ? root.filter(Boolean) : [root];
355
- return [.../* @__PURE__ */ new Set([":host", ...selectors])].join(",");
356
- }
357
- const SPECIFICITY_PLACEHOLDER_SUFFIXES = [":not(#n)", ":not(#\\#)"];
358
- const ROOT_SPECIFICITY_PLACEHOLDER_SUFFIXES = [":not(.does-not-exist)"];
359
- const MINI_PROGRAM_UNSUPPORTED_BROWSER_SELECTORS = /* @__PURE__ */ new Set([
360
- ":-moz-focusring",
361
- ":-moz-ui-invalid",
362
- "::-webkit-calendar-picker-indicator",
363
- "::-webkit-date-and-time-value",
364
- "::-webkit-datetime-edit",
365
- "::-webkit-datetime-edit-day-field",
366
- "::-webkit-datetime-edit-fields-wrapper",
367
- "::-webkit-datetime-edit-hour-field",
368
- "::-webkit-datetime-edit-meridiem-field",
369
- "::-webkit-datetime-edit-millisecond-field",
370
- "::-webkit-datetime-edit-minute-field",
371
- "::-webkit-datetime-edit-month-field",
372
- "::-webkit-datetime-edit-second-field",
373
- "::-webkit-datetime-edit-year-field",
374
- "::-webkit-inner-spin-button",
375
- "::-webkit-input-placeholder",
376
- "::-webkit-outer-spin-button",
377
- "::-webkit-search-decoration",
378
- "::placeholder",
379
- "[hidden]:where(:not([hidden='until-found']))"
380
- ]);
381
- const MINI_PROGRAM_UNSUPPORTED_BROWSER_TAG_SELECTORS = /* @__PURE__ */ new Set([
382
- "a",
383
- "abbr:where([title])",
384
- "audio",
385
- "b",
386
- "button",
387
- "canvas",
388
- "code",
389
- "embed",
390
- "h1",
391
- "h2",
392
- "h3",
393
- "h4",
394
- "h5",
395
- "h6",
396
- "hr",
397
- "html",
398
- "iframe",
399
- "img",
400
- "input",
401
- "input:where([type='button'],[type='reset'],[type='submit'])",
402
- "kbd",
403
- "menu",
404
- "object",
405
- "ol",
406
- "optgroup",
407
- "pre",
408
- "progress",
409
- "samp",
410
- "select",
411
- "select[multiple]optgroup",
412
- "select[multiple]optgroupoption",
413
- "select[size]optgroup",
414
- "select[size]optgroupoption",
415
- "small",
416
- "strong",
417
- "sub",
418
- "summary",
419
- "sup",
420
- "svg",
421
- "table",
422
- "textarea",
423
- "ul",
424
- "video"
425
- ]);
426
- const MINI_PROGRAM_UNSUPPORTED_BROWSER_PREFLIGHT_SELECTOR_PARTS = /* @__PURE__ */ new Set([...MINI_PROGRAM_UNSUPPORTED_BROWSER_TAG_SELECTORS, "::file-selector-button"]);
427
- function normalizeSelector(selector) {
428
- return selector.trim().replace(/\s+/g, "");
429
- }
430
- function normalizePseudoElementSelector(selector) {
431
- return normalizeSelector(selector).replace(/^:(before|after)$/, "::$1");
432
- }
433
- function getRuleSelectors(rule) {
434
- return rule.selector.split(",").map(normalizePseudoElementSelector).filter(Boolean);
435
- }
436
- function getSortedRuleSelectorKey(rule) {
437
- return getRuleSelectors(rule).sort().join(",");
438
- }
439
- function isUnsupportedBrowserSelector(selector) {
440
- const normalized = normalizeSelector(selector);
441
- return MINI_PROGRAM_UNSUPPORTED_BROWSER_SELECTORS.has(normalized) || MINI_PROGRAM_UNSUPPORTED_BROWSER_TAG_SELECTORS.has(normalized) && !MINI_PROGRAM_NATIVE_ELEMENT_SELECTORS.has(normalized);
442
- }
443
- function isUnsupportedBrowserPreflightSelector(selector) {
444
- const normalizedParts = selector.split(",").map(normalizeSelector).filter(Boolean);
445
- return normalizedParts.length > 1 && normalizedParts.every((part) => MINI_PROGRAM_UNSUPPORTED_BROWSER_PREFLIGHT_SELECTOR_PARTS.has(part));
446
- }
447
- function isMiniProgramNativeElementSelector(selector) {
448
- return MINI_PROGRAM_NATIVE_ELEMENT_SELECTORS.has(normalizePseudoElementSelector(selector));
449
- }
450
- function isMiniProgramPreflightSelector(selectors) {
451
- return selectors.length > 0 && selectors.every((selector) => MINI_PROGRAM_PREFLIGHT_SELECTORS.has(selector)) && selectors.some((selector) => selector === "*" || selector === ":before" || selector === ":after" || selector === "::before" || selector === "::after");
452
- }
453
- function isMiniProgramThemeScopeSelector(selectors) {
454
- return selectors.length > 0 && selectors.every((selector) => MINI_PROGRAM_THEME_SCOPE_SELECTORS.has(selector));
455
- }
456
- //#endregion
457
- //#region src/compat/mini-program-css/predicates.ts
458
- const PREFLIGHT_RESET_PROPS = /* @__PURE__ */ new Set([
459
- "box-sizing",
460
- "border",
461
- "border-width",
462
- "border-style",
463
- "border-color",
464
- "margin",
465
- "padding"
466
- ]);
467
- const PSEUDO_CONTENT_SELECTOR_RE = /^(?:::before|::after|:before|:after)(?:,(?:::before|::after|:before|:after))*$/;
468
- const TW_CONTENT_VAR_RE$1 = /var\(\s*--tw-content\b/;
469
- const BROWSER_PREFLIGHT_SINGLE_ELEMENT_DECLARATIONS = /* @__PURE__ */ new Map([["button", /* @__PURE__ */ new Set(["appearance:button", "-moz-appearance:button"])], ["textarea", /* @__PURE__ */ new Set(["resize:vertical"])]]);
470
- function hasTailwindPreflightDeclaration(rule) {
471
- let hasTailwindVar = false;
472
- let hasResetProp = false;
473
- rule.walkDecls((decl) => {
474
- if (decl.prop.startsWith("--tw-")) hasTailwindVar = true;
475
- if (PREFLIGHT_RESET_PROPS.has(decl.prop)) hasResetProp = true;
476
- });
477
- return hasTailwindVar || hasResetProp;
478
- }
479
- function hasTailwindVariableDeclaration(rule) {
480
- let hasTailwindVar = false;
481
- rule.walkDecls((decl) => {
482
- if (decl.prop.startsWith("--tw-")) hasTailwindVar = true;
483
- });
484
- return hasTailwindVar;
485
- }
486
- function isCustomPropertyRule(rule) {
487
- let hasDeclaration = false;
488
- let allCustomProperties = true;
489
- rule.each((node) => {
490
- if (node.type !== "decl") return;
491
- hasDeclaration = true;
492
- if (!node.prop.startsWith("--")) allCustomProperties = false;
493
- });
494
- return hasDeclaration && allCustomProperties;
495
- }
496
- function isEmptyTwContentDeclaration(decl) {
497
- return decl.prop === "--tw-content" && (decl.value === "\"\"" || decl.value === "''");
498
- }
499
- function isOnlyTwContentDeclarations(rule) {
500
- let hasDeclaration = false;
501
- let onlyContentVariable = true;
502
- rule.walkDecls((decl) => {
503
- hasDeclaration = true;
504
- if (decl.prop !== "--tw-content") onlyContentVariable = false;
505
- });
506
- return hasDeclaration && onlyContentVariable;
507
- }
508
- function isPseudoContentInitRule(rule) {
509
- const selector = rule.selector.replace(/\s+/g, "");
510
- return PSEUDO_CONTENT_SELECTOR_RE.test(selector) && isOnlyTwContentDeclarations(rule);
511
- }
512
- function usesTwContentVariable(root) {
513
- let used = false;
514
- root.walkDecls((decl) => {
515
- if (TW_CONTENT_VAR_RE$1.test(decl.value)) used = true;
516
- });
517
- return used;
518
- }
519
- function isMiniProgramPreflightRule(node) {
520
- if (node.type !== "rule") return false;
521
- const selectors = getRuleSelectors(node);
522
- if (!isMiniProgramPreflightSelector(selectors)) return false;
523
- if (selectors.includes("*")) return hasTailwindPreflightDeclaration(node);
524
- if (hasTailwindVariableDeclaration(node)) return true;
525
- return selectors.some((selector) => selector === ":before" || selector === ":after" || selector === "::before" || selector === "::after") && selectors.some((selector) => selector === "view" || selector === "text") && hasTailwindPreflightDeclaration(node);
526
- }
527
- function isBrowserElementPreflightRule(node) {
528
- if (node.type !== "rule") return false;
529
- const selectors = getRuleSelectors(node);
530
- if (selectors.length !== 1) return false;
531
- const declarations = BROWSER_PREFLIGHT_SINGLE_ELEMENT_DECLARATIONS.get(selectors[0]);
532
- if (!declarations) return false;
533
- let hasDeclaration = false;
534
- let allBrowserPreflightDeclarations = true;
535
- node.each((child) => {
536
- if (child.type !== "decl") return;
537
- hasDeclaration = true;
538
- const key = `${child.prop.toLowerCase()}:${child.value.trim().toLowerCase()}`;
539
- if (!declarations.has(key)) allBrowserPreflightDeclarations = false;
540
- });
541
- return hasDeclaration && allBrowserPreflightDeclarations;
542
- }
543
- function isMiniProgramThemeVariableRule(node) {
544
- if (node.type !== "rule") return false;
545
- return isMiniProgramThemeScopeSelector(getRuleSelectors(node)) && isCustomPropertyRule(node);
546
- }
547
- //#endregion
548
- //#region src/compat/mini-program-css/directives.ts
549
- const TAILWIND_V4_BANNER_RE = /\/\*!\s*tailwindcss v4\./;
550
- const GENERATOR_PLACEHOLDER_COMMENT_RE = /^\s*(?:!\s*)?weapp-tailwindcss generator-placeholder\s*$/i;
551
- function isCssWhitespace(code) {
552
- return code === 9 || code === 10 || code === 12 || code === 13 || code === 32;
553
- }
554
- function skipCssWhitespace(css, start) {
555
- let index = start;
556
- while (index < css.length && isCssWhitespace(css.charCodeAt(index))) index++;
557
- return index;
558
- }
559
- function findClosingParenthesis(css, openingIndex) {
560
- let depth = 0;
561
- let quote = 0;
562
- for (let index = openingIndex; index < css.length; index++) {
563
- const code = css.charCodeAt(index);
564
- if (quote !== 0) {
565
- if (code === 92) index++;
566
- else if (code === quote) quote = 0;
567
- continue;
568
- }
569
- if (code === 34 || code === 39) {
570
- quote = code;
571
- continue;
572
- }
573
- if (code === 92) {
574
- index++;
575
- continue;
576
- }
577
- if (code === 47 && css.charCodeAt(index + 1) === 42) {
578
- const commentEnd = css.indexOf("*/", index + 2);
579
- if (commentEnd < 0) return -1;
580
- index = commentEnd + 1;
581
- continue;
582
- }
583
- if (code === 40) {
584
- depth++;
585
- continue;
586
- }
587
- if (code === 41) {
588
- depth--;
589
- if (depth === 0) return index;
590
- }
591
- }
592
- return -1;
593
- }
594
- function isCssCodePosition(css, position) {
595
- let quote = 0;
596
- for (let index = 0; index < position; index++) {
597
- const code = css.charCodeAt(index);
598
- if (quote !== 0) {
599
- if (code === 92) index++;
600
- else if (code === quote) quote = 0;
601
- continue;
602
- }
603
- if (code === 34 || code === 39) {
604
- quote = code;
605
- continue;
606
- }
607
- if (code === 47 && css.charCodeAt(index + 1) === 42) {
608
- const commentEnd = css.indexOf("*/", index + 2);
609
- if (commentEnd < 0 || commentEnd >= position) return false;
610
- index = commentEnd + 1;
611
- }
612
- }
613
- return quote === 0;
614
- }
615
- /**
616
- * 严格移除文件末尾残留的 Tailwind source media 开始标记。
617
- * 仅处理可确认属于 Tailwind 的尾部残片,其它非法 CSS 保持原样。
618
- */
619
- function repairTrailingUnclosedTailwindSourceMedia(css) {
620
- const sourceMediaPattern = /(?:^|\r?\n)[\t\f ]*@media\s+source\(/g;
621
- for (let match = sourceMediaPattern.exec(css); match !== null; match = sourceMediaPattern.exec(css)) {
622
- const prefixLength = match[0].startsWith("\n") ? 1 : match[0].startsWith("\r\n") ? 2 : 0;
623
- const start = match.index + prefixLength;
624
- if (!isCssCodePosition(css, start)) continue;
625
- const closingIndex = findClosingParenthesis(css, start + match[0].length - prefixLength - 1);
626
- if (closingIndex < 0) continue;
627
- const blockStart = skipCssWhitespace(css, closingIndex + 1);
628
- if (css.charCodeAt(blockStart) !== 123) continue;
629
- if (skipCssWhitespace(css, blockStart + 1) !== css.length) continue;
630
- return css.slice(0, match.index);
631
- }
632
- return css;
633
- }
634
- function hasTailwindcssV4Signal(css) {
635
- if (TAILWIND_V4_BANNER_RE.test(css)) return true;
636
- const root = postcss.parse(css);
637
- let hasProperty = false;
638
- root.walkAtRules("property", (atRule) => {
639
- if (atRule.params.trim().startsWith("--tw-")) {
640
- hasProperty = true;
641
- return false;
642
- }
643
- });
644
- return hasProperty;
645
- }
646
- function unwrapTailwindSourceMedia(root) {
647
- root.walkAtRules("media", (atRule) => {
648
- if (!atRule.params.startsWith("source(")) return;
649
- if (atRule.nodes && atRule.nodes.length > 0) atRule.replaceWith(...atRule.nodes);
650
- else atRule.remove();
651
- });
652
- }
653
- function removeTailwindGenerationDirectives(root) {
654
- root.walkComments((comment) => {
655
- if (GENERATOR_PLACEHOLDER_COMMENT_RE.test(comment.text)) comment.remove();
656
- });
657
- root.walkAtRules((atRule) => {
658
- if (atRule.name === "config" || atRule.name === "source" || atRule.name === "tailwind" || atRule.name === "reference" || atRule.name === "plugin") atRule.remove();
659
- });
660
- }
661
- const MODERN_COLOR_FUNCTION_NAMES = /* @__PURE__ */ new Set([
662
- "oklch",
663
- "oklab",
664
- "lch",
665
- "lab"
666
- ]);
667
- const MODERN_COLOR_SYNTAX_FUNCTION_NAMES = /* @__PURE__ */ new Set([
668
- "rgb",
669
- "rgba",
670
- "hsl",
671
- "hsla",
672
- "hwb"
673
- ]);
674
- const PLACEHOLDER_PREFIX = "__weapp_tw_color_mix_";
675
- const DYNAMIC_ALPHA_RE = /\b(?:var|env)\(|--[\w-]+\b/;
676
- const INTERNAL_TAILWIND_ALPHA_RE = /var\(\s*--tw-[^)]+-alpha\s*\)/;
677
- const TRANSPARENT_COLOR_RE = /^transparent$/i;
678
- const CURRENT_COLOR_RE = /^currentcolor$/i;
679
- const CSS_WIDE_KEYWORD_RE = /^(?:inherit|initial|unset|revert|revert-layer)$/i;
680
- const CUSTOM_PROPERTY_RE = /^--[\w-]+$/;
681
- //#endregion
682
- //#region src/compat/color-mix/modern.ts
683
- function isDisplayP3ColorFunction(colorSource) {
684
- return /^color\(\s*display-p3\b/i.test(colorSource.trim());
685
- }
686
- function isModernColorSyntaxFunction(colorSource) {
687
- const parsed = valueParser(colorSource.trim());
688
- const node = parsed.nodes.length === 1 ? parsed.nodes[0] : void 0;
689
- if (node?.type !== "function") return false;
690
- const name = node.value.toLowerCase();
691
- if (!MODERN_COLOR_SYNTAX_FUNCTION_NAMES.has(name)) return false;
692
- return !node.nodes.some((child) => child.type === "div" && child.value === ",");
693
- }
694
- function hasUnsupportedModernColorFunction(value) {
695
- const parsed = valueParser(value);
696
- let hasUnsupported = false;
697
- parsed.walk((node) => {
698
- if (node.type !== "function") return;
699
- const name = node.value.toLowerCase();
700
- if (name === "color-mix" || MODERN_COLOR_FUNCTION_NAMES.has(name) || name === "color" && isDisplayP3ColorFunction(valueParser.stringify(node)) || isModernColorSyntaxFunction(valueParser.stringify(node))) {
701
- hasUnsupported = true;
702
- return false;
703
- }
704
- });
705
- return hasUnsupported;
706
- }
707
- //#endregion
708
- //#region src/compat/color-mix/parse.ts
709
- function splitArguments(nodes) {
710
- const args = [];
711
- let current = [];
712
- for (const node of nodes) {
713
- if (node.type === "div" && node.value === ",") {
714
- args.push(current);
715
- current = [];
716
- continue;
717
- }
718
- current.push(node);
719
- }
720
- args.push(current);
721
- return args;
722
- }
723
- function splitStopSegments(nodes) {
724
- const segments = [];
725
- let current = [];
726
- for (const node of nodes) {
727
- if (node.type === "space") {
728
- if (current.length > 0) {
729
- segments.push(current);
730
- current = [];
731
- }
732
- continue;
733
- }
734
- current.push(node);
735
- }
736
- if (current.length > 0) segments.push(current);
737
- return segments;
738
- }
739
- function trimNodes(nodes) {
740
- let start = 0;
741
- let end = nodes.length;
742
- while (start < end && nodes[start]?.type === "space") start += 1;
743
- while (end > start && nodes[end - 1]?.type === "space") end -= 1;
744
- return nodes.slice(start, end);
745
- }
746
- function getParsedColorData(colorSource) {
747
- try {
748
- const parsed = parseComponentValue(tokenize({ css: colorSource }));
749
- return color(parsed);
750
- } catch {
751
- return false;
752
- }
753
- }
754
- function parseAlphaValue(alphaSource) {
755
- const parsed = Number.parseFloat(alphaSource);
756
- if (Number.isFinite(parsed)) return alphaSource.trim().endsWith("%") ? parsed / 100 : parsed;
757
- }
758
- function resolveVarColor(colorSource, customPropertyValues, depth = 0) {
759
- if (depth > 5) return;
760
- const parsed = valueParser(colorSource.trim());
761
- const node = parsed.nodes.length === 1 ? parsed.nodes[0] : void 0;
762
- if (node?.type !== "function" || node.value.toLowerCase() !== "var") return;
763
- const args = splitArguments(node.nodes);
764
- const propertyName = valueParser.stringify(trimNodes(args[0] ?? [])).trim();
765
- if (!CUSTOM_PROPERTY_RE.test(propertyName)) return;
766
- const resolved = customPropertyValues.get(propertyName);
767
- if (!resolved) {
768
- const fallback = args[1] ? valueParser.stringify(trimNodes(args[1])).trim() : void 0;
769
- return fallback ? resolveColorData(fallback, customPropertyValues, depth + 1) : void 0;
770
- }
771
- return resolveColorData(resolved, customPropertyValues, depth + 1);
772
- }
773
- function resolveColorData(colorSource, customPropertyValues, depth = 0) {
774
- if (typeof colorSource !== "string") return;
775
- const trimmed = colorSource.trim();
776
- if (TRANSPARENT_COLOR_RE.test(trimmed)) return getParsedColorData(trimmed) || void 0;
777
- if (CURRENT_COLOR_RE.test(trimmed) || CSS_WIDE_KEYWORD_RE.test(trimmed)) return;
778
- const resolvedVar = resolveVarColor(trimmed, customPropertyValues, depth);
779
- if (resolvedVar) return resolvedVar;
780
- return getParsedColorData(trimmed) || void 0;
781
- }
782
- function normalizeColorFunctionName(colorSource, alpha, customPropertyValues) {
783
- const resolvedColor = resolveColorData(colorSource, customPropertyValues);
784
- if (!resolvedColor) return;
785
- resolvedColor.alpha = alpha;
786
- return serializeRGB(resolvedColor).toString();
787
- }
788
- function normalizeColorFunctionWithDynamicAlpha(colorSource, alphaSource, customPropertyValues) {
789
- const resolvedColor = resolveColorData(colorSource, customPropertyValues);
790
- const alphaColor = getParsedColorData(`rgb(0 0 0 / ${alphaSource})`);
791
- if (!resolvedColor || !alphaColor || typeof alphaColor.alpha === "number") return;
792
- resolvedColor.alpha = alphaColor.alpha;
793
- return serializeRGB(resolvedColor).toString();
794
- }
795
- function normalizeStandaloneColorFunction(colorSource) {
796
- const resolvedColor = getParsedColorData(colorSource);
797
- return resolvedColor ? serializeRGB(resolvedColor).toString() : void 0;
798
- }
799
- //#endregion
800
- //#region src/compat/color-mix/resolve.ts
801
- function createRgbaWithAlpha(colorSource, alphaSource, customPropertyValues) {
802
- const alpha = alphaSource.trim();
803
- return normalizeColorFunctionWithDynamicAlpha(colorSource, CUSTOM_PROPERTY_RE.test(alpha) ? `var(${alpha})` : alpha, customPropertyValues);
804
- }
805
- function tryResolveColorMix(node, customPropertyValues) {
806
- const args = splitArguments(node.nodes);
807
- if (args.length < 3) return;
808
- const colorStopNodes = splitStopSegments(args[1] ?? []);
809
- if (colorStopNodes.length < 2) return;
810
- const colorNodes = trimNodes(colorStopNodes[0] ?? []);
811
- const alphaNodes = trimNodes(colorStopNodes[1] ?? []);
812
- const trailingNodes = trimNodes(args[2] ?? []);
813
- if (!colorNodes.length || !alphaNodes.length || valueParser.stringify(trailingNodes).trim().toLowerCase() !== "transparent") return;
814
- const colorSource = valueParser.stringify(colorNodes).trim();
815
- const alphaSource = valueParser.stringify(alphaNodes).trim();
816
- if (!colorSource || !alphaSource || INTERNAL_TAILWIND_ALPHA_RE.test(alphaSource)) return;
817
- if (CURRENT_COLOR_RE.test(colorSource)) return {
818
- value: colorSource,
819
- deferred: false
820
- };
821
- if (DYNAMIC_ALPHA_RE.test(alphaSource)) {
822
- const normalized = createRgbaWithAlpha(colorSource, alphaSource, customPropertyValues);
823
- return normalized ? {
824
- value: normalized,
825
- deferred: true
826
- } : {
827
- value: colorSource,
828
- deferred: true
829
- };
830
- }
831
- const alpha = parseAlphaValue(alphaSource);
832
- if (alpha === void 0) return;
833
- const normalized = normalizeColorFunctionName(colorSource, alpha, customPropertyValues);
834
- if (normalized) return {
835
- value: normalized,
836
- deferred: false
837
- };
838
- return {
839
- value: colorSource,
840
- deferred: false
841
- };
842
- }
843
- //#endregion
844
- //#region src/cssVarsV4.ts
845
- function property(ident, initialValue, _syntax) {
846
- return {
847
- prop: ident,
848
- value: initialValue || ""
849
- };
850
- }
851
- const nullShadow = "0 0 #0000";
852
- const nodes = [
853
- property("--tw-border-spacing-x", "0", "<length>"),
854
- property("--tw-border-spacing-y", "0", "<length>"),
855
- property("--tw-translate-x", "0"),
856
- property("--tw-translate-y", "0"),
857
- property("--tw-translate-z", "0"),
858
- property("--tw-scale-x", "1"),
859
- property("--tw-scale-y", "1"),
860
- property("--tw-scale-z", "1"),
861
- property("--tw-rotate-x"),
862
- property("--tw-rotate-y"),
863
- property("--tw-rotate-z"),
864
- property("--tw-skew-x"),
865
- property("--tw-skew-y"),
866
- property("--tw-pan-x"),
867
- property("--tw-pan-y"),
868
- property("--tw-pinch-zoom"),
869
- property("--tw-scroll-snap-strictness", "proximity", "*"),
870
- property("--tw-space-x-reverse", "0"),
871
- property("--tw-space-y-reverse", "0"),
872
- property("--tw-scrollbar-thumb", "#0000", "<color>"),
873
- property("--tw-scrollbar-track", "#0000", "<color>"),
874
- property("--tw-border-style", "solid"),
875
- property("--tw-divide-x-reverse", "0"),
876
- property("--tw-divide-y-reverse", "0"),
877
- property("--tw-gradient-position", "initial"),
878
- property("--tw-gradient-from", "#0000", "<color>"),
879
- property("--tw-gradient-via", "#0000", "<color>"),
880
- property("--tw-gradient-to", "#0000", "<color>"),
881
- property("--tw-gradient-stops", "initial"),
882
- property("--tw-gradient-via-stops", "initial"),
883
- property("--tw-gradient-from-position", "0%", "<length-percentage>"),
884
- property("--tw-gradient-via-position", "50%", "<length-percentage>"),
885
- property("--tw-gradient-to-position", "100%", "<length-percentage>"),
886
- property("--tw-mask-linear", "linear-gradient(#fff, #fff)"),
887
- property("--tw-mask-radial", "linear-gradient(#fff, #fff)"),
888
- property("--tw-mask-conic", "linear-gradient(#fff, #fff)"),
889
- property("--tw-mask-left", "linear-gradient(#fff, #fff)"),
890
- property("--tw-mask-right", "linear-gradient(#fff, #fff)"),
891
- property("--tw-mask-bottom", "linear-gradient(#fff, #fff)"),
892
- property("--tw-mask-top", "linear-gradient(#fff, #fff)"),
893
- property("--tw-mask-linear-position", "0deg"),
894
- property("--tw-mask-linear-from-position", "0%"),
895
- property("--tw-mask-linear-to-position", "100%"),
896
- property("--tw-mask-linear-from-color", "black"),
897
- property("--tw-mask-linear-to-color", "transparent"),
898
- property("--tw-mask-radial-from-position", "0%"),
899
- property("--tw-mask-radial-to-position", "100%"),
900
- property("--tw-mask-radial-from-color", "black"),
901
- property("--tw-mask-radial-to-color", "transparent"),
902
- property("--tw-mask-radial-shape", "ellipse"),
903
- property("--tw-mask-radial-size", "farthest-corner"),
904
- property("--tw-mask-radial-position", "center"),
905
- property("--tw-mask-conic-position", "0deg"),
906
- property("--tw-mask-conic-from-position", "0%"),
907
- property("--tw-mask-conic-to-position", "100%"),
908
- property("--tw-mask-conic-from-color", "black"),
909
- property("--tw-mask-conic-to-color", "transparent"),
910
- property("--tw-font-weight"),
911
- property("--tw-blur"),
912
- property("--tw-brightness"),
913
- property("--tw-contrast"),
914
- property("--tw-grayscale"),
915
- property("--tw-hue-rotate"),
916
- property("--tw-invert"),
917
- property("--tw-opacity"),
918
- property("--tw-saturate"),
919
- property("--tw-sepia"),
920
- property("--tw-drop-shadow"),
921
- property("--tw-drop-shadow-color"),
922
- property("--tw-drop-shadow-alpha", "100%", "<percentage>"),
923
- property("--tw-drop-shadow-size"),
924
- property("--tw-backdrop-blur"),
925
- property("--tw-backdrop-brightness"),
926
- property("--tw-backdrop-contrast"),
927
- property("--tw-backdrop-grayscale"),
928
- property("--tw-backdrop-hue-rotate"),
929
- property("--tw-backdrop-invert"),
930
- property("--tw-backdrop-opacity"),
931
- property("--tw-backdrop-saturate"),
932
- property("--tw-backdrop-sepia"),
933
- property("--tw-duration", "initial"),
934
- property("--tw-ease", "initial"),
935
- property("--tw-content", "\"\""),
936
- property("--tw-contain-size"),
937
- property("--tw-contain-layout"),
938
- property("--tw-contain-paint"),
939
- property("--tw-contain-style"),
940
- property("--tw-leading"),
941
- property("--tw-tracking"),
942
- property("--tw-ordinal"),
943
- property("--tw-slashed-zero"),
944
- property("--tw-numeric-figure"),
945
- property("--tw-numeric-spacing"),
946
- property("--tw-numeric-fraction"),
947
- property("--tw-outline-style", "solid"),
948
- property("--tw-text-shadow-color", "initial"),
949
- property("--tw-text-shadow-alpha", "100%", "<percentage>"),
950
- property("--tw-shadow", nullShadow),
951
- property("--tw-shadow-color", "initial"),
952
- property("--tw-shadow-alpha", "100%", "<percentage>"),
953
- property("--tw-inset-shadow", nullShadow),
954
- property("--tw-inset-shadow-color", "initial"),
955
- property("--tw-inset-shadow-alpha", "100%", "<percentage>"),
956
- property("--tw-ring-color"),
957
- property("--tw-ring-shadow", nullShadow),
958
- property("--tw-inset-ring-color"),
959
- property("--tw-inset-ring-shadow", nullShadow),
960
- property("--tw-ring-inset"),
961
- property("--tw-ring-offset-width", "0px", "<length>"),
962
- property("--tw-ring-offset-color", "#fff"),
963
- property("--tw-ring-offset-shadow", nullShadow)
964
- ];
965
- for (const edge of [
966
- "top",
967
- "right",
968
- "bottom",
969
- "left"
970
- ]) nodes.push(property(`--tw-mask-${edge}-from-position`, "0%"), property(`--tw-mask-${edge}-to-position`, "100%"), property(`--tw-mask-${edge}-from-color`, "black"), property(`--tw-mask-${edge}-to-color`, "transparent"));
971
- //#endregion
972
- //#region src/utils/css-vars.ts
973
- /**
974
- * 将 CSS 变量定义转换为可直接插入的 Declaration 节点列表。
975
- */
976
- function createCssVarNodes(definitions) {
977
- return definitions.map((def) => new Declaration({
978
- prop: def.prop,
979
- value: def.value
980
- }));
981
- }
982
- const CLAMP_PX = 9999;
983
- const INFINITY_CALC_VALUE_REGEXP = /^calc\(\s*infinity\s*\*\s*(\d+(?:\.\d*)?|\.\d+)r?px\s*\)$/i;
984
- const MODERN_CHECK_WEBKIT_HYPHENS_RE = /-webkit-hyphens\s*:\s*none/;
985
- const MODERN_CHECK_MARGIN_TRIM_RE = /margin-trim\s*:\s*inline/;
986
- const MODERN_CHECK_MOZ_ORIENT_RE = /-moz-orient\s*:\s*inline/;
987
- const MODERN_CHECK_COLOR_RGB_RE = /color\s*:\s*rgb\(\s*from\s+red\s+r\s+g\s+b\s*\)/;
988
- const LINEAR_GRADIENT_LAB_RE = /background-image\s*:\s*linear-gradient\(\s*in\s+lab\s*,\s*red\s*,\s*red\s*\)/;
989
- const DISPLAY_P3_COLOR_RE = /color\s*:\s*color\(\s*display-p3\s+0\s+0\s+0%\s*\)/;
990
- const DISPLAY_P3_VALUE_RE$1 = /color\(\s*display-p3\b/i;
991
- const COLOR_GAMUT_P3_RE$1 = /\(\s*color-gamut\s*:\s*p3\s*\)/i;
992
- const GRADIENT_BACKGROUND_RE = /^(linear|radial|conic)-gradient\(/i;
993
- const GRADIENT_STOPS_VAR_RE = /^(?:linear|radial|conic)-gradient\(\s*var\(\s*--tw-gradient-stops\b/i;
994
- const SIMPLE_CLASS_SELECTOR_RE = /^\.([_a-z\u00A0-\uFFFF\\-][\w\u00A0-\uFFFF\\-]*)$/i;
995
- const COLOR_VAR_RE = /^var\(\s*(--color-[\w-]+)\s*\)$/i;
996
- const TAILWIND_THEME_VARIABLE_RE = /^--(?:animate|aspect|blur|breakpoint|color|container|drop-shadow|ease|font|inset-shadow|leading|perspective|radius|shadow|spacing|text|tracking)(?:-|$)/;
997
- const GRADIENT_DIRECTION_CLASS_RE = /^(?:-?bg-linear|bg-gradient-to-|-?bg-conic|bg-radial)/;
998
- const RADIUS_VALUE_RE = /\b([+-]?(?:\d+(?:\.\d+)?|\.\d+)(?:e[+-]?\d+)?)\s*(r?px)\b/gi;
999
- const SCIENTIFIC_NOTATION_RE = /e/i;
1000
- const TW_VAR_FUNCTION_RE = /var\(\s*(--tw-[\w-]+)\b/g;
1001
- const TW_CONTENT_VAR_RE = /var\(\s*--tw-content\b/;
1002
- const TW_GRADIENT_POSITION_PROPS = /* @__PURE__ */ new Set([
1003
- "--tw-gradient-from-position",
1004
- "--tw-gradient-via-position",
1005
- "--tw-gradient-to-position"
1006
- ]);
1007
- const UNSUPPORTED_CUSTOM_PROPERTY_DEFAULT_PROPS = /* @__PURE__ */ new Set(["--tw-gradient-via-stops"]);
1008
- const DEFAULT_VARIABLE_SCOPE_SELECTORS = /* @__PURE__ */ new Set([
1009
- "*",
1010
- "view",
1011
- "text",
1012
- ":before",
1013
- ":after",
1014
- "::before",
1015
- "::after",
1016
- "::backdrop"
1017
- ]);
1018
- function isTailwindcssV4(options) {
1019
- return options?.majorVersion === 4;
1020
- }
1021
- function isTailwindcssV4ThemeVariable(property) {
1022
- return property.startsWith("--tw-") || TAILWIND_THEME_VARIABLE_RE.test(property);
1023
- }
1024
- function testIfRootHostForV4(node) {
1025
- return node.type === "rule" && node.selector.includes(":root") && node.selector.includes(":host");
1026
- }
1027
- createCssVarNodes(nodes);
1028
- function collectUsedTailwindcssV4Variables(root) {
1029
- const props = /* @__PURE__ */ new Set();
1030
- root.walkDecls((decl) => {
1031
- if (decl.prop.startsWith("--tw-")) props.add(decl.prop);
1032
- TW_VAR_FUNCTION_RE.lastIndex = 0;
1033
- let match = TW_VAR_FUNCTION_RE.exec(decl.value);
1034
- while (match !== null) {
1035
- const prop = match[1];
1036
- if (prop) props.add(prop);
1037
- match = TW_VAR_FUNCTION_RE.exec(decl.value);
1038
- }
1039
- });
1040
- root.walkAtRules("property", (atRule) => {
1041
- const prop = atRule.params.trim();
1042
- if (prop.startsWith("--tw-")) props.add(prop);
1043
- });
1044
- return props;
1045
- }
1046
- function usesTailwindcssV4ContentVariable(root) {
1047
- let used = false;
1048
- root.walkDecls((decl) => {
1049
- if (TW_CONTENT_VAR_RE.test(decl.value)) used = true;
1050
- });
1051
- return used;
1052
- }
1053
- function createUsedCssVarsV4Nodes(usedProps) {
1054
- return nodes.filter((def) => usedProps.has(def.prop) && !UNSUPPORTED_CUSTOM_PROPERTY_DEFAULT_PROPS.has(def.prop)).map((def) => new Declaration({
1055
- prop: def.prop,
1056
- value: def.value
1057
- }));
1058
- }
1059
- function isInsideAtRule(decl, name) {
1060
- let parent = decl.parent;
1061
- while (parent) {
1062
- if (parent.type === "atrule" && parent.name === name) return true;
1063
- parent = parent.parent;
1064
- }
1065
- return false;
1066
- }
1067
- function isDefaultVariableScopeRule(rule) {
1068
- const selectors = rule.selectors.map((selector) => selector.trim());
1069
- if (!selectors.every((selector) => DEFAULT_VARIABLE_SCOPE_SELECTORS.has(selector))) return false;
1070
- if (!selectors.some((selector) => selector === "*" || selector === "view" || selector === "text")) return false;
1071
- let hasDeclaration = false;
1072
- let onlyCustomProperties = true;
1073
- rule.each((node) => {
1074
- if (node.type !== "decl") return;
1075
- hasDeclaration = true;
1076
- if (!node.prop.startsWith("--")) onlyCustomProperties = false;
1077
- });
1078
- return hasDeclaration && onlyCustomProperties;
1079
- }
1080
- function collectScopedTailwindcssV4DefaultVariables(root) {
1081
- const props = /* @__PURE__ */ new Set();
1082
- root.walkDecls((decl) => {
1083
- if (!decl.prop.startsWith("--tw-")) return;
1084
- if (isInsideAtRule(decl, "supports")) return;
1085
- if (decl.parent?.type === "rule" && isDefaultVariableScopeRule(decl.parent)) props.add(decl.prop);
1086
- });
1087
- return props;
1088
- }
1089
- function createMissingCssVarsV4Nodes(root, usedProps) {
1090
- const scopedProps = collectScopedTailwindcssV4DefaultVariables(root);
1091
- return nodes.filter((def) => usedProps.has(def.prop) && !scopedProps.has(def.prop) && !UNSUPPORTED_CUSTOM_PROPERTY_DEFAULT_PROPS.has(def.prop)).map((def) => new Declaration({
1092
- prop: def.prop,
1093
- value: def.value
1094
- }));
1095
- }
1096
- //#endregion
1097
- //#region src/compat/color-mix.ts
1098
- const DYNAMIC_VAR_FALLBACK_PLACEHOLDER_PREFIX = "__weapp_tw_var_fallback_";
1099
- function getStandaloneDynamicVarWithFallback(value) {
1100
- const nodes = valueParser(value).nodes.filter((node) => node.type !== "space" && node.type !== "comment");
1101
- const variable = nodes.length === 1 ? nodes[0] : void 0;
1102
- const property = variable?.type === "function" ? variable.nodes.find((node) => node.type === "word" && node.value.startsWith("--")) : void 0;
1103
- if (variable?.type !== "function" || variable.value.toLowerCase() !== "var" || property?.type !== "word" || isTailwindcssV4ThemeVariable(property.value) || !variable.nodes.some((node) => node.type === "div" && node.value === ",")) return;
1104
- return variable;
1105
- }
1106
- /**
1107
- * 保护带 fallback 的作者 CSS 变量,避免兼容插件把它错误静态化。
1108
- */
1109
- function protectDynamicVarFallbacks(css) {
1110
- if (!css.includes("var(") || !css.includes(",")) return {
1111
- css,
1112
- restore: (value) => value
1113
- };
1114
- const replacements = /* @__PURE__ */ new Map();
1115
- let root;
1116
- try {
1117
- root = postcss.parse(css);
1118
- } catch {
1119
- return {
1120
- css,
1121
- restore: (value) => value
1122
- };
1123
- }
1124
- root.walkDecls((decl) => {
1125
- if (!getStandaloneDynamicVarWithFallback(decl.value)) return;
1126
- const placeholder = `${DYNAMIC_VAR_FALLBACK_PLACEHOLDER_PREFIX}${replacements.size}__`;
1127
- replacements.set(placeholder, decl.value);
1128
- decl.value = placeholder;
1129
- });
1130
- if (replacements.size === 0) return {
1131
- css,
1132
- restore: (value) => value
1133
- };
1134
- return {
1135
- css: root.toString(),
1136
- restore(value) {
1137
- let restored = value;
1138
- for (const [placeholder, replacement] of replacements) restored = restored.split(placeholder).join(replacement);
1139
- return restored;
1140
- }
1141
- };
1142
- }
1143
- function normalizeModernColorValue(value, customPropertyValues = /* @__PURE__ */ new Map()) {
1144
- if (!hasUnsupportedModernColorFunction(value)) return {
1145
- value,
1146
- changed: false,
1147
- hasUnsupported: false
1148
- };
1149
- const parsed = valueParser(value);
1150
- let changed = false;
1151
- parsed.walk((node) => {
1152
- if (node.type !== "function") return;
1153
- const name = node.value.toLowerCase();
1154
- const source = valueParser.stringify(node);
1155
- let normalized;
1156
- if (MODERN_COLOR_FUNCTION_NAMES.has(name) || name === "color" && isDisplayP3ColorFunction(source) || isModernColorSyntaxFunction(source)) normalized = normalizeStandaloneColorFunction(source);
1157
- else if (name === "color-mix") normalized = tryResolveColorMix(node, customPropertyValues)?.value;
1158
- if (!normalized) return;
1159
- const mutableNode = node;
1160
- mutableNode.type = "word";
1161
- mutableNode.value = normalized;
1162
- delete mutableNode.nodes;
1163
- changed = true;
1164
- });
1165
- const nextValue = changed ? parsed.toString() : value;
1166
- return {
1167
- value: nextValue,
1168
- changed,
1169
- hasUnsupported: hasUnsupportedModernColorFunction(nextValue)
1170
- };
1171
- }
1172
- function createPlaceholder(index) {
1173
- return `${PLACEHOLDER_PREFIX}${index}__`;
1174
- }
1175
- function unwrapProtectedSupports(cssRoot) {
1176
- cssRoot.walkAtRules("supports", (atRule) => {
1177
- if (!atRule.nodes || !atRule.toString().includes("__weapp_tw_color_mix_")) return;
1178
- atRule.replaceWith(atRule.nodes);
1179
- });
1180
- }
1181
- function protectDynamicColorMixAlpha(css, options = {}) {
1182
- if (!css.includes("color-mix")) return {
1183
- css,
1184
- restore: (value) => value
1185
- };
1186
- const replacements = /* @__PURE__ */ new Map();
1187
- const root = postcss.parse(css);
1188
- const customPropertyValues = new Map(options.customPropertyValues);
1189
- let changed = false;
1190
- root.walkDecls((decl) => {
1191
- if (decl.prop.startsWith("--") && !decl.value.includes("color-mix")) customPropertyValues.set(decl.prop, decl.value.trim());
1192
- });
1193
- root.walkDecls((decl) => {
1194
- if (!decl.value.includes("color-mix")) return;
1195
- const parsed = valueParser(decl.value);
1196
- let mutated = false;
1197
- parsed.walk((node) => {
1198
- if (node.type !== "function" || node.value.toLowerCase() !== "color-mix") return;
1199
- const resolved = tryResolveColorMix(node, customPropertyValues);
1200
- if (resolved) {
1201
- if (resolved.deferred) {
1202
- const placeholder = createPlaceholder(replacements.size);
1203
- replacements.set(placeholder, resolved.value);
1204
- const mutableNode = node;
1205
- mutableNode.type = "word";
1206
- mutableNode.value = placeholder;
1207
- delete mutableNode.nodes;
1208
- mutated = true;
1209
- return;
1210
- }
1211
- const mutableNode = node;
1212
- mutableNode.type = "word";
1213
- mutableNode.value = resolved.value;
1214
- delete mutableNode.nodes;
1215
- mutated = true;
1216
- }
1217
- });
1218
- if (mutated) {
1219
- decl.value = parsed.toString();
1220
- changed = true;
1221
- }
1222
- });
1223
- if (replacements.size > 0) unwrapProtectedSupports(root);
1224
- return {
1225
- css: changed ? root.toString() : css,
1226
- restore(value) {
1227
- let restored = value;
1228
- for (const [placeholder, replacement] of replacements) restored = restored.split(placeholder).join(replacement);
1229
- return restored;
1230
- }
1231
- };
1232
- }
1233
- //#endregion
1234
- //#region src/compat/mini-program-css/color-gamut.ts
1235
- const DISPLAY_P3_VALUE_RE = /color\(\s*display-p3\b/i;
1236
- const COLOR_GAMUT_P3_RE = /\(\s*color-gamut\s*:\s*p3\s*\)/i;
1237
- function isDisplayP3MediaRule(atRule) {
1238
- return atRule.name === "media" && COLOR_GAMUT_P3_RE.test(atRule.params);
1239
- }
1240
- function isDisplayP3Declaration(decl) {
1241
- return DISPLAY_P3_VALUE_RE.test(decl.value);
1242
- }
1243
- //#endregion
1244
- //#region src/compat/mini-program-css/root-cleanups.ts
1245
- function removeSpecificityPlaceholders(root) {
1246
- root.walkRules((rule) => {
1247
- if (!rule.selectors || rule.selectors.length === 0) return;
1248
- let changed = false;
1249
- const selectors = rule.selectors.map((selector) => {
1250
- let next = selector;
1251
- for (const suffix of SPECIFICITY_PLACEHOLDER_SUFFIXES) if (next.includes(suffix)) next = next.split(suffix).join("");
1252
- if (next !== selector) changed = true;
1253
- return next;
1254
- });
1255
- if (changed) rule.selectors = selectors;
1256
- });
1257
- }
1258
- function hasMiniProgramCssSpecificityPlaceholders(source) {
1259
- return SPECIFICITY_PLACEHOLDER_SUFFIXES.some((suffix) => source.includes(suffix));
1260
- }
1261
- function stripMiniProgramCssSpecificityPlaceholders(source) {
1262
- let output = source;
1263
- for (const suffix of SPECIFICITY_PLACEHOLDER_SUFFIXES) if (output.includes(suffix)) output = output.split(suffix).join("");
1264
- return output;
1265
- }
1266
- const removeSpecificityPlaceholdersFromSource = stripMiniProgramCssSpecificityPlaceholders;
1267
- function removeRootSpecificityPlaceholders(root) {
1268
- root.walkRules((rule) => {
1269
- if (!rule.selectors || rule.selectors.length === 0) return;
1270
- let changed = false;
1271
- const selectors = rule.selectors.map((selector) => {
1272
- let next = selector;
1273
- for (const scopeSelector of MINI_PROGRAM_THEME_SCOPE_SELECTORS) for (const suffix of ROOT_SPECIFICITY_PLACEHOLDER_SUFFIXES) {
1274
- const target = `${scopeSelector}${suffix}`;
1275
- if (next.includes(target)) next = next.split(target).join(scopeSelector);
1276
- }
1277
- if (next !== selector) changed = true;
1278
- return next;
1279
- });
1280
- if (changed) rule.selectors = selectors;
1281
- });
1282
- }
1283
- function isEffectivelyEmptyContainer(container) {
1284
- return container.nodes !== void 0 && container.nodes.every((node) => node.type === "comment");
1285
- }
1286
- function isKeyframeStepRule(rule) {
1287
- return rule.parent?.type === "atrule" && rule.parent.name.toLowerCase().endsWith("keyframes");
1288
- }
1289
- function removeEmptyAtRules$1(root) {
1290
- let removed = 0;
1291
- const visit = (container) => {
1292
- for (const node of [...container.nodes ?? []]) {
1293
- if (!("nodes" in node) || node.nodes === void 0) continue;
1294
- visit(node);
1295
- if (node.type === "atrule" && node.parent && isEffectivelyEmptyContainer(node)) {
1296
- node.remove();
1297
- removed++;
1298
- }
1299
- }
1300
- };
1301
- visit(root);
1302
- return removed;
1303
- }
1304
- function removeEmptyBlockAtRules(root) {
1305
- let removed = 0;
1306
- root.walkAtRules((atRule) => {
1307
- if (atRule.nodes?.length === 0) {
1308
- atRule.remove();
1309
- removed++;
1310
- }
1311
- });
1312
- return removed;
1313
- }
1314
- function removeEmptyAtRuleAncestors(parent) {
1315
- while (parent?.type === "atrule" && isEffectivelyEmptyContainer(parent)) {
1316
- const nextParent = parent.parent;
1317
- parent.remove();
1318
- parent = nextParent?.type === "atrule" ? nextParent : void 0;
1319
- }
1320
- }
1321
- function removeEmptyRules(root) {
1322
- let removed = 0;
1323
- root.walkRules((rule) => {
1324
- if (isKeyframeStepRule(rule) || !rule.parent || !isEffectivelyEmptyContainer(rule)) return;
1325
- const parent = rule.parent;
1326
- rule.remove();
1327
- removeEmptyAtRuleAncestors(parent);
1328
- removed++;
1329
- });
1330
- return removed;
1331
- }
1332
- function removeUnsupportedBrowserSelectors(root) {
1333
- root.walkRules((rule) => {
1334
- if (!rule.selectors || rule.selectors.length === 0) return;
1335
- if (isUnsupportedBrowserPreflightSelector(rule.selector)) {
1336
- const parent = rule.parent;
1337
- rule.remove();
1338
- removeEmptyAtRuleAncestors(parent);
1339
- return;
1340
- }
1341
- if (isBrowserElementPreflightRule(rule)) {
1342
- const parent = rule.parent;
1343
- rule.remove();
1344
- removeEmptyAtRuleAncestors(parent);
1345
- return;
1346
- }
1347
- const selectors = rule.selectors.filter((selector) => !isUnsupportedBrowserSelector(selector));
1348
- if (selectors.length === rule.selectors.length) return;
1349
- if (selectors.length === 0) {
1350
- const parent = rule.parent;
1351
- rule.remove();
1352
- removeEmptyAtRuleAncestors(parent);
1353
- return;
1354
- }
1355
- rule.selectors = selectors;
1356
- });
1357
- }
1358
- function removeDeclarationAndEmptyRule(decl) {
1359
- const parent = decl.parent;
1360
- decl.remove();
1361
- if (parent?.type === "rule" && parent.nodes.length === 0) {
1362
- const ruleParent = parent.parent;
1363
- parent.remove();
1364
- removeEmptyAtRuleAncestors(ruleParent);
1365
- }
1366
- }
1367
- function removeEmptyStandardDeclarations(root) {
1368
- root.walkDecls((decl) => {
1369
- if (!decl.prop.startsWith("--") && decl.value.trim().length === 0 && decl.next()?.type !== "comment") removeDeclarationAndEmptyRule(decl);
1370
- });
1371
- }
1372
- function removeDisplayP3Declarations(root) {
1373
- root.walkAtRules((atRule) => {
1374
- if (isDisplayP3MediaRule(atRule)) {
1375
- const parent = atRule.parent;
1376
- atRule.remove();
1377
- removeEmptyAtRuleAncestors(parent);
1378
- }
1379
- });
1380
- }
1381
- const SIMPLE_MIN_WIDTH_MEDIA_RE = /^\(\s*min-width\s*:[^)]+\)$/i;
1382
- const TAILWIND_GENERATED_TOKEN_COMMENT_RE = /^\s*tokens:\s*container\s*<=\s*<tailwind generated>\s*$/i;
1383
- function isContainerMaxWidthOnlyRule(rule) {
1384
- if (!rule.selectors || rule.selectors.length !== 1 || rule.selectors[0] !== ".container") return false;
1385
- const declarations = rule.nodes?.filter((node) => node.type === "decl") ?? [];
1386
- return declarations.length === 1 && declarations[0]?.prop === "max-width" && (rule.nodes ?? []).every((node) => node.type === "decl" || node.type === "comment");
1387
- }
1388
- function removeTailwindContainerMaxWidthMediaRules(root) {
1389
- root.walkAtRules("media", (atRule) => {
1390
- if (!SIMPLE_MIN_WIDTH_MEDIA_RE.test(atRule.params.trim())) return;
1391
- atRule.walkRules((rule) => {
1392
- if (!isContainerMaxWidthOnlyRule(rule)) return;
1393
- const parent = rule.parent;
1394
- rule.remove();
1395
- removeEmptyAtRuleAncestors(parent);
1396
- });
1397
- });
1398
- }
1399
- function isContainerWidthOnlyRule(rule) {
1400
- if (!rule.selectors || rule.selectors.length !== 1 || rule.selectors[0] !== ".container") return false;
1401
- const declarations = rule.nodes?.filter((node) => node.type === "decl") ?? [];
1402
- return declarations.length === 1 && declarations[0]?.prop === "width" && declarations[0].value.trim() === "100%" && (rule.nodes ?? []).every((node) => node.type === "decl" || node.type === "comment");
1403
- }
1404
- function isTailwindGeneratedContainerRule(rule) {
1405
- const previous = rule.prev();
1406
- return previous?.type === "comment" && TAILWIND_GENERATED_TOKEN_COMMENT_RE.test(previous.text);
1407
- }
1408
- function removeTailwindContainerWidthRules(root, options = {}) {
1409
- root.walkRules((rule) => {
1410
- if (!isContainerWidthOnlyRule(rule)) return;
1411
- if (options.generatedOnly && !isTailwindGeneratedContainerRule(rule)) return;
1412
- const parent = rule.parent;
1413
- if (isTailwindGeneratedContainerRule(rule)) rule.prev()?.remove();
1414
- rule.remove();
1415
- removeEmptyAtRuleAncestors(parent);
1416
- });
1417
- }
1418
- function removeUnsupportedModernColorDeclarations(root) {
1419
- const customPropertyValues = /* @__PURE__ */ new Map();
1420
- root.walkDecls((decl) => {
1421
- if (decl.prop.startsWith("--")) customPropertyValues.set(decl.prop, decl.value.trim());
1422
- });
1423
- root.walkDecls((decl) => {
1424
- const normalized = normalizeModernColorValue(decl.value, customPropertyValues);
1425
- if (normalized.changed) {
1426
- decl.value = normalized.value;
1427
- if (decl.prop.startsWith("--")) customPropertyValues.set(decl.prop, decl.value.trim());
1428
- }
1429
- if (normalized.hasUnsupported) removeDeclarationAndEmptyRule(decl);
1430
- });
1431
- }
1432
- //#endregion
1433
- //#region src/compat/mini-program-prefixes.ts
1434
- const PRESERVED_WEBKIT_DECLARATION_PROPS = /* @__PURE__ */ new Set([
1435
- "-webkit-box-orient",
1436
- "-webkit-line-clamp",
1437
- "-webkit-overflow-scrolling",
1438
- "-webkit-text-fill-color",
1439
- "-webkit-text-stroke",
1440
- "-webkit-text-stroke-color",
1441
- "-webkit-text-stroke-width"
1442
- ]);
1443
- const PRESERVED_WEBKIT_VALUE_DECLARATIONS = /* @__PURE__ */ new Map([["display", /* @__PURE__ */ new Set(["-webkit-box"])], ["-webkit-background-clip", /* @__PURE__ */ new Set(["text"])]]);
1444
- const TRANSITION_PROPS = /* @__PURE__ */ new Set(["transition", "transition-property"]);
1445
- function splitTopLevelCommaList(value) {
1446
- const parts = [];
1447
- let start = 0;
1448
- let depth = 0;
1449
- let quote;
1450
- let escaped = false;
1451
- for (let i = 0; i < value.length; i++) {
1452
- const char = value[i];
1453
- if (escaped) {
1454
- escaped = false;
1455
- continue;
1456
- }
1457
- if (char === "\\") {
1458
- escaped = true;
1459
- continue;
1460
- }
1461
- if (quote) {
1462
- if (char === quote) quote = void 0;
1463
- continue;
1464
- }
1465
- if (char === "\"" || char === "'") {
1466
- quote = char;
1467
- continue;
1468
- }
1469
- if (char === "(") {
1470
- depth++;
1471
- continue;
1472
- }
1473
- if (char === ")") {
1474
- depth = Math.max(0, depth - 1);
1475
- continue;
1476
- }
1477
- if (char === "," && depth === 0) {
1478
- parts.push(value.slice(start, i));
1479
- start = i + 1;
1480
- }
1481
- }
1482
- parts.push(value.slice(start));
1483
- return parts;
1484
- }
1485
- function isPreservedWebkitDeclaration(decl) {
1486
- const prop = decl.prop.toLowerCase();
1487
- if (prop.startsWith("-webkit-mask")) return true;
1488
- if (PRESERVED_WEBKIT_DECLARATION_PROPS.has(prop)) return true;
1489
- return PRESERVED_WEBKIT_VALUE_DECLARATIONS.get(prop)?.has(decl.value.trim().toLowerCase()) ?? false;
1490
- }
1491
- function normalizeTransitionValue(value) {
1492
- return splitTopLevelCommaList(value).map((part) => part.trim()).filter((part) => part.length > 0 && !part.toLowerCase().startsWith("-webkit-")).join(", ");
1493
- }
1494
- function hasUnsupportedWebkitKeywordValue(decl) {
1495
- const value = decl.value.trim().toLowerCase();
1496
- if (!value.startsWith("-webkit-")) return false;
1497
- if (PRESERVED_WEBKIT_VALUE_DECLARATIONS.get(decl.prop.toLowerCase())?.has(value)) return false;
1498
- return /^-webkit-[\w-]+$/.test(value);
1499
- }
1500
- /**
1501
- * 收敛小程序 CSS 中的 WebKit 前缀,只保留 WXSS 里有实际价值的兼容写法。
1502
- */
1503
- function normalizeMiniProgramPrefixedDeclaration(decl) {
1504
- const prop = decl.prop.toLowerCase();
1505
- if (TRANSITION_PROPS.has(prop) && decl.value.toLowerCase().includes("-webkit-")) {
1506
- const value = normalizeTransitionValue(decl.value);
1507
- if (value.length === 0) {
1508
- decl.remove();
1509
- return;
1510
- }
1511
- decl.value = value;
1512
- }
1513
- if (prop.startsWith("-webkit-") && !isPreservedWebkitDeclaration(decl)) {
1514
- decl.remove();
1515
- return;
1516
- }
1517
- if (hasUnsupportedWebkitKeywordValue(decl)) decl.remove();
1518
- }
1519
- function removeUnsupportedMiniProgramPrefixedAtRule(atRule) {
1520
- if (atRule.name.toLowerCase() === "-webkit-keyframes") atRule.remove();
1521
- }
1522
- //#endregion
1523
- //#region src/compat/tailwindcss-v4/gradients.ts
1524
- function collectTailwindcssV4ThemeVariables(root) {
1525
- const variables = /* @__PURE__ */ new Map();
1526
- root.walkRules((rule) => {
1527
- if (!testIfRootHostForV4(rule) && !rule.selector.includes("page") && !rule.selector.includes(".tw-root")) return;
1528
- rule.walkDecls((decl) => {
1529
- if (decl.prop.startsWith("--color-")) variables.set(decl.prop, decl.value);
1530
- });
1531
- });
1532
- return variables;
1533
- }
1534
- function resolveTailwindcssV4GradientColor(value, themeVariables) {
1535
- const trimmed = value.trim();
1536
- const match = COLOR_VAR_RE.exec(trimmed);
1537
- if (!match) return trimmed;
1538
- return themeVariables.get(match[1]) ?? trimmed;
1539
- }
1540
- function getSingleClassSelector(selector) {
1541
- const match = SIMPLE_CLASS_SELECTOR_RE.exec(selector.trim());
1542
- return match ? match[1] : void 0;
1543
- }
1544
- function normalizeDeclarationValue(value) {
1545
- return value.replace(/\s+/g, " ").trim();
1546
- }
1547
- function normalizeTailwindcssV4GradientPosition(value) {
1548
- return value.replace(/calc\(\s*([+-]?(?:\d+(?:\.\d+)?|\.\d+)(?:deg|grad|rad|turn))\s*\*\s*-1\s*\)/gi, "-$1").replace(/^in\s+(?:oklab|oklch|hsl|srgb)(?:\s+(?:longer|shorter|increasing|decreasing)\s+hue)?$/i, "").replace(/\s+in\s+(?:oklab|oklch|hsl|srgb)(?:\s+(?:longer|shorter|increasing|decreasing)\s+hue)?\s*$/i, "").replace(/\s+(?:longer|shorter|increasing|decreasing)\s*$/i, "").trim();
1549
- }
1550
- function normalizeTailwindcssV4InfinityCalcValue(value) {
1551
- return INFINITY_CALC_VALUE_REGEXP.test(value.trim()) ? `${CLAMP_PX}px` : value;
1552
- }
1553
- const INFINITY_CALC_CSS_RE = /calc\(\s*infinity\s*\*\s*(?:\d+(?:\.\d*)?|\.\d+)r?px\s*\)/gi;
1554
- /** 在预处理器解析前收敛 Tailwind v4 生成的无限圆角,避免 Sass 将 infinity 当作非法表达式。 */
1555
- function normalizeTailwindcssV4InfinityCalcCss(css) {
1556
- return css.replace(INFINITY_CALC_CSS_RE, `${CLAMP_PX}px`);
1557
- }
1558
- function normalizeTailwindcssV4GradientDirectionDeclaration(rule, decl) {
1559
- const normalized = normalizeTailwindcssV4GradientPosition(decl.value);
1560
- if (normalized) return normalized;
1561
- const backgroundImageDecl = rule.nodes.find((node) => {
1562
- return node.type === "decl" && node.prop === "background-image";
1563
- });
1564
- if (!backgroundImageDecl) return normalized;
1565
- if (/^radial-gradient\(/i.test(backgroundImageDecl.value)) return "at center";
1566
- if (/^conic-gradient\(/i.test(backgroundImageDecl.value)) return "from 0deg";
1567
- return normalized;
1568
- }
1569
- function appendStopPosition(color, position) {
1570
- const normalizedPosition = position?.trim();
1571
- return normalizedPosition ? `${color} ${normalizedPosition}` : color;
1572
- }
1573
- function getGradientStopsFallback(value) {
1574
- if (!value.includes("var(") || !value.includes("--tw-gradient-stops")) return;
1575
- const parsed = valueParser(value);
1576
- let fallback;
1577
- parsed.walk((node) => {
1578
- if (fallback || node.type !== "function" || node.value.toLowerCase() !== "var") return;
1579
- const firstCommaIndex = node.nodes.findIndex((child) => child.type === "div" && child.value === ",");
1580
- const firstArg = node.nodes.find((child) => child.type !== "space");
1581
- if (firstArg?.type !== "word" || firstArg.value !== "--tw-gradient-stops" || firstCommaIndex < 0) return;
1582
- fallback = valueParser.stringify(node.nodes.slice(firstCommaIndex + 1)).trim();
1583
- });
1584
- return fallback;
1585
- }
1586
- function isTailwindcssV4GradientDirectionRule(rule) {
1587
- const classSelector = getSingleClassSelector(rule.selector);
1588
- if (!classSelector || !GRADIENT_DIRECTION_CLASS_RE.test(classSelector)) return false;
1589
- return rule.nodes.some((node) => {
1590
- return node.type === "decl" && (node.prop === "--tw-gradient-position" || node.prop === "background-image" && node.value.includes("linear-gradient("));
1591
- });
1592
- }
1593
- function reorderTailwindcssV4GradientDirectionRule(rule) {
1594
- const gradientPositionDecls = [];
1595
- const gradientBackgroundDecls = [];
1596
- for (const node of rule.nodes) {
1597
- if (node.type !== "decl") continue;
1598
- if (node.prop === "--tw-gradient-position") gradientPositionDecls.push(node);
1599
- else if (node.prop === "background-image" && node.value.includes("linear-gradient(")) gradientBackgroundDecls.push(node);
1600
- }
1601
- if (gradientPositionDecls.length === 0 || gradientBackgroundDecls.length === 0) return;
1602
- for (const decl of gradientPositionDecls) decl.value = normalizeTailwindcssV4GradientDirectionDeclaration(rule, decl);
1603
- const anchor = rule.nodes.find((node) => {
1604
- return node.type === "decl" && (node.prop === "--tw-gradient-position" || node.prop === "background-image" && node.value.includes("linear-gradient("));
1605
- });
1606
- if (!anchor) return;
1607
- const ordered = [...gradientPositionDecls, ...gradientBackgroundDecls];
1608
- const orderedClones = ordered.map((decl) => decl.clone());
1609
- anchor.replaceWith(...orderedClones);
1610
- for (const decl of ordered) if (decl.parent) decl.remove();
1611
- }
1612
- function mergeTailwindcssV4GradientDirectionRules(root) {
1613
- const seen = /* @__PURE__ */ new Map();
1614
- root.walkRules((rule) => {
1615
- if (!isTailwindcssV4GradientDirectionRule(rule)) return;
1616
- rule.walkDecls("--tw-gradient-position", (decl) => {
1617
- decl.value = normalizeTailwindcssV4GradientDirectionDeclaration(rule, decl);
1618
- });
1619
- const selector = rule.selector.trim();
1620
- const previous = seen.get(selector);
1621
- if (!previous || previous.parent !== rule.parent) {
1622
- seen.set(selector, rule);
1623
- return;
1624
- }
1625
- for (const node of [...rule.nodes]) {
1626
- if (node.type !== "decl") continue;
1627
- if (node.prop !== "--tw-gradient-position" && node.prop !== "background-image") continue;
1628
- previous.append(node.clone());
1629
- }
1630
- reorderTailwindcssV4GradientDirectionRule(previous);
1631
- rule.remove();
1632
- });
1633
- }
1634
- function createTailwindcssV4MiniProgramGradientValue(gradient, from, to, via) {
1635
- const stops = [gradient.position, appendStopPosition(from.color, from.position)];
1636
- if (via) stops.push(appendStopPosition(via.color, via.position));
1637
- stops.push(appendStopPosition(to.color, to.position));
1638
- return `${gradient.type}-gradient(${stops.filter(Boolean).join(", ")})`;
1639
- }
1640
- function appendTailwindcssV4MiniProgramGradientRules(root) {
1641
- const themeVariables = collectTailwindcssV4ThemeVariables(root);
1642
- const gradients = [];
1643
- const fromColors = /* @__PURE__ */ new Map();
1644
- const viaColors = /* @__PURE__ */ new Map();
1645
- const toColors = /* @__PURE__ */ new Map();
1646
- const fromPositions = [];
1647
- const viaPositions = [];
1648
- const toPositions = [];
1649
- const directBackgroundImages = [];
1650
- const existingBackgroundImages = /* @__PURE__ */ new Map();
1651
- const ruleOrder = /* @__PURE__ */ new Map();
1652
- let order = 0;
1653
- root.walkRules((rule) => {
1654
- const classSelector = getSingleClassSelector(rule.selector);
1655
- const currentOrder = order++;
1656
- if (classSelector) ruleOrder.set(classSelector, currentOrder);
1657
- rule.walkDecls("background-image", (decl) => {
1658
- const selector = rule.selector.trim();
1659
- const values = existingBackgroundImages.get(selector);
1660
- if (values) values.add(normalizeDeclarationValue(decl.value));
1661
- else existingBackgroundImages.set(selector, /* @__PURE__ */ new Set([normalizeDeclarationValue(decl.value)]));
1662
- });
1663
- if (classSelector) {
1664
- const gradientPositionDecl = rule.nodes.find((node) => {
1665
- return node.type === "decl" && node.prop === "--tw-gradient-position";
1666
- });
1667
- const gradientBackgroundDecl = rule.nodes.find((node) => {
1668
- return node.type === "decl" && node.prop === "background-image" && GRADIENT_BACKGROUND_RE.test(node.value);
1669
- });
1670
- if (gradientPositionDecl && gradientBackgroundDecl) {
1671
- const gradientType = GRADIENT_BACKGROUND_RE.exec(gradientBackgroundDecl.value)?.[1];
1672
- if (gradientType) {
1673
- gradients.push({
1674
- classSelector,
1675
- order: currentOrder,
1676
- position: normalizeTailwindcssV4GradientDirectionDeclaration(rule, gradientPositionDecl),
1677
- type: gradientType
1678
- });
1679
- const fallback = GRADIENT_STOPS_VAR_RE.test(gradientBackgroundDecl.value) ? getGradientStopsFallback(gradientBackgroundDecl.value) : void 0;
1680
- if (fallback) directBackgroundImages.push({
1681
- selector: rule.selector.trim(),
1682
- value: `${gradientType}-gradient(${fallback})`
1683
- });
1684
- }
1685
- }
1686
- rule.walkDecls((decl) => {
1687
- if (decl.prop === "--tw-gradient-from") fromColors.set(classSelector, {
1688
- classSelector,
1689
- color: resolveTailwindcssV4GradientColor(decl.value, themeVariables),
1690
- order: currentOrder
1691
- });
1692
- else if (decl.prop === "--tw-gradient-from-position") fromPositions.push({
1693
- classSelector,
1694
- position: decl.value
1695
- });
1696
- else if (decl.prop === "--tw-gradient-via") viaColors.set(classSelector, {
1697
- classSelector,
1698
- color: resolveTailwindcssV4GradientColor(decl.value, themeVariables),
1699
- order: currentOrder
1700
- });
1701
- else if (decl.prop === "--tw-gradient-via-position") viaPositions.push({
1702
- classSelector,
1703
- position: decl.value
1704
- });
1705
- else if (decl.prop === "--tw-gradient-to") toColors.set(classSelector, {
1706
- classSelector,
1707
- color: resolveTailwindcssV4GradientColor(decl.value, themeVariables),
1708
- order: currentOrder
1709
- });
1710
- else if (decl.prop === "--tw-gradient-to-position") toPositions.push({
1711
- classSelector,
1712
- position: decl.value
1713
- });
1714
- });
1715
- }
1716
- });
1717
- const fromVariants = [];
1718
- const viaVariants = [];
1719
- const toVariants = [];
1720
- const positionedFromVariants = [];
1721
- const positionedViaVariants = [];
1722
- const positionedToVariants = [];
1723
- for (const color of fromColors.values()) {
1724
- fromVariants.push(color);
1725
- for (const position of fromPositions) positionedFromVariants.push({
1726
- ...color,
1727
- classSelector: `${color.classSelector}.${position.classSelector}`,
1728
- order: Math.max(color.order, ruleOrder.get(position.classSelector) ?? color.order),
1729
- position: position.position
1730
- });
1731
- }
1732
- for (const color of viaColors.values()) {
1733
- viaVariants.push(color);
1734
- for (const position of viaPositions) positionedViaVariants.push({
1735
- ...color,
1736
- classSelector: `${color.classSelector}.${position.classSelector}`,
1737
- order: Math.max(color.order, ruleOrder.get(position.classSelector) ?? color.order),
1738
- position: position.position
1739
- });
1740
- }
1741
- for (const color of toColors.values()) {
1742
- toVariants.push(color);
1743
- for (const position of toPositions) positionedToVariants.push({
1744
- ...color,
1745
- classSelector: `${color.classSelector}.${position.classSelector}`,
1746
- order: Math.max(color.order, ruleOrder.get(position.classSelector) ?? color.order),
1747
- position: position.position
1748
- });
1749
- }
1750
- function appendGradientRule(selector, value) {
1751
- const normalizedValue = normalizeDeclarationValue(value);
1752
- if (existingBackgroundImages.get(selector)?.has(normalizedValue)) return;
1753
- existingBackgroundImages.set(selector, /* @__PURE__ */ new Set([...existingBackgroundImages.get(selector) ?? [], normalizedValue]));
1754
- root.append(rule({
1755
- selector,
1756
- nodes: [new Declaration({
1757
- prop: "background-image",
1758
- value
1759
- })]
1760
- }));
1761
- }
1762
- for (const { selector, value } of directBackgroundImages) appendGradientRule(selector, value);
1763
- function appendGradientCombinations(gradient, fromRules, viaRules, toRules) {
1764
- for (const from of fromRules) for (const to of toRules) {
1765
- appendGradientRule(`.${gradient.classSelector}.${from.classSelector}.${to.classSelector}`, createTailwindcssV4MiniProgramGradientValue(gradient, from, to));
1766
- for (const via of viaRules) appendGradientRule(`.${gradient.classSelector}.${from.classSelector}.${via.classSelector}.${to.classSelector}`, createTailwindcssV4MiniProgramGradientValue(gradient, from, to, via));
1767
- }
1768
- }
1769
- for (const gradient of gradients) {
1770
- if (gradient.position.includes(",") || /^var\(/i.test(gradient.position)) continue;
1771
- appendGradientCombinations(gradient, fromVariants, viaVariants, toVariants);
1772
- appendGradientCombinations(gradient, positionedFromVariants, positionedViaVariants, positionedToVariants);
1773
- }
1774
- }
1775
- //#endregion
1776
- //#region src/compat/tailwindcss-v4/declarations.ts
1777
- function normalizeTailwindcssV4EmptyVarFallback(value) {
1778
- if (!value.includes("var(") || !value.includes("--tw-")) return value;
1779
- const parsed = valueParser(value);
1780
- let changed = false;
1781
- parsed.walk((node) => {
1782
- if (node.type !== "function" || node.value.toLowerCase() !== "var") return;
1783
- const firstArg = node.nodes.find((child) => child.type !== "space");
1784
- const lastArg = node.nodes.findLast((child) => child.type !== "space");
1785
- if (firstArg?.type !== "word" || !firstArg.value.startsWith("--tw-") || lastArg?.type !== "div" || lastArg.value !== "," || node.after === " ") return;
1786
- node.after = " ";
1787
- changed = true;
1788
- });
1789
- return changed ? parsed.toString() : value;
1790
- }
1791
- function normalizeTailwindcssV4GradientStopsFallback(value) {
1792
- if (!value.includes("var(") || !value.includes("--tw-gradient-via-stops")) return value;
1793
- const parsed = valueParser(value);
1794
- let changed = false;
1795
- function normalizeNodes(nodes) {
1796
- for (let index = 0; index < nodes.length; index++) {
1797
- const node = nodes[index];
1798
- if (!node) continue;
1799
- if (node.type === "function" && node.value.toLowerCase() !== "var") {
1800
- normalizeNodes(node.nodes);
1801
- continue;
1802
- }
1803
- if (node.type !== "function") continue;
1804
- const firstArg = node.nodes.filter((child) => child.type !== "space")[0];
1805
- if (firstArg?.type !== "word" || firstArg.value !== "--tw-gradient-via-stops") {
1806
- normalizeNodes(node.nodes);
1807
- continue;
1808
- }
1809
- const firstCommaIndex = node.nodes.findIndex((child) => child.type === "div" && child.value === ",");
1810
- if (firstCommaIndex < 0) continue;
1811
- const fallbackNodes = node.nodes.slice(firstCommaIndex + 1);
1812
- const splitIndex = fallbackNodes.findIndex((child) => child.type === "div" && child.value === ",");
1813
- if (splitIndex < 0) continue;
1814
- const viaFallbackNodes = fallbackNodes.slice(0, splitIndex);
1815
- const stopNodes = fallbackNodes.slice(splitIndex);
1816
- const nextVarNode = {
1817
- ...node,
1818
- nodes: [
1819
- {
1820
- type: "word",
1821
- value: "--tw-gradient-via-stops"
1822
- },
1823
- {
1824
- type: "div",
1825
- value: ",",
1826
- before: "",
1827
- after: " "
1828
- },
1829
- ...viaFallbackNodes
1830
- ],
1831
- sourceEndIndex: void 0,
1832
- sourceIndex: void 0
1833
- };
1834
- nodes.splice(index, 1, nextVarNode, ...stopNodes);
1835
- changed = true;
1836
- index += stopNodes.length;
1837
- }
1838
- }
1839
- normalizeNodes(parsed.nodes);
1840
- return changed ? parsed.toString() : value;
1841
- }
1842
- function normalizeTailwindcssV4GradientPositionFallback(value) {
1843
- if (!value.includes("var(") || !value.includes("--tw-gradient-")) return value;
1844
- const parsed = valueParser(value);
1845
- let changed = false;
1846
- parsed.walk((node) => {
1847
- if (node.type !== "function" || node.value.toLowerCase() !== "var") return;
1848
- const args = node.nodes.filter((child) => child.type !== "space");
1849
- const firstArg = args[0];
1850
- if (firstArg?.type !== "word" || !TW_GRADIENT_POSITION_PROPS.has(firstArg.value)) return;
1851
- const commaIndex = args.findIndex((child) => child.type === "div" && child.value === ",");
1852
- if (commaIndex === -1 ? void 0 : args[commaIndex]) {
1853
- if (!args.slice(commaIndex + 1).some((child) => child.type !== "space") && node.after !== " ") {
1854
- node.after = " ";
1855
- changed = true;
1856
- }
1857
- return;
1858
- }
1859
- node.nodes.push({
1860
- type: "div",
1861
- value: ",",
1862
- before: "",
1863
- after: ""
1864
- });
1865
- node.after = " ";
1866
- changed = true;
1867
- });
1868
- return changed ? parsed.toString() : value;
1869
- }
1870
- function normalizeTailwindcssV4Declaration(decl) {
1871
- let changed = false;
1872
- if (decl.prop === "--tw-gradient-via-stops" && decl.value.trim() === "initial") {
1873
- decl.remove();
1874
- return true;
1875
- }
1876
- const normalizedEmptyVarFallback = normalizeTailwindcssV4EmptyVarFallback(decl.value);
1877
- if (normalizedEmptyVarFallback !== decl.value) {
1878
- decl.value = normalizedEmptyVarFallback;
1879
- changed = true;
1880
- }
1881
- const normalizedGradientStopsFallback = normalizeTailwindcssV4GradientStopsFallback(decl.value);
1882
- if (normalizedGradientStopsFallback !== decl.value) {
1883
- decl.value = normalizedGradientStopsFallback;
1884
- changed = true;
1885
- }
1886
- const normalizedGradientPositionFallback = normalizeTailwindcssV4GradientPositionFallback(decl.value);
1887
- if (normalizedGradientPositionFallback !== decl.value) {
1888
- decl.value = normalizedGradientPositionFallback;
1889
- changed = true;
1890
- }
1891
- if (decl.prop === "--tw-gradient-position") {
1892
- const nextValue = decl.parent?.type === "rule" ? normalizeTailwindcssV4GradientDirectionDeclaration(decl.parent, decl) : normalizeTailwindcssV4GradientPosition(decl.value);
1893
- if (nextValue !== decl.value) {
1894
- decl.value = nextValue;
1895
- return true;
1896
- }
1897
- }
1898
- const normalizedInfinityCalcValue = normalizeTailwindcssV4InfinityCalcValue(decl.value);
1899
- if (normalizedInfinityCalcValue !== decl.value) {
1900
- decl.value = normalizedInfinityCalcValue;
1901
- return true;
1902
- }
1903
- if (decl.prop.includes("radius")) {
1904
- RADIUS_VALUE_RE.lastIndex = 0;
1905
- const next = decl.value.replace(RADIUS_VALUE_RE, (m, num) => {
1906
- const n = Number(num);
1907
- if (!Number.isFinite(n)) return `${CLAMP_PX}px`;
1908
- if (SCIENTIFIC_NOTATION_RE.test(String(num)) || n > 1e5) return `${CLAMP_PX}px`;
1909
- return m;
1910
- });
1911
- if (next !== decl.value) {
1912
- decl.value = next;
1913
- return true;
1914
- }
1915
- }
1916
- return changed;
1917
- }
1918
- //#endregion
1919
- //#region src/compat/mini-program-css/hoist.ts
1920
- const HOIST_ANCHOR_COMMENT = "__weapp_tailwindcss_base_anchor__";
1921
- function getTopDirectiveTail(root) {
1922
- let tail;
1923
- for (const node of root.nodes ?? []) {
1924
- if (node.type === "atrule" && (node.name === "charset" || node.name === "import")) {
1925
- tail = node;
1926
- continue;
1927
- }
1928
- break;
1929
- }
1930
- return tail;
1931
- }
1932
- function reorderPreflightResetDeclarations(rule) {
1933
- const declarations = (rule.nodes ?? []).filter((node) => node.type === "decl");
1934
- if (declarations.length <= 1) return;
1935
- const resetDeclarations = [];
1936
- const otherDeclarations = [];
1937
- for (const declaration of declarations) if (PREFLIGHT_RESET_PROPS.has(declaration.prop)) resetDeclarations.push(declaration);
1938
- else otherDeclarations.push(declaration);
1939
- if (resetDeclarations.length === 0 || otherDeclarations.length === 0) return;
1940
- const orderedDeclarations = [...resetDeclarations, ...otherDeclarations];
1941
- if (orderedDeclarations.every((declaration, index) => declaration === declarations[index])) return;
1942
- for (const declaration of declarations) declaration.remove();
1943
- rule.prepend(...orderedDeclarations);
1944
- rule.raws.semicolon = true;
1945
- }
1946
- function createHoistInsertionAnchor(root) {
1947
- for (const node of root.nodes ?? []) if (isMiniProgramPreflightRule(node) || isMiniProgramThemeVariableRule(node)) {
1948
- const anchor = postcss.comment({ text: HOIST_ANCHOR_COMMENT });
1949
- node.before(anchor);
1950
- return anchor;
1951
- }
1952
- }
1953
- function insertHoistedRules(root, rules, anchor) {
1954
- if (anchor && !anchor.parent) anchor = void 0;
1955
- if (rules.length === 0) {
1956
- anchor?.remove();
1957
- return;
1958
- }
1959
- const topDirectiveTail = getTopDirectiveTail(root);
1960
- const firstRule = rules[0];
1961
- if (!firstRule) return;
1962
- if (anchor) {
1963
- if (anchor.raws.before === void 0) delete firstRule.raws.before;
1964
- else firstRule.raws.before = anchor.raws.before;
1965
- anchor.replaceWith(rules);
1966
- return;
1967
- }
1968
- firstRule.raws.before = topDirectiveTail ? "\n" : "";
1969
- if (topDirectiveTail) topDirectiveTail.after(rules);
1970
- else root.prepend(rules);
1971
- }
1972
- function mergeEquivalentHoistedRules(rules) {
1973
- const mergedRules = [];
1974
- const ruleBySelector = /* @__PURE__ */ new Map();
1975
- const propsBySelector = /* @__PURE__ */ new Map();
1976
- for (const rule of rules) {
1977
- const key = getSortedRuleSelectorKey(rule);
1978
- const existingRule = ruleBySelector.get(key);
1979
- if (existingRule) {
1980
- const existingProps = propsBySelector.get(key) ?? /* @__PURE__ */ new Set();
1981
- const nextNodes = (rule.nodes ?? []).filter((node) => {
1982
- if (node.type !== "decl") return true;
1983
- if (existingProps.has(node.prop)) return false;
1984
- existingProps.add(node.prop);
1985
- return true;
1986
- });
1987
- existingRule.append(...nextNodes.map((node) => node.clone()));
1988
- reorderPreflightResetDeclarations(existingRule);
1989
- propsBySelector.set(key, existingProps);
1990
- continue;
1991
- }
1992
- ruleBySelector.set(key, rule);
1993
- propsBySelector.set(key, new Set((rule.nodes ?? []).flatMap((node) => node.type === "decl" ? [node.prop] : [])));
1994
- reorderPreflightResetDeclarations(rule);
1995
- mergedRules.push(rule);
1996
- }
1997
- return mergedRules;
1998
- }
1999
- //#endregion
2000
- //#region src/compat/mini-program-css/preflight.ts
2001
- const MINI_PROGRAM_PSEUDO_CONTENT_SELECTORS = /* @__PURE__ */ new Set(["::before", "::after"]);
2002
- function applyConfiguredPreflightDeclarations(rule, cssPreflight) {
2003
- if (!cssPreflight || typeof cssPreflight !== "object") return;
2004
- const configuredNodes = [];
2005
- const remainingNodes = [];
2006
- const remainingDeclarations = /* @__PURE__ */ new Map();
2007
- for (const node of rule.nodes ?? []) {
2008
- if (node.type !== "decl") {
2009
- remainingNodes.push(node);
2010
- continue;
2011
- }
2012
- if (Object.hasOwn(cssPreflight, node.prop)) {
2013
- remainingDeclarations.set(node.prop, node);
2014
- continue;
2015
- }
2016
- remainingNodes.push(node);
2017
- }
2018
- for (const [prop, value] of Object.entries(cssPreflight)) {
2019
- if (value === false) continue;
2020
- const declaration = remainingDeclarations.get(prop)?.clone() ?? postcss.decl({
2021
- prop,
2022
- value: value.toString()
2023
- });
2024
- declaration.value = value.toString();
2025
- configuredNodes.push(declaration);
2026
- }
2027
- rule.removeAll();
2028
- rule.append([...configuredNodes, ...remainingNodes]);
2029
- }
2030
- function collectPreflightRules(root, options = {}) {
2031
- const preflightNodes = [];
2032
- for (const node of root.nodes ?? []) if (isMiniProgramPreflightRule(node)) preflightNodes.push(node);
2033
- if (preflightNodes.length === 0) return [];
2034
- const clonedPreflightRules = preflightNodes.map((node) => {
2035
- const rule = node.clone();
2036
- rule.walkDecls("--tw-content", (decl) => {
2037
- if (isEmptyTwContentDeclaration(decl)) decl.remove();
2038
- });
2039
- return rule;
2040
- });
2041
- for (const rule of clonedPreflightRules) {
2042
- const selectors = getRuleSelectors(rule);
2043
- const hasElementSelector = selectors.some((selector) => selector === "view" || selector === "text");
2044
- if (selectors.length > 0 && selectors.every((selector) => MINI_PROGRAM_PSEUDO_CONTENT_SELECTORS.has(selector))) rule.remove();
2045
- else if (hasElementSelector && selectors.every((selector) => MINI_PROGRAM_ELEMENT_SCOPE_SELECTORS.has(selector))) {
2046
- if (options.cssPreflight === false) {
2047
- rule.removeAll();
2048
- continue;
2049
- }
2050
- rule.selector = MINI_PROGRAM_ELEMENT_SCOPE_SELECTOR;
2051
- applyConfiguredPreflightDeclarations(rule, options.cssPreflight);
2052
- }
2053
- }
2054
- const nonEmptyPreflightRules = [...clonedPreflightRules.filter((rule) => (rule.nodes?.length ?? 0) > 0)];
2055
- for (const node of preflightNodes) node.remove();
2056
- return nonEmptyPreflightRules;
2057
- }
2058
- function createPreflightResetRule(cssPreflight) {
2059
- if (!cssPreflight || typeof cssPreflight !== "object") return;
2060
- const rule = postcss.rule({ selector: MINI_PROGRAM_ELEMENT_SCOPE_SELECTOR });
2061
- for (const [prop, value] of Object.entries(cssPreflight)) {
2062
- if (value === false) continue;
2063
- rule.append({
2064
- prop,
2065
- value: value.toString()
2066
- });
2067
- }
2068
- return rule.nodes?.length ? rule : void 0;
2069
- }
2070
- //#endregion
2071
- //#region src/compat/mini-program-css/theme.ts
2072
- function collectThemeVariableRule(root, options = {}) {
2073
- const themeRules = [];
2074
- const declarations = /* @__PURE__ */ new Map();
2075
- const shouldPreserveContentInit = usesTwContentVariable(root);
2076
- for (const node of root.nodes ?? []) {
2077
- if (!isMiniProgramThemeVariableRule(node)) continue;
2078
- themeRules.push(node);
2079
- node.walkDecls((decl) => {
2080
- if (isDisplayP3Declaration(decl)) return;
2081
- if (decl.prop.startsWith("--tw-")) return;
2082
- if (!shouldPreserveContentInit && isEmptyTwContentDeclaration(decl)) return;
2083
- declarations.set(decl.prop, decl.clone());
2084
- });
2085
- }
2086
- for (const rule of themeRules) rule.remove();
2087
- if (declarations.size === 0) return;
2088
- const rule = postcss.rule({ selector: normalizeMiniProgramThemeScopeSelector(options.cssSelectorReplacement?.root) });
2089
- for (const decl of declarations.values()) rule.append(decl);
2090
- return rule;
2091
- }
2092
- //#endregion
2093
- //#region src/compat/mini-program-css/finalize.ts
2094
- function finalizeMiniProgramCssRoot(root, options = {}) {
2095
- const shouldInjectTailwindcssV4Defaults = options.isTailwindcssV4 === true;
2096
- const tailwindcssV4DefaultNodes = shouldInjectTailwindcssV4Defaults ? createMissingCssVarsV4Nodes(root, collectUsedTailwindcssV4Variables(root)) : [];
2097
- removeUnsupportedCascadeLayers(root);
2098
- unwrapTailwindSourceMedia(root);
2099
- removeTailwindGenerationDirectives(root);
2100
- root.walkAtRules("property", (atRule) => {
2101
- atRule.remove();
2102
- });
2103
- root.walkAtRules("supports", (atRule) => {
2104
- atRule.remove();
2105
- });
2106
- removeSpecificityPlaceholders(root);
2107
- removeRootSpecificityPlaceholders(root);
2108
- removeUnsupportedBrowserSelectors(root);
2109
- removeDisplayP3Declarations(root);
2110
- removeEmptyStandardDeclarations(root);
2111
- removeTailwindContainerMaxWidthMediaRules(root);
2112
- removeTailwindContainerWidthRules(root, { generatedOnly: true });
2113
- removeUnsupportedModernColorDeclarations(root);
2114
- root.walkDecls((decl) => {
2115
- if (shouldInjectTailwindcssV4Defaults) normalizeTailwindcssV4Declaration(decl);
2116
- normalizeMiniProgramPrefixedDeclaration(decl);
2117
- });
2118
- root.walkAtRules((atRule) => {
2119
- removeUnsupportedMiniProgramPrefixedAtRule(atRule);
2120
- });
2121
- if (shouldInjectTailwindcssV4Defaults) {
2122
- mergeTailwindcssV4GradientDirectionRules(root);
2123
- if (options.tailwindcssV4GradientFallback === true) appendTailwindcssV4MiniProgramGradientRules(root);
2124
- }
2125
- const hoistAnchor = createHoistInsertionAnchor(root);
2126
- const preflightRules = collectPreflightRules(root, options);
2127
- if (preflightRules.length === 0) {
2128
- const resetRule = createPreflightResetRule(options.cssPreflight);
2129
- if (resetRule) preflightRules.push(resetRule);
2130
- }
2131
- if (tailwindcssV4DefaultNodes.length > 0) preflightRules.push(postcss.rule({
2132
- selector: MINI_PROGRAM_ELEMENT_SCOPE_SELECTOR,
2133
- nodes: tailwindcssV4DefaultNodes
2134
- }));
2135
- const themeRule = collectThemeVariableRule(root, options);
2136
- insertHoistedRules(root, mergeEquivalentHoistedRules(themeRule ? [...preflightRules, themeRule] : preflightRules), hoistAnchor);
2137
- if (options.removeEmptyAtRuleAncestors !== false) {
2138
- removeEmptyRules(root);
2139
- removeEmptyAtRules$1(root);
2140
- } else root.walkAtRules((atRule) => {
2141
- if (atRule.nodes?.length === 0) atRule.remove();
2142
- });
2143
- }
2144
- function hoistTailwindPreflightBase(css) {
2145
- try {
2146
- const root = postcss.parse(css);
2147
- insertHoistedRules(root, collectPreflightRules(root));
2148
- return root.toString();
2149
- } catch {
2150
- return css;
2151
- }
2152
- }
2153
- function finalizeMiniProgramCss(css, options = {}) {
2154
- const repairedCss = repairTrailingUnclosedTailwindSourceMedia(css);
2155
- let isTailwindcssV4 = options.isTailwindcssV4;
2156
- if (isTailwindcssV4 === void 0) try {
2157
- isTailwindcssV4 = hasTailwindcssV4Signal(repairedCss);
2158
- } catch {
2159
- isTailwindcssV4 = TAILWIND_V4_BANNER_RE.test(repairedCss);
2160
- }
2161
- const cleanedCss = removeUnsupportedMiniProgramAtRules(repairedCss);
2162
- try {
2163
- const root = postcss.parse(cleanedCss);
2164
- finalizeMiniProgramCssRoot(root, {
2165
- ...options,
2166
- isTailwindcssV4
2167
- });
2168
- return root.toString();
2169
- } catch {
2170
- return removeSpecificityPlaceholdersFromSource(cleanedCss);
2171
- }
2172
- }
2173
- //#endregion
2174
- //#region src/compat/web-css.ts
2175
- const disabledFeatures = {
2176
- theme: false,
2177
- layer: false,
2178
- property: false,
2179
- nesting: false,
2180
- oklch: false,
2181
- colorFunctions: false,
2182
- supports: false
2183
- };
2184
- const legacyWebFeatures = {
2185
- theme: true,
2186
- layer: true,
2187
- property: true,
2188
- nesting: true,
2189
- oklch: true,
2190
- colorFunctions: true,
2191
- supports: true
2192
- };
2193
- function normalizeWebCssCompatOptionsObject(options) {
2194
- const preset = options.preset ?? "legacy-web";
2195
- return {
2196
- preset,
2197
- features: {
2198
- ...preset === "legacy-web" ? legacyWebFeatures : disabledFeatures,
2199
- ...options.features
2200
- }
2201
- };
2202
- }
2203
- function normalizeWebCssCompatOptions(options) {
2204
- if (options === true) return normalizeWebCssCompatOptionsObject({ preset: "legacy-web" });
2205
- if (!options) return {
2206
- preset: "off",
2207
- features: disabledFeatures
2208
- };
2209
- return normalizeWebCssCompatOptionsObject(options);
2210
- }
2211
- function isWebCssCompatEnabled(options) {
2212
- return Object.values(options.features).some(Boolean);
2213
- }
2214
- function collectCustomPropertyValues(root) {
2215
- const values = /* @__PURE__ */ new Map();
2216
- root.walkRules((rule) => {
2217
- if (!rule.selectors.some((selector) => selector.trim() === ":root" || selector.trim() === ":host")) return;
2218
- rule.each((node) => {
2219
- if (node.type === "decl" && node.prop.startsWith("--") && !node.prop.startsWith("--tw-")) {
2220
- const decl = node;
2221
- values.set(decl.prop, decl.value.trim());
2222
- }
2223
- });
2224
- });
2225
- return values;
2226
- }
2227
- function collectRegisteredCustomPropertyFallbacks(root) {
2228
- const registeredProperties = /* @__PURE__ */ new Map();
2229
- root.walkAtRules("property", (atRule) => {
2230
- const propertyName = atRule.params.trim().split(/\s+/, 1)[0];
2231
- if (propertyName?.startsWith("--")) {
2232
- const existing = registeredProperties.get(propertyName) ?? {};
2233
- atRule.walkDecls("initial-value", (decl) => {
2234
- existing.initialValue = decl.value.trim();
2235
- });
2236
- registeredProperties.set(propertyName, existing);
2237
- }
2238
- atRule.remove();
2239
- });
2240
- return registeredProperties;
2241
- }
2242
- const tailwindUnregisteredInitialFallbackCustomProperties = /* @__PURE__ */ new Set([
2243
- "--tw-gradient-position",
2244
- "--tw-gradient-stops",
2245
- "--tw-gradient-via-stops",
2246
- "--tw-leading",
2247
- "--tw-font-weight",
2248
- "--tw-tracking"
2249
- ]);
2250
- function insertRegisteredCustomPropertyFallbackRule(root, registeredProperties) {
2251
- const declarations = [];
2252
- for (const [prop, registration] of registeredProperties) {
2253
- if (!registration.initialValue || registration.initialValue === "initial") continue;
2254
- declarations.push(postcss.decl({
2255
- prop,
2256
- value: registration.initialValue
2257
- }));
2258
- }
2259
- if (declarations.length === 0) return;
2260
- root.prepend(postcss.rule({
2261
- selector: "*, ::before, ::after, ::backdrop",
2262
- nodes: declarations
2263
- }));
2264
- }
2265
- function removeInitialFallbackDeclarations(root, registeredProperties) {
2266
- root.walkDecls((decl) => {
2267
- if ((registeredProperties.has(decl.prop) && !registeredProperties.get(decl.prop)?.initialValue || tailwindUnregisteredInitialFallbackCustomProperties.has(decl.prop)) && decl.value.trim() === "initial") decl.remove();
2268
- });
2269
- }
2270
- function unwrapThemeAtRules(root) {
2271
- root.walkAtRules("theme", (atRule) => {
2272
- if (atRule.nodes && atRule.nodes.length > 0) {
2273
- const rootNodes = [];
2274
- const hoistedNodes = [];
2275
- for (const node of atRule.nodes) if (node.type === "decl" || node.type === "comment") rootNodes.push(node.clone());
2276
- else hoistedNodes.push(node.clone());
2277
- const replacements = [...rootNodes.length > 0 ? [postcss.rule({
2278
- selector: ":root",
2279
- nodes: rootNodes
2280
- })] : [], ...hoistedNodes];
2281
- atRule.replaceWith(...replacements);
2282
- } else atRule.remove();
2283
- });
2284
- }
2285
- function resolveCustomPropertyVarValue(value, customPropertyValues) {
2286
- if (!value.includes("var(")) return value;
2287
- const parsed = valueParser(value);
2288
- let changed = false;
2289
- parsed.walk((node) => {
2290
- if (node.type !== "function" || node.value.toLowerCase() !== "var") return;
2291
- const propertyNode = node.nodes.find((child) => child.type === "word" && child.value.startsWith("--"));
2292
- if (!propertyNode) return;
2293
- const customPropertyValue = customPropertyValues.get(propertyNode.value);
2294
- if (!customPropertyValue) return;
2295
- const mutableNode = node;
2296
- mutableNode.type = "word";
2297
- mutableNode.value = customPropertyValue;
2298
- delete mutableNode.nodes;
2299
- changed = true;
2300
- });
2301
- return changed ? parsed.toString() : value;
2302
- }
2303
- function usesResolvableTailwindColorVariable(value, customPropertyValues) {
2304
- if (!value.includes("var(")) return false;
2305
- const parsed = valueParser(value);
2306
- let usesColorVariable = false;
2307
- parsed.walk((node) => {
2308
- if (node.type !== "function" || node.value.toLowerCase() !== "var") return;
2309
- const propertyNode = node.nodes.find((child) => child.type === "word" && child.value.startsWith("--color-"));
2310
- if (propertyNode && customPropertyValues.has(propertyNode.value)) usesColorVariable = true;
2311
- });
2312
- return usesColorVariable;
2313
- }
2314
- function normalizeModernColorDeclarations(root, features) {
2315
- if (!features.oklch && !features.colorFunctions) return;
2316
- const customPropertyValues = collectCustomPropertyValues(root);
2317
- root.walkDecls((decl) => {
2318
- const value = resolveCustomPropertyVarValue(decl.value, customPropertyValues);
2319
- const normalized = normalizeModernColorValue(value, customPropertyValues);
2320
- if (!normalized.changed) {
2321
- if (value !== decl.value && usesResolvableTailwindColorVariable(decl.value, customPropertyValues)) decl.value = value;
2322
- return;
2323
- }
2324
- if (!features.colorFunctions && !/oklch|oklab/i.test(value)) return;
2325
- decl.value = normalized.value;
2326
- });
2327
- }
2328
- function removeModernColorSupports(root) {
2329
- root.walkAtRules("supports", (atRule) => {
2330
- if (!/color-mix|oklch|oklab|lab|lch|display-p3/i.test(atRule.params)) return;
2331
- if (atRule.nodes && atRule.nodes.length > 0) atRule.replaceWith(...atRule.nodes);
2332
- else atRule.remove();
2333
- });
2334
- }
2335
- function normalizeTailwindcssV4GradientPositionDeclarations(root) {
2336
- root.walkDecls("--tw-gradient-position", (decl) => {
2337
- const normalized = normalizeTailwindcssV4GradientPosition(decl.value);
2338
- if (normalized) {
2339
- decl.value = normalized;
2340
- return;
2341
- }
2342
- if (normalized === decl.value.trim()) return;
2343
- const parent = decl.parent;
2344
- if (parent?.type !== "rule") {
2345
- decl.value = "to bottom";
2346
- return;
2347
- }
2348
- const backgroundImageDecl = parent.nodes.find((node) => {
2349
- return node.type === "decl" && node.prop === "background-image";
2350
- });
2351
- if (/^radial-gradient\(/i.test(backgroundImageDecl?.value ?? "")) {
2352
- decl.value = "at center";
2353
- return;
2354
- }
2355
- if (/^conic-gradient\(/i.test(backgroundImageDecl?.value ?? "")) {
2356
- decl.value = "from 0deg";
2357
- return;
2358
- }
2359
- decl.value = "to bottom";
2360
- });
2361
- }
2362
- function normalizeTailwindcssV4InfinityCalcDeclarations(root) {
2363
- root.walkDecls((decl) => {
2364
- const normalized = normalizeTailwindcssV4InfinityCalcValue(decl.value);
2365
- if (normalized !== decl.value) decl.value = normalized;
2366
- });
2367
- }
2368
- function removeEmptyAtRules(root) {
2369
- root.walkAtRules((atRule) => {
2370
- if (atRule.nodes && atRule.nodes.length === 0) atRule.remove();
2371
- });
2372
- }
2373
- function insertWebkitBackgroundClipText(root) {
2374
- root.walkDecls("background-clip", (decl) => {
2375
- if (decl.value.trim().toLowerCase() !== "text") return;
2376
- const parent = decl.parent;
2377
- if (!parent || !("nodes" in parent)) return;
2378
- if (!parent.nodes.some((node) => {
2379
- return node.type === "decl" && node.prop.toLowerCase() === "-webkit-background-clip" && node.value.trim().toLowerCase() === "text";
2380
- })) decl.cloneBefore({ prop: "-webkit-background-clip" });
2381
- });
2382
- }
2383
- function transformCssNesting(root) {
2384
- postcss([postcssPresetEnv({
2385
- stage: false,
2386
- autoprefixer: false,
2387
- features: { "nesting-rules": true }
2388
- })]).process(root, { from: void 0 }).sync();
2389
- }
2390
- function transformWebCssCompat(css, options) {
2391
- const normalized = normalizeWebCssCompatOptions(options);
2392
- if (!isWebCssCompatEnabled(normalized) && normalized.preset !== "legacy-web") return css;
2393
- try {
2394
- const root = postcss.parse(css);
2395
- if (normalized.features.theme) unwrapThemeAtRules(root);
2396
- if (normalized.features.property) {
2397
- const registeredProperties = collectRegisteredCustomPropertyFallbacks(root);
2398
- insertRegisteredCustomPropertyFallbackRule(root, registeredProperties);
2399
- removeInitialFallbackDeclarations(root, registeredProperties);
2400
- }
2401
- if (normalized.features.supports) removeModernColorSupports(root);
2402
- if (normalized.features.nesting) transformCssNesting(root);
2403
- normalizeTailwindcssV4GradientPositionDeclarations(root);
2404
- normalizeTailwindcssV4InfinityCalcDeclarations(root);
2405
- normalizeModernColorDeclarations(root, normalized.features);
2406
- if (normalized.preset === "legacy-web") insertWebkitBackgroundClipText(root);
2407
- if (normalized.features.layer) removeUnsupportedCascadeLayers(root);
2408
- removeEmptyAtRules(root);
2409
- return root.toString();
2410
- } catch {
2411
- return css;
2412
- }
2413
- }
2414
- function transformWebCssSafeSelectors(css, options) {
2415
- try {
2416
- const root = postcss.parse(css);
2417
- root.walkRules((rule) => {
2418
- if (!rule.selector.includes(".")) return;
2419
- rule.selector = selectorParser((selectors) => {
2420
- selectors.walkClasses((node) => {
2421
- node.value = internalCssSelectorReplacer(node.value, options);
2422
- });
2423
- }).processSync(rule.selector);
2424
- });
2425
- return root.toString();
2426
- } catch {
2427
- return css;
2428
- }
2429
- }
2430
- //#endregion
2431
- //#region src/utils/apply-source.ts
2432
- function normalizeGeneratedSelector(selector) {
2433
- return selector.replace(/:not\(#\\#\)/g, "").trim();
2434
- }
2435
- /** 复用调用方 AST,同时取得 apply 选择器和纯 apply 输入判定。 */
2436
- function analyzeApplyOnlySourceRoot(root) {
2437
- const selectors = /* @__PURE__ */ new Set();
2438
- let hasApplyRule = false;
2439
- let hasNonApplyRule = false;
2440
- root.walkRules((rule) => {
2441
- if (!rule.nodes?.some((node) => node.type === "atrule" && node.name === "apply")) {
2442
- hasNonApplyRule = true;
2443
- return;
2444
- }
2445
- hasApplyRule = true;
2446
- for (const selector of rule.selectors ?? [rule.selector]) {
2447
- const normalized = normalizeGeneratedSelector(selector);
2448
- if (normalized) selectors.add(normalized);
2449
- }
2450
- });
2451
- return {
2452
- selectors,
2453
- onlyApply: hasApplyRule && !hasNonApplyRule
2454
- };
2455
- }
2456
- function analyzeApplyOnlySource(source) {
2457
- try {
2458
- return analyzeApplyOnlySourceRoot(postcss$1.parse(source));
2459
- } catch {
2460
- return {
2461
- selectors: /* @__PURE__ */ new Set(),
2462
- onlyApply: false
2463
- };
2464
- }
2465
- }
2466
- //#endregion
2467
- //#region src/generator-plugin/apply-only.ts
2468
- function collectApplyOnlyCssSelectorsRoot(root) {
2469
- return analyzeApplyOnlySourceRoot(root).selectors;
2470
- }
2471
- function collectApplyOnlyCssSelectors(css) {
2472
- try {
2473
- return collectApplyOnlyCssSelectorsRoot(postcss$1.parse(css));
2474
- } catch {
2475
- return /* @__PURE__ */ new Set();
2476
- }
2477
- }
2478
- function ruleMatchesApplyOnlySelector(rule, selectors) {
2479
- return (rule.selectors ?? [rule.selector]).some((selector) => selectors.has(normalizeGeneratedSelector(selector)));
2480
- }
2481
- function filterApplyOnlyGeneratedCssRoot(root, selectors) {
2482
- if (selectors.size === 0) return false;
2483
- let changed = false;
2484
- root.walkRules((rule) => {
2485
- if (ruleMatchesApplyOnlySelector(rule, selectors) || rule.nodes?.some((node) => node.type === "decl" && node.prop.startsWith("--"))) return;
2486
- rule.remove();
2487
- changed = true;
2488
- });
2489
- root.walkAtRules((rule) => {
2490
- if (rule.nodes !== void 0 && rule.nodes.length === 0) {
2491
- rule.remove();
2492
- changed = true;
2493
- }
2494
- });
2495
- return changed;
2496
- }
2497
- function filterApplyOnlyGeneratedCss(css, selectors) {
2498
- if (selectors.size === 0) return css;
2499
- try {
2500
- const root = postcss$1.parse(css);
2501
- return filterApplyOnlyGeneratedCssRoot(root, selectors) ? root.toString() : css;
2502
- } catch {
2503
- return css;
2504
- }
2505
- }
2506
- //#endregion
2507
- //#region src/generator-plugin/config-directive.ts
2508
- function normalizeConfigDirective(css, config) {
2509
- if (!config || !/@config\s+/.test(css)) return css;
2510
- return css.replace(/@config\s+(["'])(.+?)\1\s*;?/, `@config "${quoteCssString(toCssPath(config))}";`);
2511
- }
2512
- /** 保留预处理器文本兼容;请求解析与文件定位由调用方提供。 */
2513
- function rewriteCssConfigRequests(source, resolve) {
2514
- return source.replace(/@config\s+(["'])(.+?)\1\s*;?/g, (full, quote, request) => {
2515
- const resolved = resolve(request);
2516
- return resolved === void 0 ? full : `@config ${quote}${resolved}${quote};`;
2517
- });
2518
- }
2519
- /** 保留 Vite 预处理前的行级清理语义,允许尚未编译的 Sass 等源码。 */
2520
- function stripTailwindConfigDirectives(code) {
2521
- return code.replace(/^\s*@config\s+(?:"[^"]+"|'[^']+')[^;\n]*;\s*$/gm, "");
2522
- }
2523
- function quoteCssString(value) {
2524
- return value.replaceAll("\\", "\\\\").replaceAll("\"", "\\\"");
2525
- }
2526
- function toCssPath(value) {
2527
- return value.replaceAll("\\", "/");
2528
- }
2529
- function prependConfigDirective(css, config) {
2530
- if (!config || /@config\s+/.test(css)) return css;
2531
- return `@config "${quoteCssString(toCssPath(config))}";\n${css}`;
2532
- }
2533
- //#endregion
2534
- //#region src/generator-plugin/directives.ts
2535
- const TAILWIND_ROOT_DIRECTIVE_NAMES = /* @__PURE__ */ new Set([
2536
- "config",
2537
- "custom-variant",
2538
- "plugin",
2539
- "source",
2540
- "tailwind",
2541
- "theme",
2542
- "utility",
2543
- "variant"
2544
- ]);
2545
- function createEmptyDirectiveAnalysis() {
2546
- return {
2547
- hasLocalCssImport: false,
2548
- hasTailwindApplyDirective: false,
2549
- hasTailwindNonRootGenerationDirectives: false,
2550
- hasTailwindRootDirectives: false,
2551
- hasTailwindRootImportDirectives: false,
2552
- hasTailwindSourceDirectives: false
2553
- };
2554
- }
2555
- function parseTailwindCssDirectiveRequest(params) {
2556
- return parseCssImportSpecifier(params)?.specifier;
2557
- }
2558
- function parseTailwindCssConfigRequest(params) {
2559
- return /^(["'])(.+)\1\s*;?$/.exec(params.trim())?.[2];
2560
- }
2561
- function isTailwindCssPackageJsonImportRequest(request) {
2562
- return typeof request === "string" && request.startsWith("#");
2563
- }
2564
- function isWeappTailwindcssImportRequest(request) {
2565
- return request === "weapp-tailwindcss" || request?.startsWith("weapp-tailwindcss/") === true;
2566
- }
2567
- function normalizeTailwindCssImportRequest(request, options = {}) {
2568
- return options.importFallback && (request === "weapp-tailwindcss" || request?.startsWith("weapp-tailwindcss/")) ? request.replace(/^weapp-tailwindcss/, "tailwindcss") : request;
2569
- }
2570
- function isTailwindCssImportRequest(request, options = {}) {
2571
- const normalized = normalizeTailwindCssImportRequest(request, options);
2572
- return normalized === "tailwindcss" || normalized === "tailwindcss4" || normalized?.startsWith("tailwindcss/") === true || normalized?.startsWith("tailwindcss4/") === true;
2573
- }
2574
- function isTailwindCssImportAtRule(node, options = {}) {
2575
- if (node.name === "tailwind") return true;
2576
- if (node.name !== "import" && node.name !== "use" && node.name !== "forward") return false;
2577
- return isTailwindCssImportRequest(parseTailwindCssDirectiveRequest(node.params), options);
2578
- }
2579
- function getTailwindCssDirectiveRequest(node) {
2580
- return node.name === "import" ? parseTailwindCssDirectiveRequest(node.params) : node.name === "config" || node.name === "plugin" || node.name === "reference" ? parseTailwindCssConfigRequest(node.params) : void 0;
2581
- }
2582
- function isTailwindCssGenerationDirective(node, options = {}) {
2583
- if (node.type !== "atrule") return false;
2584
- const atRule = node;
2585
- const request = getTailwindCssDirectiveRequest(atRule);
2586
- return isTailwindCssImportAtRule(atRule, options) || isTailwindCssPackageJsonImportRequest(request) || atRule.name === "apply" || !options.ignoreLayer && atRule.name === "layer" || atRule.name === "config" || atRule.name === "source";
2587
- }
2588
- function hasTailwindApplyDirective(css) {
2589
- return /@apply\b/.test(css);
2590
- }
2591
- function analyzeTailwindCssDirectives(root, options = {}) {
2592
- const analysis = createEmptyDirectiveAnalysis();
2593
- root.walk((node) => {
2594
- if (node.type !== "atrule") return;
2595
- const atRule = node;
2596
- if (atRule.name === "import") {
2597
- const request = parseTailwindCssDirectiveRequest(atRule.params);
2598
- if (request?.startsWith(".") === true || request?.startsWith("/") === true) analysis.hasLocalCssImport = true;
2599
- }
2600
- const isTailwindImport = isTailwindCssImportAtRule(atRule, options);
2601
- if (isTailwindImport) {
2602
- analysis.hasTailwindRootImportDirectives = true;
2603
- analysis.hasTailwindRootDirectives = true;
2604
- }
2605
- const request = atRule.name === "import" || atRule.name === "config" || atRule.name === "plugin" ? getTailwindCssDirectiveRequest(atRule) : void 0;
2606
- if (isTailwindImport || isTailwindCssPackageJsonImportRequest(request) || TAILWIND_ROOT_DIRECTIVE_NAMES.has(atRule.name)) analysis.hasTailwindRootDirectives = true;
2607
- if (atRule.name === "apply") analysis.hasTailwindApplyDirective = true;
2608
- if (isTailwindCssGenerationDirective(atRule, options)) {
2609
- analysis.hasTailwindSourceDirectives = true;
2610
- if (!isTailwindImport) analysis.hasTailwindNonRootGenerationDirectives = true;
2611
- }
2612
- });
2613
- return analysis;
2614
- }
2615
- function hasTailwindRootDirectives(root, options = {}) {
2616
- let found = false;
2617
- root.walkAtRules((rule) => {
2618
- if (rule.name === "import" && isTailwindCssImportRequest(parseTailwindCssDirectiveRequest(rule.params), options)) {
2619
- found = true;
2620
- return false;
2621
- }
2622
- if (TAILWIND_ROOT_DIRECTIVE_NAMES.has(rule.name)) {
2623
- found = true;
2624
- return false;
2625
- }
2626
- });
2627
- return found;
2628
- }
2629
- //#endregion
2630
- export { CLAMP_PX, COLOR_GAMUT_P3_RE$1 as COLOR_GAMUT_P3_RE, DISPLAY_P3_COLOR_RE, DISPLAY_P3_VALUE_RE$1 as DISPLAY_P3_VALUE_RE, INFINITY_CALC_VALUE_REGEXP, LINEAR_GRADIENT_LAB_RE, MINI_PROGRAM_ELEMENT_SCOPE_SELECTOR, MINI_PROGRAM_ELEMENT_SCOPE_SELECTORS, MODERN_CHECK_COLOR_RGB_RE, MODERN_CHECK_MARGIN_TRIM_RE, MODERN_CHECK_MOZ_ORIENT_RE, MODERN_CHECK_WEBKIT_HYPHENS_RE, analyzeApplyOnlySource, analyzeTailwindCssDirectives, appendTailwindcssV4MiniProgramGradientRules, collectApplyOnlyCssSelectors, collectApplyOnlyCssSelectorsRoot, collectUsedTailwindcssV4Variables, consumeCascadeLayers, createMissingCssVarsV4Nodes, createUsedCssVarsV4Nodes, filterApplyOnlyGeneratedCss, filterApplyOnlyGeneratedCssRoot, finalizeMiniProgramCss, finalizeMiniProgramCssRoot, getRuleSelectors, hasMiniProgramCssSpecificityPlaceholders, hasTailwindApplyDirective, hasTailwindRootDirectives, hoistTailwindPreflightBase, isBrowserElementPreflightRule, isCustomPropertyRule, isEmptyTwContentDeclaration, isMiniProgramNativeElementSelector, isMiniProgramPreflightRule, isMiniProgramThemeScopeSelector, isMiniProgramThemeVariableRule, isPseudoContentInitRule, isTailwindCssGenerationDirective, isTailwindCssImportAtRule, isTailwindCssImportRequest, isTailwindCssPackageJsonImportRequest, isTailwindcssV4, isTailwindcssV4ThemeVariable, isUnsupportedBrowserPreflightSelector, isWeappTailwindcssImportRequest, mergeTailwindcssV4GradientDirectionRules, normalizeConfigDirective, normalizeGeneratedSelector, normalizeMiniProgramPrefixedDeclaration, normalizeModernColorValue, normalizeTailwindCssImportRequest, normalizeTailwindcssV4Declaration, normalizeTailwindcssV4InfinityCalcCss, normalizeWebCssCompatOptions, parseTailwindCssConfigRequest, parseTailwindCssDirectiveRequest, prependConfigDirective, protectDynamicColorMixAlpha, protectDynamicVarFallbacks, removeEmptyAtRules$1 as removeEmptyAtRules, removeEmptyBlockAtRules, removeEmptyRules, removeEmptyStandardDeclarations, removeSpecificityPlaceholders, removeTailwindContainerMaxWidthMediaRules, removeTailwindContainerWidthRules, removeUnsupportedAtSupports, removeUnsupportedCascadeLayers, removeUnsupportedMiniProgramAtRules, removeUnsupportedMiniProgramPrefixedAtRule, removeUnsupportedModernColorDeclarations, repairTrailingUnclosedTailwindSourceMedia, rewriteCssConfigRequests, stripMiniProgramCssSpecificityPlaceholders, stripTailwindConfigDirectives, testIfRootHostForV4, transformLynxCssCompat, transformWebCssCompat, transformWebCssSafeSelectors, unwrapUnsupportedCascadeLayers, usesTailwindcssV4ContentVariable, usesTwContentVariable };