tailwindcss-patch 9.4.3 → 9.5.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 (36) hide show
  1. package/dist/{cli-BztQHMRp.js → cli-CGyUnvFc.js} +3 -2
  2. package/dist/{cli-D0jXMGXf.mjs → cli-DRfALTSo.mjs} +1 -1
  3. package/dist/cli.js +2 -2
  4. package/dist/cli.mjs +2 -2
  5. package/dist/commands/cli-runtime.d.mts +1 -1
  6. package/dist/commands/cli-runtime.d.ts +1 -1
  7. package/dist/commands/cli-runtime.js +2 -2
  8. package/dist/commands/cli-runtime.mjs +2 -2
  9. package/dist/{dist-DDcbvOwe.js → dist-DlC5vuI2.js} +1 -1
  10. package/dist/index.d.mts +7 -149
  11. package/dist/index.d.ts +8 -150
  12. package/dist/index.js +294 -521
  13. package/dist/index.mjs +6 -471
  14. package/dist/{validate-BuqRodYI.d.ts → validate-B5-08lrU.d.ts} +7 -251
  15. package/dist/{validate-oAkURzUC.d.mts → validate-CgrG4aAY.d.mts} +7 -251
  16. package/dist/{validate-Bug_WYcU.mjs → validate-Q00Ccqht.mjs} +8 -1405
  17. package/dist/{validate-DbuKewV-.js → validate-XiYmTZcd.js} +82 -1708
  18. package/package.json +8 -10
  19. package/src/api/tailwindcss-patcher.ts +8 -5
  20. package/src/extraction/candidate-extractor.ts +17 -701
  21. package/src/extraction/split-candidate-tokens.ts +5 -101
  22. package/src/options/types.ts +1 -2
  23. package/src/style-candidates.ts +5 -35
  24. package/src/style-generator.ts +11 -80
  25. package/src/types.ts +21 -95
  26. package/src/v3/index.ts +2 -2
  27. package/src/v4/index.ts +104 -28
  28. package/src/v3/style-generator.ts +0 -384
  29. package/src/v4/bare-arbitrary-values.ts +0 -545
  30. package/src/v4/candidates.ts +0 -316
  31. package/src/v4/engine.ts +0 -112
  32. package/src/v4/node-adapter.ts +0 -207
  33. package/src/v4/source-scan.ts +0 -432
  34. package/src/v4/source.ts +0 -235
  35. package/src/v4/style-generator.ts +0 -44
  36. package/src/v4/types.ts +0 -103
@@ -1,545 +0,0 @@
1
- export interface BareArbitraryValueOptions {
2
- /**
3
- * 允许作为无方括号任意值的单位列表。
4
- */
5
- units?: string[]
6
- }
7
-
8
- export interface BareArbitraryValueResolveResult {
9
- candidate: string
10
- canonicalCandidate: string
11
- }
12
-
13
- export interface BareArbitraryValueSourceCandidate {
14
- rawCandidate: string
15
- start: number
16
- end: number
17
- }
18
-
19
- const DEFAULT_BARE_ARBITRARY_VALUE_UNITS = [
20
- '%',
21
- 'px',
22
- 'rpx',
23
- 'rem',
24
- 'em',
25
- 'vw',
26
- 'vh',
27
- 'vmin',
28
- 'vmax',
29
- 'dvw',
30
- 'dvh',
31
- 'svw',
32
- 'svh',
33
- 'lvw',
34
- 'lvh',
35
- 'ch',
36
- 'ex',
37
- 'lh',
38
- 'rlh',
39
- 'fr',
40
- 'deg',
41
- 'rad',
42
- 'turn',
43
- 's',
44
- 'ms',
45
- ]
46
-
47
- const NUMBER_RE = /^-?(?:\d+|\d*\.\d+)$/
48
- const FUNCTION_VALUE_RE = /^[a-z_-][\w-]*\(/i
49
- const HEX_ESCAPE_RE = /^[\da-f]$/i
50
- const ASPECT_RATIO_RE = /^\d+\/\d+$/
51
- const ESCAPED_WHITESPACE_RE = /\\[nrt]/g
52
-
53
- function splitVariantPrefix(candidate: string) {
54
- let depth = 0
55
- let quote: string | undefined
56
- let lastSeparator = -1
57
-
58
- for (let index = 0; index < candidate.length; index++) {
59
- const character = candidate[index]
60
- if (character === '\\') {
61
- index++
62
- continue
63
- }
64
-
65
- if (quote) {
66
- if (character === quote) {
67
- quote = undefined
68
- }
69
- continue
70
- }
71
-
72
- if (character === '"' || character === '\'') {
73
- quote = character
74
- continue
75
- }
76
-
77
- if (character === '[' || character === '(' || character === '{') {
78
- depth++
79
- continue
80
- }
81
-
82
- if (character === ']' || character === ')' || character === '}') {
83
- depth = Math.max(0, depth - 1)
84
- continue
85
- }
86
-
87
- if (depth === 0 && character === ':') {
88
- lastSeparator = index
89
- }
90
- }
91
-
92
- if (lastSeparator === -1) {
93
- return {
94
- prefix: '',
95
- body: candidate,
96
- }
97
- }
98
-
99
- return {
100
- prefix: candidate.slice(0, lastSeparator + 1),
101
- body: candidate.slice(lastSeparator + 1),
102
- }
103
- }
104
-
105
- function isBalancedFunctionValue(value: string) {
106
- let depth = 0
107
- let quote: string | undefined
108
-
109
- for (let index = 0; index < value.length; index++) {
110
- const character = value[index]
111
-
112
- if (character === '\\') {
113
- index++
114
- continue
115
- }
116
-
117
- if (quote) {
118
- if (character === quote) {
119
- quote = undefined
120
- }
121
- continue
122
- }
123
-
124
- if (character === '"' || character === '\'') {
125
- quote = character
126
- continue
127
- }
128
-
129
- if (character === '(') {
130
- depth++
131
- continue
132
- }
133
-
134
- if (character === ')') {
135
- depth--
136
- if (depth < 0) {
137
- return false
138
- }
139
- }
140
- }
141
-
142
- return depth === 0 && quote === undefined
143
- }
144
-
145
- function isEscapedAt(value: string, index: number) {
146
- let slashCount = 0
147
- for (let slashIndex = index - 1; slashIndex >= 0 && value[slashIndex] === '\\'; slashIndex--) {
148
- slashCount++
149
- }
150
- return slashCount % 2 === 1
151
- }
152
-
153
- function isBalancedBareArbitraryBody(value: string) {
154
- let depth = 0
155
- let quote: string | undefined
156
-
157
- for (let index = 0; index < value.length; index++) {
158
- const character = value[index]
159
-
160
- if (isEscapedAt(value, index)) {
161
- continue
162
- }
163
-
164
- if (quote) {
165
- if (character === quote) {
166
- quote = undefined
167
- }
168
- continue
169
- }
170
-
171
- if (character === '"' || character === '\'') {
172
- quote = character
173
- continue
174
- }
175
-
176
- if (character === '(' || character === '{') {
177
- depth++
178
- continue
179
- }
180
-
181
- if (character === ')' || character === '}') {
182
- depth--
183
- if (depth < 0) {
184
- return false
185
- }
186
- }
187
- }
188
-
189
- return depth === 0 && quote === undefined
190
- }
191
-
192
- function isHexColorValue(value: string) {
193
- return /^#(?:[0-9a-f]{3,4}|[0-9a-f]{6,8})$/i.test(value)
194
- }
195
-
196
- function isQuotedValue(value: string) {
197
- const quote = value[0]
198
- if ((quote !== '"' && quote !== '\'') || value[value.length - 1] !== quote) {
199
- return false
200
- }
201
-
202
- let escaped = false
203
- for (let index = 1; index < value.length - 1; index++) {
204
- const character = value[index]
205
- if (escaped) {
206
- escaped = false
207
- continue
208
- }
209
- if (character === '\\') {
210
- escaped = true
211
- }
212
- }
213
-
214
- return !escaped
215
- }
216
-
217
- function normalizeBareArbitraryValueOptions(options: boolean | BareArbitraryValueOptions | undefined) {
218
- if (options === false || options === undefined || options === null) {
219
- return
220
- }
221
-
222
- const units = options === true ? DEFAULT_BARE_ARBITRARY_VALUE_UNITS : options.units ?? DEFAULT_BARE_ARBITRARY_VALUE_UNITS
223
- const normalizedUnits = [...new Set(units.filter(unit => typeof unit === 'string' && unit.length > 0))]
224
- if (normalizedUnits.length === 0) {
225
- return
226
- }
227
- return {
228
- units: normalizedUnits.sort((a, b) => b.length - a.length),
229
- }
230
- }
231
-
232
- export function isBareArbitraryValuesEnabled(options: boolean | BareArbitraryValueOptions | undefined) {
233
- return normalizeBareArbitraryValueOptions(options) !== undefined
234
- }
235
-
236
- function normalizeEscapedValue(value: string) {
237
- let result = ''
238
- for (let index = 0; index < value.length; index++) {
239
- const character = value[index]
240
- if (character !== '\\') {
241
- result += character
242
- continue
243
- }
244
-
245
- const nextCharacter = value[index + 1]
246
- if (nextCharacter === undefined) {
247
- result += character
248
- continue
249
- }
250
-
251
- if (HEX_ESCAPE_RE.test(nextCharacter)) {
252
- let hex = ''
253
- let nextIndex = index + 1
254
- while (nextIndex < value.length && hex.length < 6) {
255
- const hexCharacter = value[nextIndex]
256
- if (hexCharacter === undefined || !HEX_ESCAPE_RE.test(hexCharacter)) {
257
- break
258
- }
259
- hex += hexCharacter
260
- nextIndex++
261
- }
262
- if (/[\t\n\f\r ]/.test(value[nextIndex] ?? '')) {
263
- nextIndex++
264
- }
265
-
266
- const decoded = String.fromCodePoint(Number.parseInt(hex, 16))
267
- result += decoded === '_' ? '\\_' : decoded
268
- index = nextIndex - 1
269
- continue
270
- }
271
-
272
- result += nextCharacter === '_' ? '\\_' : nextCharacter
273
- index++
274
- }
275
- return result
276
- }
277
-
278
- function resolveValueWithUnit(body: string, units: string[]) {
279
- const value = normalizeEscapedValue(body)
280
- for (const unit of units) {
281
- if (!value.endsWith(unit)) {
282
- continue
283
- }
284
- const numberPart = value.slice(0, -unit.length)
285
- if (NUMBER_RE.test(numberPart)) {
286
- return `${numberPart}${unit}`
287
- }
288
- }
289
- }
290
-
291
- function resolveArbitraryValue(utility: string, body: string, units: string[]) {
292
- const value = normalizeEscapedValue(body)
293
- const withUnit = resolveValueWithUnit(value, units)
294
- if (withUnit) {
295
- return withUnit
296
- }
297
-
298
- if (utility === 'aspect' && ASPECT_RATIO_RE.test(value)) {
299
- return value
300
- }
301
-
302
- if (isHexColorValue(value)) {
303
- return value
304
- }
305
-
306
- if (isQuotedValue(value)) {
307
- return value
308
- }
309
-
310
- if (FUNCTION_VALUE_RE.test(value) && value.endsWith(')') && isBalancedFunctionValue(value)) {
311
- if (utility === 'text' && /^var\(/i.test(value)) {
312
- return `color:${value}`
313
- }
314
- return value
315
- }
316
- }
317
-
318
- function resolveUtilityAndValue(body: string, units: string[]) {
319
- let depth = 0
320
- let quote: string | undefined
321
-
322
- for (let index = body.length - 1; index > 0; index--) {
323
- const character = body[index]
324
-
325
- if (isEscapedAt(body, index)) {
326
- continue
327
- }
328
-
329
- if (quote) {
330
- if (character === quote) {
331
- quote = undefined
332
- }
333
- continue
334
- }
335
-
336
- if (character === '"' || character === '\'') {
337
- quote = character
338
- continue
339
- }
340
-
341
- if (character === ')' || character === '}') {
342
- depth++
343
- continue
344
- }
345
-
346
- if (character === '(' || character === '{') {
347
- depth = Math.max(0, depth - 1)
348
- continue
349
- }
350
-
351
- if (depth > 0 || character !== '-') {
352
- continue
353
- }
354
-
355
- const utility = body.slice(0, index)
356
- const rawValue = body.slice(index + 1)
357
- if (!utility || !rawValue) {
358
- continue
359
- }
360
-
361
- const value = resolveArbitraryValue(utility, rawValue, units)
362
- if (value) {
363
- return {
364
- utility,
365
- value,
366
- }
367
- }
368
- }
369
- }
370
-
371
- export function resolveBareArbitraryValueCandidate(
372
- candidate: string,
373
- options?: boolean | BareArbitraryValueOptions,
374
- ): BareArbitraryValueResolveResult | undefined {
375
- const normalizedOptions = normalizeBareArbitraryValueOptions(options)
376
- if (!normalizedOptions || !candidate || candidate.includes('[') || candidate.includes(']')) {
377
- return
378
- }
379
-
380
- const { prefix, body } = splitVariantPrefix(candidate)
381
- const important = body.startsWith('!') ? '!' : ''
382
- let normalizedBody = important ? body.slice(1) : body
383
- const negative = normalizedBody.startsWith('-') ? '-' : ''
384
- if (negative) {
385
- normalizedBody = normalizedBody.slice(1)
386
- }
387
- if (!isBalancedBareArbitraryBody(normalizedBody)) {
388
- return
389
- }
390
-
391
- const resolved = resolveUtilityAndValue(normalizedBody, normalizedOptions.units)
392
- if (!resolved) {
393
- return
394
- }
395
-
396
- return {
397
- candidate,
398
- canonicalCandidate: `${prefix}${important}${negative}${resolved.utility}-[${resolved.value}]`,
399
- }
400
- }
401
-
402
- function isBareArbitrarySourceSplitter(char: string) {
403
- return /\s/.test(char)
404
- }
405
-
406
- function isQuoteBoundary(content: string, start: number, index: number) {
407
- const tokenPrefix = content.slice(start, index)
408
- return tokenPrefix.length === 0 || !tokenPrefix.endsWith('-')
409
- }
410
-
411
- function trimBareArbitrarySourceToken(token: string, start: number) {
412
- let nextToken = token
413
- let nextStart = start
414
- while (nextToken.length > 0 && /^[<{([]$/.test(nextToken[0]!)) {
415
- nextToken = nextToken.slice(1)
416
- nextStart++
417
- }
418
- while (nextToken.length > 0 && /^[>\],;]$/.test(nextToken[nextToken.length - 1]!)) {
419
- nextToken = nextToken.slice(0, -1)
420
- }
421
- return {
422
- token: nextToken,
423
- start: nextStart,
424
- }
425
- }
426
-
427
- function pushBareArbitrarySourceCandidate(
428
- result: BareArbitraryValueSourceCandidate[],
429
- token: string,
430
- start: number,
431
- options: boolean | BareArbitraryValueOptions | undefined,
432
- ) {
433
- const trimmed = trimBareArbitrarySourceToken(token, start)
434
- if (!trimmed.token || trimmed.token.includes('=') || trimmed.token.includes('[') || trimmed.token.includes(']')) {
435
- return
436
- }
437
- if (!resolveBareArbitraryValueCandidate(trimmed.token, options)) {
438
- return
439
- }
440
- result.push({
441
- rawCandidate: trimmed.token,
442
- start: trimmed.start,
443
- end: trimmed.start + trimmed.token.length,
444
- })
445
- }
446
-
447
- export function extractBareArbitraryValueSourceCandidatesWithPositions(
448
- content: string,
449
- options?: boolean | BareArbitraryValueOptions,
450
- ): BareArbitraryValueSourceCandidate[] {
451
- if (!isBareArbitraryValuesEnabled(options)) {
452
- return []
453
- }
454
-
455
- const normalized = content.includes('\\') ? content.replace(ESCAPED_WHITESPACE_RE, ' ') : content
456
- const result: BareArbitraryValueSourceCandidate[] = []
457
- let depth = 0
458
- let quote: string | undefined
459
- let start = 0
460
-
461
- for (let index = 0; index < normalized.length; index++) {
462
- const char = normalized[index]
463
- if (char === undefined) {
464
- continue
465
- }
466
- if (char === '\\') {
467
- index++
468
- continue
469
- }
470
-
471
- if (quote) {
472
- if (char === quote) {
473
- quote = undefined
474
- }
475
- }
476
- else if ((char === '"' || char === '\'' || char === '`') && !isQuoteBoundary(normalized, start, index)) {
477
- quote = char
478
- }
479
- else if (char === '(' || char === '{' || char === '[') {
480
- depth++
481
- }
482
- else if (char === ')' || char === '}' || char === ']') {
483
- depth = Math.max(0, depth - 1)
484
- }
485
-
486
- if (!isBareArbitrarySourceSplitter(char) && !((char === '"' || char === '\'' || char === '`') && depth === 0 && isQuoteBoundary(normalized, start, index))) {
487
- continue
488
- }
489
-
490
- pushBareArbitrarySourceCandidate(result, normalized.slice(start, index), start, options)
491
- start = index + 1
492
- }
493
-
494
- pushBareArbitrarySourceCandidate(result, normalized.slice(start), start, options)
495
- return result
496
- }
497
-
498
- export function extractBareArbitraryValueSourceCandidates(
499
- content: string,
500
- options?: boolean | BareArbitraryValueOptions,
501
- ) {
502
- return [...new Set(
503
- extractBareArbitraryValueSourceCandidatesWithPositions(content, options)
504
- .map(candidate => candidate.rawCandidate),
505
- )]
506
- }
507
-
508
- // Based on the CSS.escape algorithm, scoped to class selector escaping.
509
- export function escapeCssClassName(value: string) {
510
- let result = ''
511
- for (let index = 0; index < value.length; index++) {
512
- const codeUnit = value.charCodeAt(index)
513
- const character = value.charAt(index)
514
-
515
- if (codeUnit === 0x0000) {
516
- result += '\uFFFD'
517
- continue
518
- }
519
-
520
- if (
521
- (codeUnit >= 0x0001 && codeUnit <= 0x001F)
522
- || codeUnit === 0x007F
523
- || (index === 0 && codeUnit >= 0x0030 && codeUnit <= 0x0039)
524
- || (index === 1 && codeUnit >= 0x0030 && codeUnit <= 0x0039 && value.charCodeAt(0) === 0x002D)
525
- ) {
526
- result += `\\${codeUnit.toString(16)} `
527
- continue
528
- }
529
-
530
- if (
531
- codeUnit >= 0x0080
532
- || codeUnit === 0x002D
533
- || codeUnit === 0x005F
534
- || (codeUnit >= 0x0030 && codeUnit <= 0x0039)
535
- || (codeUnit >= 0x0041 && codeUnit <= 0x005A)
536
- || (codeUnit >= 0x0061 && codeUnit <= 0x007A)
537
- ) {
538
- result += character
539
- continue
540
- }
541
-
542
- result += `\\${character}`
543
- }
544
- return result
545
- }