weapp-tailwindcss 4.3.2 → 4.4.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/chunk-2F7HOQQY.mjs +8 -0
  2. package/dist/chunk-2NRTWL47.js +43 -0
  3. package/dist/{chunk-YNMM5ZP5.mjs → chunk-3MSGCIVH.mjs} +128 -138
  4. package/dist/chunk-6GP37C26.js +8 -0
  5. package/dist/{chunk-GRWK73SM.js → chunk-AEJDBNAX.js} +567 -309
  6. package/dist/{chunk-IDYXPWF6.mjs → chunk-AXYGCCZW.mjs} +51 -63
  7. package/dist/chunk-E2LRXNZ3.js +122 -0
  8. package/dist/{chunk-BXPTS6UP.mjs → chunk-FBGUUXQV.mjs} +1 -1
  9. package/dist/{chunk-72PXDJ7I.js → chunk-FOSGDQZ7.js} +34 -43
  10. package/dist/chunk-H4JTYYOI.mjs +43 -0
  11. package/dist/{chunk-3YIQPUK7.mjs → chunk-IHKVNALD.mjs} +29 -38
  12. package/dist/chunk-KAKRCCPX.mjs +122 -0
  13. package/dist/{chunk-AMSF25MI.js → chunk-NZ7VALIM.js} +130 -140
  14. package/dist/{chunk-YSVQIZ4W.js → chunk-PPTSD6TQ.js} +51 -63
  15. package/dist/{chunk-K6IPKJSY.js → chunk-RBRSMHFS.js} +1 -1
  16. package/dist/chunk-UW3WHSZ5.js +39 -0
  17. package/dist/{chunk-DGVVFKNF.mjs → chunk-WCIVXE2D.mjs} +566 -308
  18. package/dist/chunk-ZNKIYZRQ.mjs +39 -0
  19. package/dist/cli.js +5 -8
  20. package/dist/cli.mjs +4 -7
  21. package/dist/core.js +5 -5
  22. package/dist/core.mjs +4 -4
  23. package/dist/css-macro/postcss.js +1 -1
  24. package/dist/css-macro/postcss.mjs +1 -1
  25. package/dist/css-macro.js +3 -3
  26. package/dist/css-macro.mjs +2 -2
  27. package/dist/defaults.js +4 -4
  28. package/dist/defaults.mjs +3 -3
  29. package/dist/escape.js +1 -1
  30. package/dist/escape.mjs +1 -1
  31. package/dist/gulp.js +7 -7
  32. package/dist/gulp.mjs +6 -6
  33. package/dist/index.js +10 -9
  34. package/dist/index.mjs +9 -8
  35. package/dist/postcss-html-transform.js +1 -1
  36. package/dist/postcss-html-transform.mjs +1 -1
  37. package/dist/presets.js +3 -3
  38. package/dist/presets.mjs +2 -2
  39. package/dist/types.d.mts +248 -194
  40. package/dist/types.d.ts +248 -194
  41. package/dist/types.js +1 -1
  42. package/dist/types.mjs +1 -1
  43. package/dist/vite.js +7 -7
  44. package/dist/vite.mjs +6 -6
  45. package/dist/webpack.js +8 -7
  46. package/dist/webpack.mjs +7 -6
  47. package/dist/webpack4.js +53 -68
  48. package/dist/webpack4.mjs +52 -67
  49. package/package.json +10 -12
  50. package/dist/chunk-3AUX4FGE.mjs +0 -13
  51. package/dist/chunk-JXBLHLFR.mjs +0 -27
  52. package/dist/chunk-K3KFCISK.js +0 -145
  53. package/dist/chunk-LSSLYD6B.js +0 -13
  54. package/dist/chunk-O335YLYH.js +0 -27
  55. package/dist/chunk-RC2KZ2LO.mjs +0 -145
@@ -3,17 +3,15 @@ import {
3
3
  } from "./chunk-Q67IXIAH.mjs";
4
4
  import {
5
5
  getDefaultOptions
6
- } from "./chunk-3YIQPUK7.mjs";
6
+ } from "./chunk-IHKVNALD.mjs";
7
7
  import {
8
8
  defuOverrideArray,
9
- isMap,
10
- regExpTest
11
- } from "./chunk-JXBLHLFR.mjs";
9
+ isMap
10
+ } from "./chunk-ZNKIYZRQ.mjs";
12
11
 
13
12
  // src/context/index.ts
14
- import { logger, pc } from "@weapp-tailwindcss/logger";
13
+ import { logger as logger2, pc } from "@weapp-tailwindcss/logger";
15
14
  import { useMangleStore } from "@weapp-tailwindcss/mangle";
16
- import { createStyleHandler } from "@weapp-tailwindcss/postcss";
17
15
 
18
16
  // src/cache/index.ts
19
17
  import { LRUCache } from "lru-cache";
@@ -25,6 +23,9 @@ function md5Hash(data) {
25
23
  }
26
24
 
27
25
  // src/cache/index.ts
26
+ function isProcessResult(value) {
27
+ return typeof value === "object" && value !== null && "result" in value;
28
+ }
28
29
  function createCache(options) {
29
30
  const disabled = options === false;
30
31
  const hashMap = /* @__PURE__ */ new Map();
@@ -34,7 +35,7 @@ function createCache(options) {
34
35
  ttl: 0,
35
36
  ttlAutopurge: false
36
37
  });
37
- return {
38
+ const cache = {
38
39
  hashMap,
39
40
  instance,
40
41
  hasHashKey(key) {
@@ -56,47 +57,60 @@ function createCache(options) {
56
57
  return md5Hash(message);
57
58
  },
58
59
  calcHashValueChanged(key, hash) {
59
- const hit = this.getHashValue(key);
60
+ const hit = hashMap.get(key);
60
61
  if (hit) {
61
- this.setHashValue(key, {
62
- // new file should be changed
62
+ hashMap.set(key, {
63
63
  changed: hash !== hit.hash,
64
- // new hash
65
64
  hash
66
65
  });
67
66
  } else {
68
- this.setHashValue(key, {
69
- // new file should be changed
67
+ hashMap.set(key, {
70
68
  changed: true,
71
69
  hash
72
70
  });
73
71
  }
74
- return this;
72
+ return cache;
75
73
  },
76
74
  has(key) {
77
75
  return instance.has(key);
78
76
  },
79
- async process(key, callback, fallback) {
77
+ async process({
78
+ key,
79
+ hashKey,
80
+ rawSource,
81
+ hash,
82
+ resolveCache,
83
+ transform,
84
+ onCacheHit
85
+ }) {
80
86
  if (disabled) {
81
- const res = await fallback();
82
- if (res) {
83
- this.set(res.key, res.source);
84
- }
85
- } else {
86
- const hit = this.getHashValue(key);
87
- if (hit && !hit.changed) {
88
- const returnFlag = await callback();
89
- if (returnFlag !== false) {
90
- return;
91
- }
92
- }
93
- const res = await fallback();
94
- if (res) {
95
- this.set(res.key, res.source);
87
+ const value2 = await transform();
88
+ return isProcessResult(value2) ? value2.result : value2;
89
+ }
90
+ const cacheHashKey = hashKey ?? key;
91
+ let hasChanged = true;
92
+ if (hash != null || rawSource != null) {
93
+ const nextHash = hash ?? cache.computeHash(rawSource);
94
+ cache.calcHashValueChanged(cacheHashKey, nextHash);
95
+ const entry = cache.getHashValue(cacheHashKey);
96
+ hasChanged = entry?.changed ?? true;
97
+ }
98
+ const readCache = resolveCache ?? (() => cache.get(key));
99
+ if (!hasChanged) {
100
+ const cached = readCache();
101
+ if (cached !== void 0) {
102
+ await onCacheHit?.(cached);
103
+ return cached;
96
104
  }
97
105
  }
106
+ const value = await transform();
107
+ const normalized = isProcessResult(value) ? value : { result: value };
108
+ const stored = normalized.cacheValue ?? normalized.result;
109
+ cache.set(key, stored);
110
+ return normalized.result;
98
111
  }
99
112
  };
113
+ return cache;
100
114
  }
101
115
  function initializeCache(cacheConfig) {
102
116
  if (typeof cacheConfig === "boolean" || cacheConfig === void 0) {
@@ -105,6 +119,19 @@ function initializeCache(cacheConfig) {
105
119
  return cacheConfig;
106
120
  }
107
121
 
122
+ // src/context/custom-attributes.ts
123
+ function toCustomAttributesEntities(customAttributes) {
124
+ if (isMap(customAttributes)) {
125
+ return [
126
+ ...customAttributes.entries()
127
+ ];
128
+ }
129
+ return Object.entries(customAttributes);
130
+ }
131
+
132
+ // src/context/handlers.ts
133
+ import { createStyleHandler } from "@weapp-tailwindcss/postcss";
134
+
108
135
  // src/js/babel.ts
109
136
  import { jsStringEscape as jsStringEscape2 } from "@ast-core/escape";
110
137
  import { LRUCache as LRUCache2 } from "lru-cache";
@@ -118,101 +145,198 @@ function _interopDefaultCompat(e) {
118
145
  }
119
146
  var traverse = _interopDefaultCompat(_babelTraverse);
120
147
 
148
+ // src/utils/nameMatcher.ts
149
+ function createNameMatcher(list, { exact = false } = {}) {
150
+ if (!list || list.length === 0) {
151
+ return () => false;
152
+ }
153
+ const exactStrings = /* @__PURE__ */ new Set();
154
+ const fuzzyStrings = [];
155
+ const regexList = [];
156
+ for (const item of list) {
157
+ if (typeof item === "string") {
158
+ if (exact) {
159
+ exactStrings.add(item);
160
+ } else {
161
+ fuzzyStrings.push(item);
162
+ }
163
+ } else {
164
+ regexList.push(item);
165
+ }
166
+ }
167
+ return (value) => {
168
+ if (exact && exactStrings.has(value)) {
169
+ return true;
170
+ }
171
+ if (!exact) {
172
+ for (const candidate of fuzzyStrings) {
173
+ if (value.includes(candidate)) {
174
+ return true;
175
+ }
176
+ }
177
+ }
178
+ for (const regex of regexList) {
179
+ regex.lastIndex = 0;
180
+ if (regex.test(value)) {
181
+ return true;
182
+ }
183
+ }
184
+ return false;
185
+ };
186
+ }
187
+
121
188
  // src/js/handlers.ts
122
189
  import { jsStringEscape } from "@ast-core/escape";
123
190
  import { escapeStringRegexp } from "@weapp-core/regex";
124
191
  import { splitCode } from "@weapp-tailwindcss/shared/extractors";
125
192
 
126
193
  // src/utils/decode.ts
194
+ var unicodeEscapeRE = /\\u([\dA-Fa-f]{4})/g;
195
+ function decodeUnicode(value) {
196
+ return value.replace(unicodeEscapeRE, (_match, hex) => {
197
+ const codePoint = Number.parseInt(hex, 16);
198
+ return Number.isNaN(codePoint) ? _match : String.fromCharCode(codePoint);
199
+ });
200
+ }
127
201
  function decodeUnicode2(input) {
128
202
  try {
129
203
  return JSON.parse(`"${input}"`);
130
204
  } catch (_error) {
131
- return input;
205
+ return decodeUnicode(input);
132
206
  }
133
207
  }
134
208
 
135
209
  // src/js/handlers.ts
210
+ function hasIgnoreComment(node) {
211
+ return Array.isArray(node.leadingComments) && node.leadingComments.some((comment) => comment.value.includes("weapp-tw") && comment.value.includes("ignore"));
212
+ }
213
+ function shouldTransformClassName(candidate, {
214
+ alwaysEscape,
215
+ classNameSet,
216
+ jsPreserveClass
217
+ }) {
218
+ if (alwaysEscape) {
219
+ return true;
220
+ }
221
+ if (!classNameSet) {
222
+ return false;
223
+ }
224
+ if (!classNameSet.has(candidate)) {
225
+ return false;
226
+ }
227
+ return !jsPreserveClass?.(candidate);
228
+ }
229
+ function extractLiteralValue(path2, { unescapeUnicode, arbitraryValues }) {
230
+ const allowDoubleQuotes = arbitraryValues?.allowDoubleQuotes;
231
+ let offset = 0;
232
+ let original;
233
+ if (path2.isStringLiteral()) {
234
+ offset = 1;
235
+ original = path2.node.value;
236
+ } else if (path2.isTemplateElement()) {
237
+ original = path2.node.value.raw;
238
+ } else {
239
+ original = "";
240
+ }
241
+ let literal = original;
242
+ if (unescapeUnicode && original.includes("\\u")) {
243
+ literal = decodeUnicode2(original);
244
+ }
245
+ return {
246
+ allowDoubleQuotes,
247
+ literal,
248
+ offset,
249
+ original
250
+ };
251
+ }
136
252
  function replaceHandleValue(path2, options) {
137
253
  const {
138
- classNameSet,
139
254
  escapeMap,
140
- mangleContext: ctx,
141
- needEscaped = false,
142
- jsPreserveClass,
143
- arbitraryValues,
144
- alwaysEscape,
145
- unescapeUnicode
255
+ mangleContext,
256
+ needEscaped = false
146
257
  } = options;
147
- const allowDoubleQuotes = arbitraryValues?.allowDoubleQuotes;
148
- const offset = path2.isStringLiteral() ? 1 : 0;
149
- const str = path2.isStringLiteral() ? path2.node.value : path2.isTemplateElement() ? path2.node.value.raw : "";
150
- let rawStr = str;
151
- let needUpdate = false;
152
- if (unescapeUnicode && rawStr.includes("\\u")) {
153
- rawStr = decodeUnicode2(rawStr);
258
+ const { literal, original, allowDoubleQuotes, offset } = extractLiteralValue(path2, options);
259
+ if (hasIgnoreComment(path2.node)) {
260
+ return void 0;
154
261
  }
155
- const node = path2.node;
156
- const arr = splitCode(rawStr, allowDoubleQuotes);
157
- for (const v of arr) {
158
- if (alwaysEscape || classNameSet && classNameSet.has(v) && !jsPreserveClass?.(v)) {
159
- let ignoreFlag = false;
160
- if (Array.isArray(node.leadingComments)) {
161
- ignoreFlag = node.leadingComments.findIndex((x) => x.value.includes("weapp-tw") && x.value.includes("ignore")) > -1;
162
- }
163
- if (!ignoreFlag) {
164
- if (ctx) {
165
- rawStr = ctx.jsHandler(rawStr);
166
- }
167
- rawStr = rawStr.replace(
168
- new RegExp(escapeStringRegexp(v)),
169
- replaceWxml(v, {
170
- escapeMap
171
- })
172
- );
173
- needUpdate = true;
262
+ const candidates = splitCode(literal, allowDoubleQuotes);
263
+ if (candidates.length === 0) {
264
+ return void 0;
265
+ }
266
+ let transformed = literal;
267
+ let mutated = false;
268
+ const replacementCache = /* @__PURE__ */ new Map();
269
+ for (const candidate of candidates) {
270
+ if (!shouldTransformClassName(candidate, options)) {
271
+ continue;
272
+ }
273
+ if (mangleContext) {
274
+ const mangled = mangleContext.jsHandler(transformed);
275
+ if (mangled !== transformed) {
276
+ transformed = mangled;
277
+ mutated = true;
174
278
  }
175
279
  }
176
- }
177
- if (needUpdate && typeof node.start === "number" && typeof node.end === "number") {
178
- const start = node.start + offset;
179
- const end = node.end - offset;
180
- if (start < end && str !== rawStr) {
181
- const value = needEscaped ? jsStringEscape(rawStr) : rawStr;
182
- return {
183
- start,
184
- end,
185
- value,
186
- path: path2
280
+ if (!transformed.includes(candidate)) {
281
+ continue;
282
+ }
283
+ let cached = replacementCache.get(candidate);
284
+ if (!cached) {
285
+ cached = {
286
+ pattern: new RegExp(escapeStringRegexp(candidate)),
287
+ replacement: replaceWxml(candidate, { escapeMap })
187
288
  };
289
+ replacementCache.set(candidate, cached);
290
+ }
291
+ const { pattern, replacement } = cached;
292
+ const replaced = transformed.replace(pattern, replacement);
293
+ if (replaced !== transformed) {
294
+ transformed = replaced;
295
+ mutated = true;
188
296
  }
189
297
  }
298
+ const node = path2.node;
299
+ if (!mutated || typeof node.start !== "number" || typeof node.end !== "number") {
300
+ return void 0;
301
+ }
302
+ const start = node.start + offset;
303
+ const end = node.end - offset;
304
+ if (start >= end || transformed === original) {
305
+ return void 0;
306
+ }
307
+ const value = needEscaped ? jsStringEscape(transformed) : transformed;
308
+ return {
309
+ start,
310
+ end,
311
+ value,
312
+ path: path2
313
+ };
190
314
  }
191
315
 
192
316
  // src/js/JsTokenUpdater.ts
193
317
  var JsTokenUpdater = class {
194
318
  constructor({ value } = {}) {
195
- this.value = value ?? [];
319
+ this.tokens = value ? [...value] : [];
196
320
  }
197
321
  addToken(token) {
198
322
  if (token) {
199
- this.value.push(token);
323
+ this.tokens.push(token);
200
324
  }
201
325
  }
202
326
  push(...args) {
203
- this.value.push(...args);
327
+ this.tokens.push(...args);
204
328
  return this;
205
329
  }
206
330
  map(callbackfn) {
207
- this.value = this.value.map(callbackfn);
331
+ this.tokens = this.tokens.map(callbackfn);
208
332
  return this;
209
333
  }
210
334
  filter(callbackfn) {
211
- this.value = this.value.filter(callbackfn);
335
+ this.tokens = this.tokens.filter(callbackfn);
212
336
  return this;
213
337
  }
214
338
  updateMagicString(ms) {
215
- for (const { start, end, value } of this.value) {
339
+ for (const { start, end, value } of this.tokens) {
216
340
  ms.update(start, end, value);
217
341
  }
218
342
  return ms;
@@ -220,13 +344,14 @@ var JsTokenUpdater = class {
220
344
  };
221
345
 
222
346
  // src/js/NodePathWalker.ts
223
- var walkedBindingWeakMap = /* @__PURE__ */ new WeakMap();
224
347
  var NodePathWalker = class {
225
348
  constructor({ ignoreCallExpressionIdentifiers, callback } = {}) {
226
349
  this.ignoreCallExpressionIdentifiers = ignoreCallExpressionIdentifiers ?? [];
227
350
  this.callback = callback ?? (() => {
228
351
  });
229
352
  this.imports = /* @__PURE__ */ new Set();
353
+ this.visited = /* @__PURE__ */ new WeakSet();
354
+ this.isIgnoredCallIdentifier = createNameMatcher(this.ignoreCallExpressionIdentifiers, { exact: true });
230
355
  }
231
356
  walkVariableDeclarator(path2) {
232
357
  const init = path2.get("init");
@@ -273,10 +398,10 @@ var NodePathWalker = class {
273
398
  }
274
399
  }
275
400
  walkNode(arg) {
276
- if (walkedBindingWeakMap.get(arg)) {
401
+ if (this.visited.has(arg)) {
277
402
  return;
278
403
  }
279
- walkedBindingWeakMap.set(arg, true);
404
+ this.visited.add(arg);
280
405
  if (arg.isIdentifier()) {
281
406
  const binding = arg.scope.getBinding(arg.node.name);
282
407
  if (binding) {
@@ -336,14 +461,11 @@ var NodePathWalker = class {
336
461
  }
337
462
  }
338
463
  /**
339
- * @description main 方法
340
- * @param path
464
+ * Walk the arguments of a desired call expression so their bindings can be analysed.
341
465
  */
342
466
  walkCallExpression(path2) {
343
467
  const calleePath = path2.get("callee");
344
- if (calleePath.isIdentifier() && regExpTest(this.ignoreCallExpressionIdentifiers, calleePath.node.name, {
345
- exact: true
346
- })) {
468
+ if (calleePath.isIdentifier() && this.isIgnoredCallIdentifier(calleePath.node.name)) {
347
469
  for (const arg of path2.get("arguments")) {
348
470
  this.walkNode(arg);
349
471
  }
@@ -431,19 +553,88 @@ function isEvalPath(p) {
431
553
  }
432
554
  return false;
433
555
  }
434
- var ignoreFlagMap = /* @__PURE__ */ new WeakMap();
556
+ function createEvalReplacementToken(path2, updated) {
557
+ const node = path2.node;
558
+ let offset = 0;
559
+ let original;
560
+ if (path2.isStringLiteral()) {
561
+ offset = 1;
562
+ original = path2.node.value;
563
+ } else if (path2.isTemplateElement()) {
564
+ original = path2.node.value.raw;
565
+ } else {
566
+ original = "";
567
+ }
568
+ if (typeof node.start !== "number" || typeof node.end !== "number") {
569
+ return void 0;
570
+ }
571
+ const start = node.start + offset;
572
+ const end = node.end - offset;
573
+ if (start >= end) {
574
+ return void 0;
575
+ }
576
+ if (original === updated) {
577
+ return void 0;
578
+ }
579
+ const value = path2.isStringLiteral() ? jsStringEscape2(updated) : updated;
580
+ return {
581
+ start,
582
+ end,
583
+ value,
584
+ path: path2
585
+ };
586
+ }
587
+ function handleEvalStringLiteral(path2, options, updater) {
588
+ const { code } = jsHandler(path2.node.value, {
589
+ ...options,
590
+ needEscaped: false,
591
+ generateMap: false
592
+ });
593
+ if (!code) {
594
+ return;
595
+ }
596
+ const token = createEvalReplacementToken(path2, code);
597
+ if (token) {
598
+ updater.addToken(token);
599
+ }
600
+ }
601
+ function handleEvalTemplateElement(path2, options, updater) {
602
+ const { code } = jsHandler(path2.node.value.raw, {
603
+ ...options,
604
+ generateMap: false
605
+ });
606
+ if (!code) {
607
+ return;
608
+ }
609
+ const token = createEvalReplacementToken(path2, code);
610
+ if (token) {
611
+ updater.addToken(token);
612
+ }
613
+ }
614
+ function walkEvalExpression(path2, options, updater) {
615
+ path2.traverse({
616
+ StringLiteral(innerPath) {
617
+ handleEvalStringLiteral(innerPath, options, updater);
618
+ },
619
+ TemplateElement(innerPath) {
620
+ handleEvalTemplateElement(innerPath, options, updater);
621
+ }
622
+ });
623
+ }
435
624
  function analyzeSource(ast, options) {
436
625
  const jsTokenUpdater = new JsTokenUpdater();
626
+ const ignoredPaths = /* @__PURE__ */ new WeakSet();
437
627
  const walker = new NodePathWalker(
438
628
  {
439
629
  ignoreCallExpressionIdentifiers: options.ignoreCallExpressionIdentifiers,
440
630
  callback(path2) {
441
631
  if (path2.isStringLiteral() || path2.isTemplateElement()) {
442
- ignoreFlagMap.set(path2, true);
632
+ ignoredPaths.add(path2);
443
633
  }
444
634
  }
445
635
  }
446
636
  );
637
+ const isIgnoredTaggedTemplate = createNameMatcher(options.ignoreTaggedTemplateExpressionIdentifiers, { exact: true });
447
638
  const targetPaths = [];
448
639
  const importDeclarations = /* @__PURE__ */ new Set();
449
640
  const exportDeclarations = /* @__PURE__ */ new Set();
@@ -466,7 +657,7 @@ function analyzeSource(ast, options) {
466
657
  }
467
658
  if (ppp.isTaggedTemplateExpression()) {
468
659
  const tagPath = ppp.get("tag");
469
- if (tagPath.isIdentifier() && regExpTest(options.ignoreTaggedTemplateExpressionIdentifiers ?? [], tagPath.node.name, { exact: true })) {
660
+ if (tagPath.isIdentifier() && isIgnoredTaggedTemplate(tagPath.node.name)) {
470
661
  return;
471
662
  }
472
663
  }
@@ -477,59 +668,7 @@ function analyzeSource(ast, options) {
477
668
  CallExpression: {
478
669
  enter(p) {
479
670
  if (isEvalPath(p)) {
480
- p.traverse({
481
- StringLiteral: {
482
- enter(path2) {
483
- const { code } = jsHandler(path2.node.value, {
484
- ...options,
485
- needEscaped: false,
486
- generateMap: false
487
- });
488
- if (code) {
489
- const node = path2.node;
490
- if (typeof node.start === "number" && typeof node.end === "number") {
491
- const start = node.start + 1;
492
- const end = node.end - 1;
493
- if (start < end && path2.node.value !== code) {
494
- jsTokenUpdater.addToken(
495
- {
496
- start,
497
- end,
498
- value: jsStringEscape2(code),
499
- path: path2
500
- }
501
- );
502
- }
503
- }
504
- }
505
- }
506
- },
507
- TemplateElement: {
508
- enter(path2) {
509
- const { code } = jsHandler(path2.node.value.raw, {
510
- ...options,
511
- generateMap: false
512
- });
513
- if (code) {
514
- const node = path2.node;
515
- if (typeof node.start === "number" && typeof node.end === "number") {
516
- const start = node.start;
517
- const end = node.end;
518
- if (start < end && path2.node.value.raw !== code) {
519
- jsTokenUpdater.addToken(
520
- {
521
- start,
522
- end,
523
- value: code,
524
- path: path2
525
- }
526
- );
527
- }
528
- }
529
- }
530
- }
531
- }
532
- });
671
+ walkEvalExpression(p, options, jsTokenUpdater);
533
672
  return;
534
673
  }
535
674
  walker.walkCallExpression(p);
@@ -553,46 +692,30 @@ function analyzeSource(ast, options) {
553
692
  ast,
554
693
  targetPaths,
555
694
  importDeclarations,
556
- exportDeclarations
557
- // jsTokens,
695
+ exportDeclarations,
696
+ ignoredPaths
558
697
  };
559
698
  }
560
699
  function processUpdatedSource(rawSource, options, analysis) {
561
700
  const ms = new MagicString(rawSource);
562
- const { targetPaths, jsTokenUpdater } = analysis;
563
- const tokens = targetPaths.filter(
564
- (x) => {
565
- return !ignoreFlagMap.get(x);
701
+ const { targetPaths, jsTokenUpdater, ignoredPaths } = analysis;
702
+ const replacementTokens = [];
703
+ for (const path2 of targetPaths) {
704
+ if (ignoredPaths.has(path2)) {
705
+ continue;
566
706
  }
567
- ).map(
568
- (p) => {
569
- if (p.isStringLiteral()) {
570
- return replaceHandleValue(
571
- p,
572
- {
573
- ...options,
574
- needEscaped: options.needEscaped ?? true
575
- }
576
- );
577
- } else if (p.isTemplateElement()) {
578
- return replaceHandleValue(
579
- p,
580
- {
581
- ...options,
582
- needEscaped: false
583
- }
584
- );
707
+ const token = replaceHandleValue(
708
+ path2,
709
+ {
710
+ ...options,
711
+ needEscaped: path2.isStringLiteral() ? options.needEscaped ?? true : false
585
712
  }
586
- return void 0;
587
- }
588
- ).filter(Boolean);
589
- jsTokenUpdater.push(
590
- ...tokens
591
- ).filter(
592
- (x) => {
593
- return !ignoreFlagMap.get(x.path);
713
+ );
714
+ if (token) {
715
+ replacementTokens.push(token);
594
716
  }
595
- ).updateMagicString(ms);
717
+ }
718
+ jsTokenUpdater.push(...replacementTokens).filter((token) => !ignoredPaths.has(token.path)).updateMagicString(ms);
596
719
  return ms;
597
720
  }
598
721
  function jsHandler(rawSource, options) {
@@ -629,69 +752,69 @@ function createJsHandler(options) {
629
752
  uniAppX
630
753
  } = options;
631
754
  function handler(rawSource, classNameSet, options2) {
632
- const opts = defuOverrideArray(options2, {
633
- classNameSet,
634
- escapeMap,
635
- arbitraryValues,
636
- mangleContext,
637
- jsPreserveClass,
638
- generateMap,
639
- babelParserOptions,
640
- ignoreCallExpressionIdentifiers,
641
- ignoreTaggedTemplateExpressionIdentifiers,
642
- uniAppX
643
- });
644
- return jsHandler(rawSource, opts);
755
+ const overrideOptions = options2 ?? {};
756
+ const resolvedOptions = defuOverrideArray(
757
+ {
758
+ ...overrideOptions,
759
+ classNameSet
760
+ },
761
+ {
762
+ classNameSet,
763
+ escapeMap,
764
+ arbitraryValues,
765
+ mangleContext,
766
+ jsPreserveClass,
767
+ generateMap,
768
+ babelParserOptions,
769
+ ignoreCallExpressionIdentifiers,
770
+ ignoreTaggedTemplateExpressionIdentifiers,
771
+ uniAppX
772
+ }
773
+ );
774
+ return jsHandler(rawSource, resolvedOptions);
645
775
  }
646
776
  return handler;
647
777
  }
648
778
 
649
- // src/tailwindcss/index.ts
650
- import { getPackageInfoSync } from "local-pkg";
651
-
652
- // src/tailwindcss/patcher.ts
653
- import path from "path";
654
- import process from "process";
655
- import { defuOverrideArray as defuOverrideArray2 } from "@weapp-tailwindcss/shared";
656
- import { TailwindcssPatcher } from "tailwindcss-patch";
657
- function createTailwindcssPatcher(options) {
658
- const { basedir, cacheDir, supportCustomLengthUnitsPatch, tailwindcss, tailwindcssPatcherOptions } = options || {};
659
- const cache = {};
660
- if (cacheDir) {
661
- if (path.isAbsolute(cacheDir)) {
662
- cache.dir = cacheDir;
663
- } else if (basedir) {
664
- cache.dir = path.resolve(basedir, cacheDir);
665
- } else {
666
- cache.dir = path.resolve(process.cwd(), cacheDir);
667
- }
668
- }
669
- return new TailwindcssPatcher(defuOverrideArray2(
670
- tailwindcssPatcherOptions,
671
- {
672
- cache,
673
- patch: {
674
- basedir,
675
- applyPatches: {
676
- exportContext: true,
677
- extendLengthUnits: supportCustomLengthUnitsPatch
678
- },
679
- tailwindcss,
680
- resolve: {
681
- paths: [
682
- import.meta.url
683
- ]
684
- }
685
- }
686
- }
687
- ));
688
- }
689
-
690
779
  // src/wxml/utils.ts
691
780
  import * as t from "@babel/types";
692
781
  import { Parser } from "htmlparser2";
693
782
  import MagicString2 from "magic-string";
694
783
 
784
+ // src/wxml/whitespace.ts
785
+ var WHITESPACE_CODES = /* @__PURE__ */ new Set([
786
+ 9,
787
+ // \t
788
+ 10,
789
+ // \n
790
+ 11,
791
+ // \v
792
+ 12,
793
+ // \f
794
+ 13,
795
+ // \r
796
+ 32,
797
+ // space
798
+ 160,
799
+ // \u00A0
800
+ 65279
801
+ // \uFEFF
802
+ ]);
803
+ function isWhitespace(char) {
804
+ if (char.length === 0) {
805
+ return false;
806
+ }
807
+ return WHITESPACE_CODES.has(char.charCodeAt(0));
808
+ }
809
+ function isAllWhitespace(value) {
810
+ for (let i = 0; i < value.length; i++) {
811
+ if (!WHITESPACE_CODES.has(value.charCodeAt(i))) {
812
+ return false;
813
+ }
814
+ }
815
+ return true;
816
+ }
817
+
695
818
  // src/wxml/Tokenizer.ts
696
819
  var Tokenizer = class {
697
820
  constructor() {
@@ -700,7 +823,7 @@ var Tokenizer = class {
700
823
  processChar(char, index) {
701
824
  switch (this.state) {
702
825
  case 0 /* START */:
703
- if (char === " ") {
826
+ if (isWhitespace(char)) {
704
827
  } else if (char === "{") {
705
828
  this.state = 2 /* OPEN_BRACE */;
706
829
  this.bufferStartIndex = index;
@@ -714,7 +837,7 @@ var Tokenizer = class {
714
837
  }
715
838
  break;
716
839
  case 1 /* TEXT */:
717
- if (char === " ") {
840
+ if (isWhitespace(char)) {
718
841
  this.tokens.push({ start: this.bufferStartIndex, end: index, value: this.buffer, expressions: this.expressions });
719
842
  this.buffer = "";
720
843
  this.expressions = [];
@@ -756,7 +879,7 @@ var Tokenizer = class {
756
879
  }
757
880
  break;
758
881
  case 4 /* BRACES_COMPLETE */:
759
- if (char === " ") {
882
+ if (isWhitespace(char)) {
760
883
  this.tokens.push({
761
884
  start: this.bufferStartIndex,
762
885
  end: index,
@@ -781,6 +904,7 @@ var Tokenizer = class {
781
904
  }
782
905
  }
783
906
  run(input) {
907
+ this.reset();
784
908
  for (let i = 0; i < input.length; i++) {
785
909
  const char = input[i];
786
910
  this.processChar(char, i);
@@ -793,7 +917,9 @@ var Tokenizer = class {
793
917
  expressions: this.expressions
794
918
  });
795
919
  }
796
- return this.tokens;
920
+ const tokens = this.tokens;
921
+ this.reset();
922
+ return tokens;
797
923
  }
798
924
  reset() {
799
925
  this.state = 0 /* START */;
@@ -848,7 +974,19 @@ function generateCode(match, options = {}) {
848
974
  }
849
975
  }
850
976
  function handleEachClassFragment(ms, tokens, options = {}) {
977
+ let previousEnd = 0;
851
978
  for (const token of tokens) {
979
+ if (token.start > previousEnd) {
980
+ const gap = ms.slice(previousEnd, token.start);
981
+ if (isAllWhitespace(gap)) {
982
+ ms.update(previousEnd, token.start, replaceWxml(gap, {
983
+ keepEOL: false,
984
+ escapeMap: options.escapeMap,
985
+ mangleContext: options.mangleContext,
986
+ ignoreHead: true
987
+ }));
988
+ }
989
+ }
852
990
  let p = token.start;
853
991
  if (token.expressions.length > 0) {
854
992
  for (const exp of token.expressions) {
@@ -882,6 +1020,21 @@ function handleEachClassFragment(ms, tokens, options = {}) {
882
1020
  ignoreHead: false
883
1021
  }));
884
1022
  }
1023
+ previousEnd = token.end;
1024
+ }
1025
+ if (tokens.length > 0) {
1026
+ const lastToken = tokens[tokens.length - 1];
1027
+ if (lastToken.end < ms.original.length) {
1028
+ const gap = ms.slice(lastToken.end, ms.original.length);
1029
+ if (isAllWhitespace(gap)) {
1030
+ ms.update(lastToken.end, ms.original.length, replaceWxml(gap, {
1031
+ keepEOL: false,
1032
+ escapeMap: options.escapeMap,
1033
+ mangleContext: options.mangleContext,
1034
+ ignoreHead: true
1035
+ }));
1036
+ }
1037
+ }
885
1038
  }
886
1039
  }
887
1040
  function templateReplacer(original, options = {}) {
@@ -897,10 +1050,15 @@ function regTest(reg, str) {
897
1050
  }
898
1051
  function isPropsMatch(props, attr) {
899
1052
  if (Array.isArray(props)) {
1053
+ let lowerAttr;
900
1054
  for (const prop of props) {
901
- const res = typeof prop === "string" ? prop.toLowerCase() === attr.toLowerCase() : regTest(prop, attr);
902
- if (res) {
903
- return res;
1055
+ if (typeof prop === "string") {
1056
+ lowerAttr ?? (lowerAttr = attr.toLowerCase());
1057
+ if (prop.toLowerCase() === lowerAttr) {
1058
+ return true;
1059
+ }
1060
+ } else if (regTest(prop, attr)) {
1061
+ return true;
904
1062
  }
905
1063
  }
906
1064
  return false;
@@ -918,6 +1076,23 @@ async function customTemplateHandler(rawSource, options) {
918
1076
  runtimeSet,
919
1077
  jsHandler: jsHandler2
920
1078
  } = options ?? {};
1079
+ const wildcardAttributeRules = [];
1080
+ const tagAttributeRuleMap = /* @__PURE__ */ new Map();
1081
+ const regexpAttributeRules = [];
1082
+ for (const [selector, props] of customAttributesEntities) {
1083
+ if (selector === "*") {
1084
+ wildcardAttributeRules.push(props);
1085
+ } else if (typeof selector === "string") {
1086
+ const list = tagAttributeRuleMap.get(selector);
1087
+ if (list) {
1088
+ list.push(props);
1089
+ } else {
1090
+ tagAttributeRuleMap.set(selector, [props]);
1091
+ }
1092
+ } else {
1093
+ regexpAttributeRules.push([selector, props]);
1094
+ }
1095
+ }
921
1096
  const s = new MagicString2(rawSource);
922
1097
  let tag = "";
923
1098
  const wxsArray = [];
@@ -928,7 +1103,13 @@ async function customTemplateHandler(rawSource, options) {
928
1103
  },
929
1104
  onattribute(name, value, quote) {
930
1105
  if (value) {
931
- let update2 = function() {
1106
+ const lowerName = name.toLowerCase();
1107
+ let updated = false;
1108
+ const update = () => {
1109
+ if (updated) {
1110
+ return;
1111
+ }
1112
+ updated = true;
932
1113
  s.update(
933
1114
  parser.startIndex + name.length + 2,
934
1115
  // !important
@@ -942,21 +1123,34 @@ async function customTemplateHandler(rawSource, options) {
942
1123
  })
943
1124
  );
944
1125
  };
945
- var update = update2;
946
- if (!disabledDefaultTemplateHandler && ["class", "hover-class", "virtualhostclass"].includes(name.toLocaleLowerCase())) {
947
- update2();
1126
+ if (!disabledDefaultTemplateHandler && (lowerName === "class" || lowerName === "hover-class" || lowerName === "virtualhostclass")) {
1127
+ update();
948
1128
  }
949
- for (const [t2, props] of customAttributesEntities) {
950
- if (t2 === "*") {
1129
+ if (!updated) {
1130
+ for (const props of wildcardAttributeRules) {
951
1131
  if (isPropsMatch(props, name)) {
952
- update2();
1132
+ update();
1133
+ break;
1134
+ }
1135
+ }
1136
+ }
1137
+ if (!updated) {
1138
+ const tagRules = tagAttributeRuleMap.get(tag);
1139
+ if (tagRules) {
1140
+ for (const props of tagRules) {
1141
+ if (isPropsMatch(props, name)) {
1142
+ update();
1143
+ break;
1144
+ }
953
1145
  }
954
- } else if (typeof t2 === "string") {
955
- if (t2 === tag && isPropsMatch(props, name)) {
956
- update2();
1146
+ }
1147
+ }
1148
+ if (!updated) {
1149
+ for (const [selector, props] of regexpAttributeRules) {
1150
+ if (regTest(selector, tag) && isPropsMatch(props, name)) {
1151
+ update();
1152
+ break;
957
1153
  }
958
- } else if (regTest(t2, tag) && isPropsMatch(props, name)) {
959
- update2();
960
1154
  }
961
1155
  }
962
1156
  }
@@ -992,77 +1186,31 @@ function createTemplateHandler(options = {}) {
992
1186
  };
993
1187
  }
994
1188
 
995
- // src/context/index.ts
996
- var loggerLevelMap = {
997
- error: 0,
998
- warn: 1,
999
- info: 3,
1000
- silent: -999
1001
- };
1002
- function getCompilerContext(opts) {
1003
- const ctx = defuOverrideArray(
1004
- opts,
1005
- getDefaultOptions(),
1006
- {}
1007
- );
1008
- ctx.escapeMap = ctx.customReplaceDictionary;
1189
+ // src/context/handlers.ts
1190
+ function createHandlersFromContext(ctx, mangleContext, customAttributesEntities, cssCalcOptions) {
1009
1191
  const {
1010
1192
  cssPreflight,
1011
1193
  customRuleCallback,
1012
1194
  cssPreflightRange,
1013
- customAttributes,
1014
- supportCustomLengthUnitsPatch,
1015
- arbitraryValues,
1195
+ escapeMap,
1016
1196
  cssChildCombinatorReplaceValue,
1017
- inlineWxs,
1018
1197
  injectAdditionalCssVarScope,
1019
- jsPreserveClass,
1020
- disabledDefaultTemplateHandler,
1021
1198
  cssSelectorReplacement,
1022
1199
  rem2rpx,
1023
- cache,
1024
- babelParserOptions,
1025
1200
  postcssOptions,
1026
1201
  cssRemoveProperty,
1027
1202
  cssRemoveHoverPseudoClass,
1028
- escapeMap,
1029
- mangle,
1030
- tailwindcssBasedir,
1031
- appType,
1032
- ignoreCallExpressionIdentifiers,
1033
- ignoreTaggedTemplateExpressionIdentifiers,
1034
1203
  cssPresetEnv,
1035
- tailwindcss,
1036
- tailwindcssPatcherOptions,
1037
1204
  uniAppX,
1038
- cssEntries,
1039
- cssCalc,
1040
1205
  px2rpx,
1041
- logLevel
1206
+ arbitraryValues,
1207
+ jsPreserveClass,
1208
+ babelParserOptions,
1209
+ ignoreCallExpressionIdentifiers,
1210
+ ignoreTaggedTemplateExpressionIdentifiers,
1211
+ inlineWxs,
1212
+ disabledDefaultTemplateHandler
1042
1213
  } = ctx;
1043
- logger.level = loggerLevelMap[logLevel] ?? loggerLevelMap.info;
1044
- const twPatcher = createTailwindcssPatcher(
1045
- {
1046
- basedir: tailwindcssBasedir,
1047
- cacheDir: appType === "mpx" ? "node_modules/tailwindcss-patch/.cache" : void 0,
1048
- supportCustomLengthUnitsPatch: supportCustomLengthUnitsPatch ?? true,
1049
- tailwindcss: defuOverrideArray(
1050
- tailwindcss,
1051
- {
1052
- v4: {
1053
- base: tailwindcssBasedir,
1054
- cssEntries
1055
- }
1056
- }
1057
- ),
1058
- tailwindcssPatcherOptions
1059
- }
1060
- );
1061
- logger.success(`\u5F53\u524D\u4F7F\u7528 ${pc.cyanBright("Tailwind CSS")} \u7248\u672C\u4E3A: ${pc.underline(pc.bold(pc.green(twPatcher.packageInfo.version)))}`);
1062
- const cssCalcOptions = cssCalc ?? twPatcher.majorVersion === 4;
1063
- const customAttributesEntities = isMap(customAttributes) ? [...customAttributes.entries()] : Object.entries(customAttributes);
1064
- const { initMangle, mangleContext, setMangleRuntimeSet } = useMangleStore();
1065
- initMangle(mangle);
1066
1214
  const styleHandler = createStyleHandler({
1067
1215
  cssPreflight,
1068
1216
  customRuleCallback,
@@ -1100,11 +1248,121 @@ function getCompilerContext(opts) {
1100
1248
  jsHandler: jsHandler2,
1101
1249
  disabledDefaultTemplateHandler
1102
1250
  });
1251
+ return {
1252
+ styleHandler,
1253
+ jsHandler: jsHandler2,
1254
+ templateHandler
1255
+ };
1256
+ }
1257
+
1258
+ // src/context/logger.ts
1259
+ import { logger } from "@weapp-tailwindcss/logger";
1260
+ var loggerLevelMap = {
1261
+ error: 0,
1262
+ warn: 1,
1263
+ info: 3,
1264
+ silent: -999
1265
+ };
1266
+ function applyLoggerLevel(logLevel) {
1267
+ logger.level = loggerLevelMap[logLevel ?? "info"] ?? loggerLevelMap.info;
1268
+ }
1269
+
1270
+ // src/tailwindcss/index.ts
1271
+ import { getPackageInfoSync } from "local-pkg";
1272
+
1273
+ // src/tailwindcss/patcher.ts
1274
+ import path from "path";
1275
+ import process from "process";
1276
+ import { defuOverrideArray as defuOverrideArray2 } from "@weapp-tailwindcss/shared";
1277
+ import { TailwindcssPatcher } from "tailwindcss-patch";
1278
+ function createTailwindcssPatcher(options) {
1279
+ const { basedir, cacheDir, supportCustomLengthUnitsPatch, tailwindcss, tailwindcssPatcherOptions } = options || {};
1280
+ const cache = {};
1281
+ if (cacheDir) {
1282
+ if (path.isAbsolute(cacheDir)) {
1283
+ cache.dir = cacheDir;
1284
+ } else if (basedir) {
1285
+ cache.dir = path.resolve(basedir, cacheDir);
1286
+ } else {
1287
+ cache.dir = path.resolve(process.cwd(), cacheDir);
1288
+ }
1289
+ }
1290
+ return new TailwindcssPatcher(defuOverrideArray2(
1291
+ tailwindcssPatcherOptions,
1292
+ {
1293
+ cache,
1294
+ patch: {
1295
+ basedir,
1296
+ applyPatches: {
1297
+ exportContext: true,
1298
+ extendLengthUnits: supportCustomLengthUnitsPatch
1299
+ },
1300
+ tailwindcss,
1301
+ resolve: {
1302
+ paths: [
1303
+ import.meta.url
1304
+ ]
1305
+ }
1306
+ }
1307
+ }
1308
+ ));
1309
+ }
1310
+
1311
+ // src/context/tailwindcss.ts
1312
+ function createTailwindcssPatcherFromContext(ctx) {
1313
+ const {
1314
+ tailwindcssBasedir,
1315
+ supportCustomLengthUnitsPatch,
1316
+ tailwindcss,
1317
+ tailwindcssPatcherOptions,
1318
+ cssEntries,
1319
+ appType
1320
+ } = ctx;
1321
+ return createTailwindcssPatcher(
1322
+ {
1323
+ basedir: tailwindcssBasedir,
1324
+ cacheDir: appType === "mpx" ? "node_modules/tailwindcss-patch/.cache" : void 0,
1325
+ supportCustomLengthUnitsPatch: supportCustomLengthUnitsPatch ?? true,
1326
+ tailwindcss: defuOverrideArray(
1327
+ tailwindcss,
1328
+ {
1329
+ v4: {
1330
+ base: tailwindcssBasedir,
1331
+ cssEntries
1332
+ }
1333
+ }
1334
+ ),
1335
+ tailwindcssPatcherOptions
1336
+ }
1337
+ );
1338
+ }
1339
+
1340
+ // src/context/index.ts
1341
+ function getCompilerContext(opts) {
1342
+ const ctx = defuOverrideArray(
1343
+ opts,
1344
+ getDefaultOptions(),
1345
+ {}
1346
+ );
1347
+ ctx.escapeMap = ctx.customReplaceDictionary;
1348
+ applyLoggerLevel(ctx.logLevel);
1349
+ const twPatcher = createTailwindcssPatcherFromContext(ctx);
1350
+ logger2.success(`\u5F53\u524D\u4F7F\u7528 ${pc.cyanBright("Tailwind CSS")} \u7248\u672C\u4E3A: ${pc.underline(pc.bold(pc.green(twPatcher.packageInfo.version)))}`);
1351
+ const cssCalcOptions = ctx.cssCalc ?? twPatcher.majorVersion === 4;
1352
+ const customAttributesEntities = toCustomAttributesEntities(ctx.customAttributes);
1353
+ const { initMangle, mangleContext, setMangleRuntimeSet } = useMangleStore();
1354
+ initMangle(ctx.mangle);
1355
+ const { styleHandler, jsHandler: jsHandler2, templateHandler } = createHandlersFromContext(
1356
+ ctx,
1357
+ mangleContext,
1358
+ customAttributesEntities,
1359
+ cssCalcOptions
1360
+ );
1103
1361
  ctx.styleHandler = styleHandler;
1104
1362
  ctx.jsHandler = jsHandler2;
1105
1363
  ctx.templateHandler = templateHandler;
1106
1364
  ctx.setMangleRuntimeSet = setMangleRuntimeSet;
1107
- ctx.cache = initializeCache(cache);
1365
+ ctx.cache = initializeCache(ctx.cache);
1108
1366
  ctx.twPatcher = twPatcher;
1109
1367
  return ctx;
1110
1368
  }