@weapp-tailwindcss/postcss 3.3.5 → 3.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/README.zh-CN.md +6 -0
- package/dist/compat/index.d.ts +57 -0
- package/dist/compat/legacy-css/source-cleanup.d.ts +2 -0
- package/dist/compat/mini-program-css/output-import-shell.d.ts +8 -0
- package/dist/compat/native/compile.d.ts +2 -0
- package/dist/compat/native/properties.d.ts +15 -0
- package/dist/compat/native/selectors.d.ts +8 -0
- package/dist/compat/native/types.d.ts +23 -0
- package/dist/compat/processed-css/cleanup.d.ts +4 -0
- package/dist/compat/processed-css/composition.d.ts +6 -0
- package/dist/compat/processed-css/entry-directives.d.ts +1 -0
- package/dist/compat/processed-css/imports.d.ts +8 -0
- package/dist/compat/scoped-css/cleanup.d.ts +4 -0
- package/dist/compat/scoped-css/coverage.d.ts +10 -0
- package/dist/compat/scoped-css/covered-rules.d.ts +4 -0
- package/dist/compat/scoped-css/predicates.d.ts +13 -0
- package/dist/compat/tailwind-directive-injection.d.ts +8 -0
- package/dist/compat/tailwindcss-v4/generated-output.d.ts +5 -0
- package/dist/compat/tailwindcss-v4/package-import-statements.d.ts +1 -0
- package/dist/compat/tailwindcss-v4/preflight-imports.d.ts +3 -0
- package/dist/compat/tailwindcss-v4/rpx-candidates.d.ts +6 -0
- package/dist/compat/tailwindcss-v4/theme-injection.d.ts +1 -0
- package/dist/compat/tailwindcss-v4/theme-source.d.ts +5 -0
- package/dist/compat/tailwindcss-v4/user-css/apply-only.d.ts +6 -0
- package/dist/compat/tailwindcss-v4/user-css/apply-reference.d.ts +4 -0
- package/dist/compat/tailwindcss-v4/user-css/at-rules.d.ts +3 -0
- package/dist/compat/tailwindcss-v4/user-css/class-selectors.d.ts +2 -0
- package/dist/compat/tailwindcss-v4/user-css/directives/entry-source.d.ts +9 -0
- package/dist/compat/tailwindcss-v4/user-css/directives/fallback.d.ts +11 -0
- package/dist/compat/tailwindcss-v4/user-css/directives/index.d.ts +2 -0
- package/dist/compat/tailwindcss-v4/user-css/directives/shared.d.ts +26 -0
- package/dist/compat/tailwindcss-v4/user-css/framework-composition.d.ts +2 -0
- package/dist/compat/tailwindcss-v4/user-css/framework-source.d.ts +1 -0
- package/dist/compat/tailwindcss-v4/user-css/generated-cleanup.d.ts +7 -0
- package/dist/compat/tailwindcss-v4/user-css/identity.d.ts +1 -0
- package/dist/compat/tailwindcss-v4/user-css/markers.d.ts +32 -0
- package/dist/compat/tailwindcss-v4/user-css/rule-deduplication.d.ts +1 -0
- package/dist/compat/tailwindcss-v4/user-css/scoped-rules.d.ts +4 -0
- package/dist/compat/tailwindcss-v4/user-css/source-fragments.d.ts +15 -0
- package/dist/compat/tailwindcss-v4/user-css/transform.d.ts +14 -0
- package/dist/compat/tailwindcss-v4/user-css/user-layer-order.d.ts +10 -0
- package/dist/compat/tailwindcss-v4/user-css/user-layers.d.ts +15 -0
- package/dist/compat/uni-app-x/apply-source.d.ts +2 -0
- package/dist/compat/uni-app-x/harmony-apply.d.ts +2 -0
- package/dist/compat/uni-app-x/reference-paths.d.ts +2 -0
- package/dist/compat/uni-app-x-style-value.d.ts +2 -0
- package/dist/compat/webpack-css/bare-selectors.d.ts +1 -0
- package/dist/compat/webpack-css/generated-cleanup.d.ts +4 -0
- package/dist/compat/webpack-css/identity.d.ts +5 -0
- package/dist/compat/webpack-css/preflight.d.ts +5 -0
- package/dist/compat/webpack-css/user-source.d.ts +6 -0
- package/dist/diagnostics/rpx-theme.d.ts +9 -0
- package/dist/directives-DTKFO5Hv.js +2630 -0
- package/dist/experimental/lightningcss/index.cjs +256 -0
- package/dist/experimental/lightningcss/index.d.ts +3 -0
- package/dist/experimental/lightningcss/index.js +245 -0
- package/dist/experimental/lightningcss/options.d.ts +3 -0
- package/dist/experimental/lightningcss/selector-transform.d.ts +10 -0
- package/dist/experimental/lightningcss/selector-utils.d.ts +10 -0
- package/dist/generator-plugin/config-directive.d.ts +5 -0
- package/dist/generator-plugin/source-files.d.ts +5 -5
- package/dist/generator-plugin/types.d.ts +5 -0
- package/dist/index.cjs +383 -9089
- package/dist/index.d.ts +2 -43
- package/dist/index.js +10 -8935
- package/dist/native.cjs +425 -0
- package/dist/native.d.ts +3 -0
- package/dist/native.js +419 -0
- package/dist/plugin-BWDgxMn5.cjs +194 -0
- package/dist/plugin-CpkRzMhp.js +185 -0
- package/dist/plugin.cjs +3 -0
- package/dist/plugin.d.ts +2 -0
- package/dist/plugin.js +2 -0
- package/dist/postcss-runtime-i5rHe_mj.js +2 -0
- package/dist/preflight-BTZL2nvC.cjs +21 -0
- package/dist/preflight-DVg4eehD.js +16 -0
- package/dist/resolve-DQiOQfoY.js +354 -0
- package/dist/resolve-EBh65bS8.cjs +3556 -0
- package/dist/rewrite-imports-CdZQE6CI.js +146 -0
- package/dist/shared-CELzerNo.cjs +34 -0
- package/dist/shared-CfQUwapA.js +23 -0
- package/dist/source-scan/candidates.d.ts +4 -0
- package/dist/source-scan/description.d.ts +15 -0
- package/dist/source-scan/params.d.ts +5 -0
- package/dist/source-scan/resolve.d.ts +30 -0
- package/dist/source-scan/tailwind-v4/entry-source.d.ts +16 -0
- package/dist/source-scan/tailwind-v4/fingerprint.d.ts +5 -0
- package/dist/source-scan.d.ts +3 -24
- package/dist/syntax/index.d.ts +1 -0
- package/dist/syntax/location-dependencies.d.ts +2 -0
- package/dist/syntax/rewrite-imports.d.ts +5 -0
- package/dist/syntax/runtime-signature.d.ts +2 -0
- package/dist/syntax/source-style.d.ts +1 -0
- package/dist/syntax.cjs +547 -0
- package/dist/syntax.d.ts +6 -0
- package/dist/syntax.js +3 -0
- package/dist/transform-Djx5HILQ.js +9239 -0
- package/dist/transform-Xb48e-Wk.cjs +10957 -0
- package/dist/transform.cjs +421 -0
- package/dist/transform.d.ts +40 -0
- package/dist/transform.js +10 -0
- package/dist/utils/apply-source.d.ts +11 -0
- package/dist/utils/css-source-trace.d.ts +6 -0
- package/dist/utils/custom-property-values.d.ts +4 -0
- package/dist/utils/generated-css-marker.d.ts +12 -0
- package/package.json +45 -5
package/dist/syntax.cjs
ADDED
|
@@ -0,0 +1,547 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
13
|
+
get: ((k) => from[k]).bind(null, key),
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
20
|
+
value: mod,
|
|
21
|
+
enumerable: true
|
|
22
|
+
}) : target, mod));
|
|
23
|
+
//#endregion
|
|
24
|
+
let _weapp_tailwindcss_engine = require("@weapp-tailwindcss/engine");
|
|
25
|
+
let _weapp_tailwindcss_source_scan = require("@weapp-tailwindcss/source-scan");
|
|
26
|
+
let node_path = require("node:path");
|
|
27
|
+
node_path = __toESM(node_path, 1);
|
|
28
|
+
let _csstools_css_tokenizer = require("@csstools/css-tokenizer");
|
|
29
|
+
let node_module = require("node:module");
|
|
30
|
+
let tailwindcss_config = require("tailwindcss-config");
|
|
31
|
+
let postcss = require("postcss");
|
|
32
|
+
postcss = __toESM(postcss, 1);
|
|
33
|
+
let postcss_scss = require("postcss-scss");
|
|
34
|
+
postcss_scss = __toESM(postcss_scss, 1);
|
|
35
|
+
//#region src/source-scan/params.ts
|
|
36
|
+
function parseConfigParam(params) {
|
|
37
|
+
const value = params.trim();
|
|
38
|
+
return /^(['"])(.+)\1$/.exec(value)?.[2];
|
|
39
|
+
}
|
|
40
|
+
function parseSourceFileParam(params) {
|
|
41
|
+
const value = params.trim();
|
|
42
|
+
if (!value || value === "none" || value.startsWith("inline(")) return;
|
|
43
|
+
const negated = value.startsWith("not ");
|
|
44
|
+
const sourceValue = negated ? value.slice(4).trim() : value;
|
|
45
|
+
if (sourceValue.startsWith("inline(")) return;
|
|
46
|
+
const match = /^(['"])(.+)\1$/.exec(sourceValue);
|
|
47
|
+
return match?.[2] ? {
|
|
48
|
+
negated,
|
|
49
|
+
sourcePath: match[2]
|
|
50
|
+
} : void 0;
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
53
|
+
//#region src/source-scan/inline-source.ts
|
|
54
|
+
const NUMERICAL_RANGE_RE = /^(-?\d+)\.\.(-?\d+)(?:\.\.(-?\d+))?$/;
|
|
55
|
+
function segmentTopLevel(input, separator, options = {}) {
|
|
56
|
+
const parts = [];
|
|
57
|
+
const stack = [];
|
|
58
|
+
let lastPos = 0;
|
|
59
|
+
let quote;
|
|
60
|
+
for (let index = 0; index < input.length; index++) {
|
|
61
|
+
const char = input[index];
|
|
62
|
+
if (char === "\\") {
|
|
63
|
+
index += 1;
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (quote) {
|
|
67
|
+
if (char === quote) quote = void 0;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (char === "\"" || char === "'") {
|
|
71
|
+
quote = char;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (char === "(") {
|
|
75
|
+
stack.push(")");
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (char === "[") {
|
|
79
|
+
stack.push("]");
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (char === "{") {
|
|
83
|
+
stack.push("}");
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
if (stack.length > 0 && char === stack[stack.length - 1]) {
|
|
87
|
+
stack.pop();
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (stack.length === 0 && char === separator) {
|
|
91
|
+
const part = input.slice(lastPos, index);
|
|
92
|
+
if (part || options.keepEmpty) parts.push(part);
|
|
93
|
+
lastPos = index + 1;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const part = input.slice(lastPos);
|
|
97
|
+
if (part || options.keepEmpty) parts.push(part);
|
|
98
|
+
return parts;
|
|
99
|
+
}
|
|
100
|
+
function isSequence(value) {
|
|
101
|
+
return NUMERICAL_RANGE_RE.test(value);
|
|
102
|
+
}
|
|
103
|
+
function expandSequence(value) {
|
|
104
|
+
const match = value.match(NUMERICAL_RANGE_RE);
|
|
105
|
+
if (!match) return [value];
|
|
106
|
+
const [, start, end, stepValue] = match;
|
|
107
|
+
if (start === void 0 || end === void 0) return [value];
|
|
108
|
+
let step = stepValue ? Number.parseInt(stepValue, 10) : void 0;
|
|
109
|
+
const startNumber = Number.parseInt(start, 10);
|
|
110
|
+
const endNumber = Number.parseInt(end, 10);
|
|
111
|
+
const increasing = startNumber < endNumber;
|
|
112
|
+
if (step === void 0) step = increasing ? 1 : -1;
|
|
113
|
+
if (step === 0) return [];
|
|
114
|
+
if (increasing && step < 0) step = -step;
|
|
115
|
+
if (!increasing && step > 0) step = -step;
|
|
116
|
+
const result = [];
|
|
117
|
+
for (let value = startNumber; increasing ? value <= endNumber : value >= endNumber; value += step) result.push(String(value));
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
function expandInlineSourceCandidatePattern(pattern) {
|
|
121
|
+
const index = pattern.indexOf("{");
|
|
122
|
+
if (index === -1) return [pattern];
|
|
123
|
+
const prefix = pattern.slice(0, index);
|
|
124
|
+
const rest = pattern.slice(index);
|
|
125
|
+
let depth = 0;
|
|
126
|
+
let endIndex = -1;
|
|
127
|
+
for (let index = 0; index < rest.length; index++) {
|
|
128
|
+
const char = rest[index];
|
|
129
|
+
if (char === "{") depth += 1;
|
|
130
|
+
else if (char === "}") {
|
|
131
|
+
depth -= 1;
|
|
132
|
+
if (depth === 0) {
|
|
133
|
+
endIndex = index;
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (endIndex === -1) return [pattern];
|
|
139
|
+
const inner = rest.slice(1, endIndex);
|
|
140
|
+
const suffix = rest.slice(endIndex + 1);
|
|
141
|
+
const parts = (isSequence(inner) ? expandSequence(inner) : segmentTopLevel(inner, ",", { keepEmpty: true })).flatMap((part) => expandInlineSourceCandidatePattern(part));
|
|
142
|
+
return expandInlineSourceCandidatePattern(suffix).flatMap((suffix) => parts.map((part) => `${prefix}${part}${suffix}`));
|
|
143
|
+
}
|
|
144
|
+
function parseSourceInlineParam(params) {
|
|
145
|
+
let value = params.trim();
|
|
146
|
+
const negated = value.startsWith("not ");
|
|
147
|
+
if (negated) value = value.slice(4).trim();
|
|
148
|
+
if (!value.startsWith("inline(") || !value.endsWith(")")) return;
|
|
149
|
+
const inlineValue = value.slice(7, -1).trim();
|
|
150
|
+
const match = /^(['"])([\s\S]*)\1$/.exec(inlineValue);
|
|
151
|
+
if (!match) return;
|
|
152
|
+
const source = match[2];
|
|
153
|
+
if (source === void 0) return;
|
|
154
|
+
return {
|
|
155
|
+
negated,
|
|
156
|
+
source
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function collectCssInlineSourceCandidates(root) {
|
|
160
|
+
const included = /* @__PURE__ */ new Set();
|
|
161
|
+
const excluded = /* @__PURE__ */ new Set();
|
|
162
|
+
root.walkAtRules("source", (rule) => {
|
|
163
|
+
const parsed = parseSourceInlineParam(rule.params);
|
|
164
|
+
if (!parsed) return;
|
|
165
|
+
const target = parsed.negated ? excluded : included;
|
|
166
|
+
for (const source of segmentTopLevel(parsed.source, " ")) {
|
|
167
|
+
const trimmed = source.trim();
|
|
168
|
+
if (!trimmed) continue;
|
|
169
|
+
for (const candidate of expandInlineSourceCandidatePattern(trimmed)) {
|
|
170
|
+
const normalized = candidate.trim();
|
|
171
|
+
if (normalized) target.add(normalized);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
for (const candidate of excluded) included.delete(candidate);
|
|
176
|
+
return {
|
|
177
|
+
included,
|
|
178
|
+
excluded
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
//#endregion
|
|
182
|
+
//#region src/source-scan.ts
|
|
183
|
+
async function resolveCssSourceEntries(root, base, defaultPattern = (0, _weapp_tailwindcss_source_scan.createSourceScanPattern)()) {
|
|
184
|
+
const entries = [];
|
|
185
|
+
const tasks = [];
|
|
186
|
+
root.walkAtRules("source", (rule) => {
|
|
187
|
+
const parsed = parseSourceFileParam(rule.params);
|
|
188
|
+
if (!parsed) return;
|
|
189
|
+
tasks.push((0, _weapp_tailwindcss_source_scan.resolveTailwindSourceEntry)(parsed.sourcePath, base, parsed.negated, defaultPattern));
|
|
190
|
+
});
|
|
191
|
+
entries.push(...await Promise.all(tasks));
|
|
192
|
+
return entries;
|
|
193
|
+
}
|
|
194
|
+
async function expandTailwindSourceEntries(entries, options = {}) {
|
|
195
|
+
return (0, _weapp_tailwindcss_source_scan.expandSourceEntries)(entries, ({ cwd, sources }) => (0, _weapp_tailwindcss_engine.resolveProjectSourceFiles)({
|
|
196
|
+
cwd,
|
|
197
|
+
sources,
|
|
198
|
+
...options.ignore ? { ignoredSources: options.ignore.map((pattern) => ({
|
|
199
|
+
base: cwd,
|
|
200
|
+
pattern: (0, _weapp_tailwindcss_source_scan.normalizeGlobPattern)(pattern),
|
|
201
|
+
negated: true
|
|
202
|
+
})) } : {}
|
|
203
|
+
}));
|
|
204
|
+
}
|
|
205
|
+
//#endregion
|
|
206
|
+
//#region src/syntax/css-import.ts
|
|
207
|
+
function significantTokens(params) {
|
|
208
|
+
return (0, _csstools_css_tokenizer.tokenize)({ css: params }).filter((token) => token[0] !== _csstools_css_tokenizer.TokenType.Whitespace && token[0] !== _csstools_css_tokenizer.TokenType.Comment);
|
|
209
|
+
}
|
|
210
|
+
function isCssWhitespace(char) {
|
|
211
|
+
return char === " " || char === " " || char === "\n" || char === "\r" || char === "\f";
|
|
212
|
+
}
|
|
213
|
+
function skipCssWhitespace(params, index) {
|
|
214
|
+
while (index < params.length && isCssWhitespace(params[index])) index++;
|
|
215
|
+
return index;
|
|
216
|
+
}
|
|
217
|
+
function parseSimpleQuotedSpecifier(params, start) {
|
|
218
|
+
const quote = params[start];
|
|
219
|
+
if (quote !== "\"" && quote !== "'") return;
|
|
220
|
+
let index = start + 1;
|
|
221
|
+
while (index < params.length) {
|
|
222
|
+
const char = params[index];
|
|
223
|
+
if (char === "\\" || char === "\n" || char === "\r") return;
|
|
224
|
+
if (char === quote) return {
|
|
225
|
+
specifier: params.slice(start + 1, index),
|
|
226
|
+
raw: params.slice(start, index + 1),
|
|
227
|
+
quote
|
|
228
|
+
};
|
|
229
|
+
index++;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
function parseSimpleImportSpecifier(params) {
|
|
233
|
+
let index = skipCssWhitespace(params, 0);
|
|
234
|
+
const quoted = parseSimpleQuotedSpecifier(params, index);
|
|
235
|
+
if (quoted) return quoted;
|
|
236
|
+
if (params.slice(index, index + 4).toLowerCase() !== "url(") return;
|
|
237
|
+
const urlStart = index;
|
|
238
|
+
index = skipCssWhitespace(params, index + 4);
|
|
239
|
+
const inner = parseSimpleQuotedSpecifier(params, index);
|
|
240
|
+
if (!inner) return;
|
|
241
|
+
index = skipCssWhitespace(params, index + inner.raw.length);
|
|
242
|
+
if (params[index] !== ")") return;
|
|
243
|
+
return {
|
|
244
|
+
specifier: inner.specifier,
|
|
245
|
+
raw: params.slice(urlStart, index + 1),
|
|
246
|
+
quote: inner.quote
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* 解析 `@import` / `@use` / `@forward` 参数中的请求串。
|
|
251
|
+
* 无 escape/注释的引号和 `url("...")` 走快路径;复杂输入才使用 CSS tokenizer。
|
|
252
|
+
*/
|
|
253
|
+
function parseCssImportSpecifier(params) {
|
|
254
|
+
const simple = parseSimpleImportSpecifier(params);
|
|
255
|
+
if (simple) return simple;
|
|
256
|
+
const tokens = significantTokens(params);
|
|
257
|
+
const first = tokens[0];
|
|
258
|
+
if (!first || first[0] === _csstools_css_tokenizer.TokenType.EOF) return;
|
|
259
|
+
if (first[0] === _csstools_css_tokenizer.TokenType.String || first[0] === _csstools_css_tokenizer.TokenType.URL || first[0] === _csstools_css_tokenizer.TokenType.Ident) return {
|
|
260
|
+
specifier: first[4].value,
|
|
261
|
+
raw: first[1],
|
|
262
|
+
quote: first[0] === _csstools_css_tokenizer.TokenType.String ? first[1][0] : void 0
|
|
263
|
+
};
|
|
264
|
+
if (first[0] === _csstools_css_tokenizer.TokenType.Function && first[4].value.toLowerCase() === "url" && (tokens[1]?.[0] === _csstools_css_tokenizer.TokenType.String || tokens[1]?.[0] === _csstools_css_tokenizer.TokenType.Ident) && tokens[2]?.[0] === _csstools_css_tokenizer.TokenType.CloseParen) return {
|
|
265
|
+
specifier: tokens[1][4].value,
|
|
266
|
+
raw: params.slice(first[2], tokens[2][3] + 1),
|
|
267
|
+
quote: tokens[1][0] === _csstools_css_tokenizer.TokenType.String ? tokens[1][1][0] : void 0
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
/** 把文件系统路径写成 CSS 请求串;缓存和读文件仍使用原始路径。 */
|
|
271
|
+
function quoteCssImportSpecifier(file, quote = "\"") {
|
|
272
|
+
return `${quote}${(node_path.default.sep === "\\" || /^[a-z]:[\\/]|^\\\\/i.test(file) ? file.replaceAll("\\", "/") : file).replaceAll("\\", "\\\\").replaceAll(quote, `\\${quote}`).replaceAll("\n", "\\a ").replaceAll("\r", "\\d ")}${quote}`;
|
|
273
|
+
}
|
|
274
|
+
/** 判断 import 参数是否指向 Tailwind CSS 包入口。 */
|
|
275
|
+
function isTailwindCssImport(params) {
|
|
276
|
+
const specifier = parseCssImportSpecifier(params)?.specifier;
|
|
277
|
+
if (!specifier) return false;
|
|
278
|
+
if (specifier === "tailwindcss" || specifier.startsWith("tailwindcss/")) return true;
|
|
279
|
+
const paths = specifier.includes("\\") ? node_path.default.win32 : node_path.default.posix;
|
|
280
|
+
return paths.basename(specifier) === "index.css" && paths.basename(paths.dirname(specifier)) === "tailwindcss";
|
|
281
|
+
}
|
|
282
|
+
/** 解析 `@import "..." source(...)` 中的 source 参数。 */
|
|
283
|
+
function parseImportSourceParam(params) {
|
|
284
|
+
const tokens = significantTokens(params);
|
|
285
|
+
const index = tokens.findIndex((token) => token[0] === _csstools_css_tokenizer.TokenType.Function && token[4].value === "source");
|
|
286
|
+
const value = tokens[index + 1];
|
|
287
|
+
if (index < 0 || tokens[index + 2]?.[0] !== _csstools_css_tokenizer.TokenType.CloseParen) return;
|
|
288
|
+
if (value?.[0] === _csstools_css_tokenizer.TokenType.Ident && value[4].value === "none") return {
|
|
289
|
+
none: true,
|
|
290
|
+
sourcePath: void 0
|
|
291
|
+
};
|
|
292
|
+
return value?.[0] === _csstools_css_tokenizer.TokenType.String ? {
|
|
293
|
+
none: false,
|
|
294
|
+
sourcePath: value[4].value
|
|
295
|
+
} : void 0;
|
|
296
|
+
}
|
|
297
|
+
//#endregion
|
|
298
|
+
//#region src/source-scan/description.ts
|
|
299
|
+
/** 只提取来源指令;默认扫描策略与配置加载由调用层决定。 */
|
|
300
|
+
function describeCssSources(root, isSourceImport = isTailwindCssImport) {
|
|
301
|
+
const imports = [];
|
|
302
|
+
const sources = [];
|
|
303
|
+
const configs = [];
|
|
304
|
+
root.walkAtRules((rule) => {
|
|
305
|
+
if (rule.name === "import" && isSourceImport(rule.params)) imports.push(parseImportSourceParam(rule.params) ?? {});
|
|
306
|
+
else if (rule.name === "source") {
|
|
307
|
+
const source = parseSourceFileParam(rule.params);
|
|
308
|
+
if (source) sources.push(source);
|
|
309
|
+
} else if (rule.name === "config") {
|
|
310
|
+
const config = parseConfigParam(rule.params);
|
|
311
|
+
if (config) configs.push(config);
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
return {
|
|
315
|
+
imports,
|
|
316
|
+
sources,
|
|
317
|
+
configs,
|
|
318
|
+
inlineCandidates: collectCssInlineSourceCandidates(root)
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
//#endregion
|
|
322
|
+
//#region src/source-scan/resolve.ts
|
|
323
|
+
/** 将 AST 描述与配置 content 合并,再交给共享扫描策略生成执行计划。 */
|
|
324
|
+
async function resolveCssScanSources(definitions, policy) {
|
|
325
|
+
const entries = [];
|
|
326
|
+
const configEntries = [];
|
|
327
|
+
const configGroups = [];
|
|
328
|
+
const configPaths = /* @__PURE__ */ new Set();
|
|
329
|
+
const included = /* @__PURE__ */ new Set();
|
|
330
|
+
const excluded = /* @__PURE__ */ new Set();
|
|
331
|
+
let automaticBase;
|
|
332
|
+
let sourceNone = false;
|
|
333
|
+
let hasImport = false;
|
|
334
|
+
for (const { root, base } of definitions) {
|
|
335
|
+
const descriptor = describeCssSources(root);
|
|
336
|
+
hasImport ||= descriptor.imports.length > 0;
|
|
337
|
+
sourceNone ||= descriptor.imports.some((item) => item.none);
|
|
338
|
+
for (const item of descriptor.imports) if (item.sourcePath) automaticBase = (0, _weapp_tailwindcss_source_scan.sourcePathApi)(base, item.sourcePath).resolve(base, item.sourcePath);
|
|
339
|
+
for (const source of descriptor.sources) entries.push(await (0, _weapp_tailwindcss_source_scan.resolveTailwindSourceEntry)(source.sourcePath, base, source.negated, policy.pattern));
|
|
340
|
+
for (const value of descriptor.inlineCandidates.included) included.add(value);
|
|
341
|
+
for (const value of descriptor.inlineCandidates.excluded) excluded.add(value);
|
|
342
|
+
for (const request of descriptor.configs) configPaths.add(policy.configResolution === "module" ? (0, node_module.createRequire)(node_path.default.join(base, "package.json")).resolve(request) : (0, _weapp_tailwindcss_source_scan.sourcePathApi)(base, request).resolve(base, request));
|
|
343
|
+
}
|
|
344
|
+
if (policy.config) configPaths.add((0, _weapp_tailwindcss_source_scan.sourcePathApi)(policy.base, policy.config).resolve(policy.base, policy.config));
|
|
345
|
+
for (const config of policy.loadConfigContent === false ? [] : configPaths) {
|
|
346
|
+
const base = node_path.default.dirname(config);
|
|
347
|
+
const loaded = await (0, tailwindcss_config.loadConfig)({
|
|
348
|
+
config,
|
|
349
|
+
cwd: base
|
|
350
|
+
});
|
|
351
|
+
const group = (0, _weapp_tailwindcss_source_scan.normalizeLegacyContentEntries)(loaded?.config.content, base, { relativeBase: base });
|
|
352
|
+
configGroups.push(group);
|
|
353
|
+
configEntries.push(...group);
|
|
354
|
+
}
|
|
355
|
+
const explicitEntries = policy.sourceEntries ?? entries;
|
|
356
|
+
const combinedEntries = [...explicitEntries, ...configEntries];
|
|
357
|
+
let mode = policy.automatic;
|
|
358
|
+
if (mode !== "disabled") {
|
|
359
|
+
if (automaticBase) mode = "auto";
|
|
360
|
+
else if (sourceNone || policy.requireImport && !hasImport && combinedEntries.length === 0) mode = "disabled";
|
|
361
|
+
}
|
|
362
|
+
const base = automaticBase ?? (combinedEntries.length > 0 ? policy.base : policy.defaultBase ?? policy.base);
|
|
363
|
+
return {
|
|
364
|
+
entries: (0, _weapp_tailwindcss_source_scan.createSourceScanPlan)({
|
|
365
|
+
base,
|
|
366
|
+
mode,
|
|
367
|
+
entries: combinedEntries,
|
|
368
|
+
pattern: policy.pattern,
|
|
369
|
+
...policy.ignoredPatterns ? { ignoredPatterns: policy.ignoredPatterns } : {}
|
|
370
|
+
}),
|
|
371
|
+
explicitEntries,
|
|
372
|
+
configEntries,
|
|
373
|
+
configGroups,
|
|
374
|
+
configPaths: [...configPaths],
|
|
375
|
+
inlineCandidates: {
|
|
376
|
+
included,
|
|
377
|
+
excluded
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
//#endregion
|
|
382
|
+
//#region src/syntax/parse.ts
|
|
383
|
+
/** 解析标准 CSS;调用方负责处理非法输入。 */
|
|
384
|
+
function parseCssSource(source, from) {
|
|
385
|
+
return postcss.default.parse(source, { from });
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* 解析 SCSS/Sass 风格源码。
|
|
389
|
+
* `postcss.parse` 不读取 syntax 选项,行注释和插值必须走 SCSS parser。
|
|
390
|
+
*/
|
|
391
|
+
function parseScssSource(source, from) {
|
|
392
|
+
return postcss_scss.default.parse(source, { from });
|
|
393
|
+
}
|
|
394
|
+
function stringifyScssSource(root) {
|
|
395
|
+
return root.toString(postcss_scss.default.stringify);
|
|
396
|
+
}
|
|
397
|
+
/** Harmony 在 Sass 预处理前读取局部样式;必须识别行注释,避免将其并入选择器。 */
|
|
398
|
+
function parseUniAppXStyleSource(source) {
|
|
399
|
+
return parseScssSource(source);
|
|
400
|
+
}
|
|
401
|
+
function isUniAppXStyleSourceEmpty(source) {
|
|
402
|
+
try {
|
|
403
|
+
return parseUniAppXStyleSource(source).nodes.every((node) => node.type === "comment");
|
|
404
|
+
} catch {
|
|
405
|
+
return false;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
//#endregion
|
|
409
|
+
//#region src/syntax/runtime-signature.ts
|
|
410
|
+
function rawField(node, field, value) {
|
|
411
|
+
const raw = node.raws[field];
|
|
412
|
+
return raw?.value === value ? raw.raw : value;
|
|
413
|
+
}
|
|
414
|
+
function signatureNodes(nodes) {
|
|
415
|
+
const result = [];
|
|
416
|
+
for (const node of nodes) {
|
|
417
|
+
if (node.type === "comment") continue;
|
|
418
|
+
const before = node.raws.before?.trim() ?? "";
|
|
419
|
+
const between = node.raws.between?.trim() ?? "";
|
|
420
|
+
if (node.type === "decl") result.push([
|
|
421
|
+
"decl",
|
|
422
|
+
before,
|
|
423
|
+
node.prop,
|
|
424
|
+
between,
|
|
425
|
+
rawField(node, "value", node.value),
|
|
426
|
+
Boolean(node.important)
|
|
427
|
+
]);
|
|
428
|
+
else {
|
|
429
|
+
const after = node.raws.after?.trim() ?? "";
|
|
430
|
+
if (node.type === "rule") result.push([
|
|
431
|
+
"rule",
|
|
432
|
+
before,
|
|
433
|
+
rawField(node, "selector", node.selector),
|
|
434
|
+
between,
|
|
435
|
+
signatureNodes(node.nodes),
|
|
436
|
+
after
|
|
437
|
+
]);
|
|
438
|
+
else result.push([
|
|
439
|
+
"atrule",
|
|
440
|
+
before,
|
|
441
|
+
node.name,
|
|
442
|
+
node.raws.afterName?.trim() ?? "",
|
|
443
|
+
rawField(node, "params", node.params),
|
|
444
|
+
between,
|
|
445
|
+
Boolean(node.nodes),
|
|
446
|
+
signatureNodes(node.nodes ?? []),
|
|
447
|
+
after
|
|
448
|
+
]);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
return result;
|
|
452
|
+
}
|
|
453
|
+
/** 忽略结构性排版,保留值、选择器和 token 边界;不追求合并所有等价 CSS。 */
|
|
454
|
+
function createCssRuntimeAffectingSignature(source) {
|
|
455
|
+
try {
|
|
456
|
+
const root = parseCssSource(source);
|
|
457
|
+
return JSON.stringify([
|
|
458
|
+
"css",
|
|
459
|
+
signatureNodes(root.nodes),
|
|
460
|
+
root.raws.after?.trim() ?? ""
|
|
461
|
+
]);
|
|
462
|
+
} catch {
|
|
463
|
+
return JSON.stringify(["raw", source]);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
//#endregion
|
|
467
|
+
//#region src/syntax/location-dependencies.ts
|
|
468
|
+
const LOCATION_SYNTAX_HINT_RE = /[@\\]|url\(/i;
|
|
469
|
+
const ABSOLUTE_URL_RE = /^(?:[a-z][a-z\d+.-]*:|\/|#)/i;
|
|
470
|
+
function isIndependentUrl(value) {
|
|
471
|
+
return ABSOLUTE_URL_RE.test(value.trim());
|
|
472
|
+
}
|
|
473
|
+
/** 判断 CSS 转换是否依赖资源位置;路径解析和缓存范围仍由调用方负责。 */
|
|
474
|
+
function hasCssLocationDependencies(source) {
|
|
475
|
+
if (!LOCATION_SYNTAX_HINT_RE.test(source)) return false;
|
|
476
|
+
let malformed = false;
|
|
477
|
+
const stream = (0, _csstools_css_tokenizer.tokenizer)({ css: source }, { onParseError() {
|
|
478
|
+
malformed = true;
|
|
479
|
+
} });
|
|
480
|
+
const nextSignificant = () => {
|
|
481
|
+
let token = stream.nextToken();
|
|
482
|
+
while (token[0] === _csstools_css_tokenizer.TokenType.Whitespace || token[0] === _csstools_css_tokenizer.TokenType.Comment) token = stream.nextToken();
|
|
483
|
+
return token;
|
|
484
|
+
};
|
|
485
|
+
while (!stream.endOfFile()) {
|
|
486
|
+
const token = stream.nextToken();
|
|
487
|
+
if (token[0] === _csstools_css_tokenizer.TokenType.AtKeyword && token[4].value.toLowerCase() === "import") return true;
|
|
488
|
+
if (token[0] === _csstools_css_tokenizer.TokenType.URL && !isIndependentUrl(token[4].value)) return true;
|
|
489
|
+
if (token[0] === _csstools_css_tokenizer.TokenType.Function && token[4].value.toLowerCase() === "url") {
|
|
490
|
+
const value = nextSignificant();
|
|
491
|
+
if (value[0] !== _csstools_css_tokenizer.TokenType.String || !isIndependentUrl(value[4].value)) return true;
|
|
492
|
+
if (nextSignificant()[0] !== _csstools_css_tokenizer.TokenType.CloseParen) return true;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
return malformed;
|
|
496
|
+
}
|
|
497
|
+
//#endregion
|
|
498
|
+
//#region src/syntax/rewrite-imports.ts
|
|
499
|
+
/** 改写请求串;文件查找、包解析与路径规则由调用方提供。 */
|
|
500
|
+
function rewriteCssImportSpecifiers(css, resolve, options = {}) {
|
|
501
|
+
let root;
|
|
502
|
+
try {
|
|
503
|
+
root = postcss.default.parse(css);
|
|
504
|
+
} catch (error) {
|
|
505
|
+
if (options.tolerateInvalidCss) return css;
|
|
506
|
+
throw error;
|
|
507
|
+
}
|
|
508
|
+
const names = new Set(options.atRuleNames ?? ["import"]);
|
|
509
|
+
let changed = false;
|
|
510
|
+
root.walkAtRules((rule) => {
|
|
511
|
+
if (!names.has(rule.name)) return;
|
|
512
|
+
const parsed = parseCssImportSpecifier(rule.params);
|
|
513
|
+
if (!parsed) return;
|
|
514
|
+
const replacement = resolve(parsed.specifier);
|
|
515
|
+
if (!replacement) return;
|
|
516
|
+
rule.params = rule.params.replace(parsed.raw, () => quoteCssImportSpecifier(replacement, parsed.quote));
|
|
517
|
+
changed = true;
|
|
518
|
+
});
|
|
519
|
+
return changed ? root.toString() : css;
|
|
520
|
+
}
|
|
521
|
+
//#endregion
|
|
522
|
+
exports.collectCssInlineSourceCandidates = collectCssInlineSourceCandidates;
|
|
523
|
+
exports.createCssRuntimeAffectingSignature = createCssRuntimeAffectingSignature;
|
|
524
|
+
exports.describeCssSources = describeCssSources;
|
|
525
|
+
exports.expandInlineSourceCandidatePattern = expandInlineSourceCandidatePattern;
|
|
526
|
+
exports.expandTailwindSourceEntries = expandTailwindSourceEntries;
|
|
527
|
+
exports.hasCssLocationDependencies = hasCssLocationDependencies;
|
|
528
|
+
exports.isTailwindCssImport = isTailwindCssImport;
|
|
529
|
+
exports.isUniAppXStyleSourceEmpty = isUniAppXStyleSourceEmpty;
|
|
530
|
+
exports.parseConfigParam = parseConfigParam;
|
|
531
|
+
exports.parseCssImportSpecifier = parseCssImportSpecifier;
|
|
532
|
+
exports.parseCssSource = parseCssSource;
|
|
533
|
+
exports.parseImportSourceParam = parseImportSourceParam;
|
|
534
|
+
exports.parseScssSource = parseScssSource;
|
|
535
|
+
exports.parseSourceFileParam = parseSourceFileParam;
|
|
536
|
+
exports.parseUniAppXStyleSource = parseUniAppXStyleSource;
|
|
537
|
+
exports.quoteCssImportSpecifier = quoteCssImportSpecifier;
|
|
538
|
+
exports.resolveCssScanSources = resolveCssScanSources;
|
|
539
|
+
exports.resolveCssSourceEntries = resolveCssSourceEntries;
|
|
540
|
+
exports.rewriteCssImportSpecifiers = rewriteCssImportSpecifiers;
|
|
541
|
+
Object.defineProperty(exports, "scss", {
|
|
542
|
+
enumerable: true,
|
|
543
|
+
get: function() {
|
|
544
|
+
return postcss_scss.default;
|
|
545
|
+
}
|
|
546
|
+
});
|
|
547
|
+
exports.stringifyScssSource = stringifyScssSource;
|
package/dist/syntax.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { collectCssInlineSourceCandidates, expandInlineSourceCandidatePattern, expandTailwindSourceEntries, parseConfigParam, parseSourceFileParam, resolveCssSourceEntries, type TailwindInlineSourceCandidates } from './source-scan.js';
|
|
2
|
+
export { describeCssSources } from './source-scan/description.js';
|
|
3
|
+
export { type CssScanDefinition, type CssScanPolicy, resolveCssScanSources } from './source-scan/resolve.js';
|
|
4
|
+
export * from './syntax/index.js';
|
|
5
|
+
export { hasCssLocationDependencies } from './syntax/location-dependencies.js';
|
|
6
|
+
export { rewriteCssImportSpecifiers } from './syntax/rewrite-imports.js';
|
package/dist/syntax.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { collectCssInlineSourceCandidates, describeCssSources, expandInlineSourceCandidatePattern, expandTailwindSourceEntries, isTailwindCssImport, parseConfigParam, parseCssImportSpecifier, parseImportSourceParam, parseSourceFileParam, quoteCssImportSpecifier, resolveCssScanSources, resolveCssSourceEntries } from "./resolve-DQiOQfoY.js";
|
|
2
|
+
import { createCssRuntimeAffectingSignature, hasCssLocationDependencies, isUniAppXStyleSourceEmpty, parseCssSource, parseScssSource, parseUniAppXStyleSource, rewriteCssImportSpecifiers, scss, stringifyScssSource } from "./rewrite-imports-CdZQE6CI.js";
|
|
3
|
+
export { collectCssInlineSourceCandidates, createCssRuntimeAffectingSignature, describeCssSources, expandInlineSourceCandidatePattern, expandTailwindSourceEntries, hasCssLocationDependencies, isTailwindCssImport, isUniAppXStyleSourceEmpty, parseConfigParam, parseCssImportSpecifier, parseCssSource, parseImportSourceParam, parseScssSource, parseSourceFileParam, parseUniAppXStyleSource, quoteCssImportSpecifier, resolveCssScanSources, resolveCssSourceEntries, rewriteCssImportSpecifiers, scss, stringifyScssSource };
|