@@ -69,12 +69,15 @@ import {
6969} from './lsp/diagnosticsProvider'
7070import { doCodeActions } from 'tailwindcss-language-service/src/codeActions/codeActionProvider'
7171import { getDocumentColors } from 'tailwindcss-language-service/src/documentColorProvider'
72- import { fromRatio , names as namedColors } from '@ctrl/tinycolor'
7372import { debounce } from 'debounce'
7473import { getModuleDependencies } from './util/getModuleDependencies'
7574import assert from 'assert'
7675// import postcssLoadConfig from 'postcss-load-config'
7776import * as parcel from './watcher/index.js'
77+ import { generateRules } from 'tailwindcss-language-service/src/util/jit'
78+ import { getColor } from 'tailwindcss-language-service/src/util/color'
79+ import * as culori from 'culori'
80+ import namedColors from 'color-name'
7881
7982const CONFIG_FILE_GLOB = '{tailwind,tailwind.config}.{js,cjs}'
8083const TRIGGER_CHARACTERS = [
@@ -101,7 +104,7 @@ declare var __non_webpack_require__: typeof require
101104const connection =
102105 process . argv . length <= 2 ? createConnection ( process . stdin , process . stdout ) : createConnection ( )
103106
104- console . log = connection . console . log . bind ( connection . console )
107+ // console.log = connection.console.log.bind(connection.console)
105108console . error = connection . console . error . bind ( connection . console )
106109
107110process . on ( 'unhandledRejection' , ( e : any ) => {
@@ -150,6 +153,15 @@ function first<T>(...options: Array<() => T>): T {
150153 }
151154}
152155
156+ function firstOptional < T > ( ...options : Array < ( ) => T > ) : T | undefined {
157+ for ( let i = 0 ; i < options . length ; i ++ ) {
158+ let option = options [ i ]
159+ try {
160+ return option ( )
161+ } catch ( _ ) { }
162+ }
163+ }
164+
153165interface ProjectService {
154166 state : State
155167 tryInit : ( ) => Promise < void >
@@ -528,8 +540,8 @@ async function createProjectService(
528540 }
529541
530542 if ( semver . gte ( tailwindcssVersion , '1.99.0' ) ) {
531- applyComplexClasses = __non_webpack_require__ (
532- resolveFrom ( tailwindDir , './lib/lib/substituteClassApplyAtRules' )
543+ applyComplexClasses = firstOptional ( ( ) =>
544+ __non_webpack_require__ ( resolveFrom ( tailwindDir , './lib/lib/substituteClassApplyAtRules' ) )
533545 )
534546 } else if ( semver . gte ( tailwindcssVersion , '1.7.0' ) ) {
535547 applyComplexClasses = __non_webpack_require__ (
@@ -551,6 +563,13 @@ async function createProjectService(
551563
552564 try {
553565 let createContext = first (
566+ ( ) => {
567+ let createContextFn = __non_webpack_require__ (
568+ resolveFrom ( configDir , 'tailwindcss/lib/lib/setupContextUtils' )
569+ ) . createContext
570+ assert . strictEqual ( typeof createContextFn , 'function' )
571+ return ( state ) => createContextFn ( state . config )
572+ } ,
554573 ( ) => {
555574 let createContextFn = __non_webpack_require__ (
556575 resolveFrom ( configDir , 'tailwindcss/lib/jit/lib/setupContextUtils' )
@@ -582,17 +601,30 @@ async function createProjectService(
582601
583602 jitModules = {
584603 generateRules : {
585- module : __non_webpack_require__ (
586- resolveFrom ( configDir , 'tailwindcss/lib/jit/lib/generateRules' )
587- ) . generateRules ,
604+ module : first (
605+ ( ) =>
606+ __non_webpack_require__ ( resolveFrom ( configDir , 'tailwindcss/lib/lib/generateRules' ) )
607+ . generateRules ,
608+ ( ) =>
609+ __non_webpack_require__ (
610+ resolveFrom ( configDir , 'tailwindcss/lib/jit/lib/generateRules' )
611+ ) . generateRules
612+ ) ,
588613 } ,
589614 createContext : {
590615 module : createContext ,
591616 } ,
592617 expandApplyAtRules : {
593- module : __non_webpack_require__ (
594- resolveFrom ( configDir , 'tailwindcss/lib/jit/lib/expandApplyAtRules' )
595- ) . default ,
618+ module : first (
619+ ( ) =>
620+ __non_webpack_require__ (
621+ resolveFrom ( configDir , 'tailwindcss/lib/lib/expandApplyAtRules' )
622+ ) . default ,
623+ ( ) =>
624+ __non_webpack_require__ (
625+ resolveFrom ( configDir , 'tailwindcss/lib/jit/lib/expandApplyAtRules' )
626+ ) . default
627+ ) ,
596628 } ,
597629 }
598630 } catch ( _ ) {
@@ -728,6 +760,8 @@ async function createProjectService(
728760 let presetVariants : any [ ] = [ ]
729761 let originalConfig : any
730762
763+ let isV3 = semver . gte ( tailwindcss . version , '2.99.0' )
764+
731765 let hook = new Hook ( fs . realpathSync ( state . configPath ) , ( exports ) => {
732766 originalConfig = klona ( exports )
733767
@@ -736,7 +770,7 @@ async function createProjectService(
736770 separator = ':'
737771 }
738772 dset ( exports , sepLocation , `__TWSEP__${ separator } __TWSEP__` )
739- exports . purge = [ ]
773+ exports [ isV3 ? 'content' : ' purge' ] = [ ]
740774
741775 let mode : any
742776 if ( Array . isArray ( exports . presets ) ) {
@@ -753,7 +787,9 @@ async function createProjectService(
753787 }
754788 delete exports . mode
755789
756- if ( state . modules . jit && mode === 'jit' ) {
790+ let isJit = isV3 || ( state . modules . jit && mode === 'jit' )
791+
792+ if ( isJit ) {
757793 state . jit = true
758794 exports . variants = [ ]
759795
@@ -828,32 +864,42 @@ async function createProjectService(
828864 if ( state . jit ) {
829865 state . jitContext = state . modules . jit . createContext . module ( state )
830866 state . jitContext . tailwindConfig . separator = state . config . separator
867+ if ( state . jitContext . getClassList ) {
868+ state . classList = state . jitContext . getClassList ( ) . map ( ( className ) => {
869+ return [ className , { color : getColor ( state , className ) } ]
870+ } )
871+ }
831872 }
832873
833874 let postcssResult : Result
834- try {
835- postcssResult = await postcss
836- . module ( [
837- // ...state.postcssPlugins.before.map((x) => x()),
838- tailwindcss . module ( state . configPath ) ,
839- // ...state.postcssPlugins.after.map((x) => x()),
840- ] )
841- . process (
842- [
843- semver . gte ( tailwindcss . version , '0.99.0' ) ? 'base' : 'preflight' ,
844- 'components' ,
845- 'utilities' ,
846- ]
847- . map ( ( x ) => `/*__tw_intellisense_layer_${ x } __*/\n@tailwind ${ x } ;` )
848- . join ( '\n' ) ,
849- {
850- from : undefined ,
851- }
852- )
853- } catch ( error ) {
854- throw error
855- } finally {
875+
876+ if ( state . classList ) {
856877 hook . unhook ( )
878+ } else {
879+ try {
880+ postcssResult = await postcss
881+ . module ( [
882+ // ...state.postcssPlugins.before.map((x) => x()),
883+ tailwindcss . module ( state . configPath ) ,
884+ // ...state.postcssPlugins.after.map((x) => x()),
885+ ] )
886+ . process (
887+ [
888+ semver . gte ( tailwindcss . version , '0.99.0' ) ? 'base' : 'preflight' ,
889+ 'components' ,
890+ 'utilities' ,
891+ ]
892+ . map ( ( x ) => `/*__tw_intellisense_layer_${ x } __*/\n@tailwind ${ x } ;` )
893+ . join ( '\n' ) ,
894+ {
895+ from : undefined ,
896+ }
897+ )
898+ } catch ( error ) {
899+ throw error
900+ } finally {
901+ hook . unhook ( )
902+ }
857903 }
858904
859905 if ( state . dependencies ) {
@@ -865,7 +911,9 @@ async function createProjectService(
865911 state . configId = getConfigId ( state . configPath , state . dependencies )
866912
867913 state . plugins = await getPlugins ( originalConfig )
868- state . classNames = ( await extractClassNames ( postcssResult . root ) ) as ClassNames
914+ if ( postcssResult ) {
915+ state . classNames = ( await extractClassNames ( postcssResult . root ) ) as ClassNames
916+ }
869917 state . variants = getVariants ( state )
870918
871919 let screens = dlv ( state . config , 'theme.screens' , dlv ( state . config , 'screens' , { } ) )
@@ -939,16 +987,25 @@ async function createProjectService(
939987 let currentColor = match [ 1 ]
940988
941989 let isNamedColor = colorNames . includes ( currentColor )
942- let color = fromRatio ( {
990+
991+ let color : culori . RgbColor = {
992+ mode : 'rgb' ,
943993 r : params . color . red ,
944994 g : params . color . green ,
945995 b : params . color . blue ,
946- a : params . color . alpha ,
947- } )
996+ alpha : params . color . alpha ,
997+ }
998+
999+ let hexValue = culori . formatHex8 ( color )
1000+
1001+ if ( ! isNamedColor && ( currentColor . length === 4 || currentColor . length === 5 ) ) {
1002+ let [ , ...chars ] =
1003+ hexValue . match ( / ^ # ( [ a - f \d ] ) \1( [ a - f \d ] ) \2( [ a - f \d ] ) \3(?: ( [ a - f \d ] ) \4) ? $ / i) ?? [ ]
1004+ if ( chars . length ) {
1005+ hexValue = `#${ chars . filter ( Boolean ) . join ( '' ) } `
1006+ }
1007+ }
9481008
949- let hexValue = color . toHex8String (
950- ! isNamedColor && ( currentColor . length === 4 || currentColor . length === 5 )
951- )
9521009 if ( hexValue . length === 5 ) {
9531010 hexValue = hexValue . replace ( / f $ / , '' )
9541011 } else if ( hexValue . length === 9 ) {
@@ -959,8 +1016,12 @@ async function createProjectService(
9591016
9601017 return [
9611018 hexValue ,
962- color . toRgbString ( ) . replace ( / / g, '' ) ,
963- color . toHslString ( ) . replace ( / / g, '' ) ,
1019+ culori . formatRgb ( color ) . replace ( / / g, '' ) ,
1020+ culori
1021+ . formatHsl ( color )
1022+ . replace ( / / g, '' )
1023+ // round numbers
1024+ . replace ( / \d + \. \d + ( % ? ) / g, ( value , suffix ) => `${ Math . round ( parseFloat ( value ) ) } ${ suffix } ` ) ,
9641025 ] . map ( ( value ) => ( { label : `${ prefix } -[${ value } ]` } ) )
9651026 } ,
9661027 }
0 commit comments