@@ -2,19 +2,7 @@ import type { Config } from 'tailwindcss'
22import { parseCandidate } from '../../../../tailwindcss/src/candidate'
33import type { DesignSystem } from '../../../../tailwindcss/src/design-system'
44import { printCandidate } from '../candidates'
5-
6- const QUOTES = [ '"' , "'" , '`' ]
7- const LOGICAL_OPERATORS = [ '&&' , '||' , '===' , '==' , '!=' , '!==' , '>' , '>=' , '<' , '<=' ]
8- const CONDITIONAL_TEMPLATE_SYNTAX = [
9- // Vue
10- / v - e l s e - i f = [ ' " ] $ / ,
11- / v - i f = [ ' " ] $ / ,
12- / v - s h o w = [ ' " ] $ / ,
13-
14- // Alpine
15- / x - i f = [ ' " ] $ / ,
16- / x - s h o w = [ ' " ] $ / ,
17- ]
5+ import { isSafeMigration } from '../is-safe-migration'
186
197// In v3 the important modifier `!` sits in front of the utility itself, not
208// before any of the variants. In v4, we want it to be at the end of the utility
@@ -46,63 +34,15 @@ export function important(
4634 // with v3 in that it can read `!` in the front of the utility too, we err
4735 // on the side of caution and only migrate candidates that we are certain
4836 // are inside of a string.
49- if ( location ) {
50- let currentLineBeforeCandidate = ''
51- for ( let i = location . start - 1 ; i >= 0 ; i -- ) {
52- let char = location . contents . at ( i ) !
53- if ( char === '\n' ) {
54- break
55- }
56- currentLineBeforeCandidate = char + currentLineBeforeCandidate
57- }
58- let currentLineAfterCandidate = ''
59- for ( let i = location . end ; i < location . contents . length ; i ++ ) {
60- let char = location . contents . at ( i ) !
61- if ( char === '\n' ) {
62- break
63- }
64- currentLineAfterCandidate += char
65- }
66-
67- // Heuristic 1: Require the candidate to be inside quotes
68- let isQuoteBeforeCandidate = QUOTES . some ( ( quote ) =>
69- currentLineBeforeCandidate . includes ( quote ) ,
70- )
71- let isQuoteAfterCandidate = QUOTES . some ( ( quote ) =>
72- currentLineAfterCandidate . includes ( quote ) ,
73- )
74- if ( ! isQuoteBeforeCandidate || ! isQuoteAfterCandidate ) {
75- continue nextCandidate
76- }
77-
78- // Heuristic 2: Disallow object access immediately following the candidate
79- if ( currentLineAfterCandidate [ 0 ] === '.' ) {
80- continue nextCandidate
81- }
82-
83- // Heuristic 3: Disallow logical operators preceding or following the candidate
84- for ( let operator of LOGICAL_OPERATORS ) {
85- if (
86- currentLineAfterCandidate . trim ( ) . startsWith ( operator ) ||
87- currentLineBeforeCandidate . trim ( ) . endsWith ( operator )
88- ) {
89- continue nextCandidate
90- }
91- }
92-
93- // Heuristic 4: Disallow conditional template syntax
94- for ( let rule of CONDITIONAL_TEMPLATE_SYNTAX ) {
95- if ( rule . test ( currentLineBeforeCandidate ) ) {
96- continue nextCandidate
97- }
98- }
37+ if ( location && ! isSafeMigration ( location ) ) {
38+ continue nextCandidate
9939 }
100-
101- // The printCandidate function will already put the exclamation mark in
102- // the right place, so we just need to mark this candidate as requiring a
103- // migration.
104- return printCandidate ( designSystem , candidate )
10540 }
41+
42+ // The printCandidate function will already put the exclamation mark in the
43+ // right place, so we just need to mark this candidate as requiring a
44+ // migration.
45+ return printCandidate ( designSystem , candidate )
10646 }
10747
10848 return rawCandidate
0 commit comments