Skip to content

Commit 0ef371e

Browse files
committed
Refactor
Refactor
1 parent 712b5ff commit 0ef371e

File tree

2 files changed

+43
-9
lines changed

2 files changed

+43
-9
lines changed

packages/tailwindcss-language-service/src/util/color.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ const colorRegex = new RegExp(
5656
'gi',
5757
)
5858

59-
function getColorsInString(str: string): (culori.Color | KeywordColor)[] {
59+
function getColorsInString(state: State, str: string): (culori.Color | KeywordColor)[] {
6060
if (/(?:box|drop)-shadow/.test(str)) return []
6161

6262
function toColor(match: RegExpMatchArray) {
@@ -73,6 +73,7 @@ function getColorsInString(str: string): (culori.Color | KeywordColor)[] {
7373
}
7474

7575
function getColorFromDecls(
76+
state: State,
7677
decls: Record<string, string | string[]>,
7778
): culori.Color | KeywordColor | null {
7879
let props = Object.keys(decls).filter((prop) => {
@@ -99,7 +100,9 @@ function getColorFromDecls(
99100

100101
const propsToCheck = areAllCustom ? props : nonCustomProps
101102

102-
const colors = propsToCheck.flatMap((prop) => ensureArray(decls[prop]).flatMap(getColorsInString))
103+
const colors = propsToCheck.flatMap((prop) => ensureArray(decls[prop]).flatMap((str) => {
104+
return getColorsInString(state, str)
105+
}))
103106

104107
// check that all of the values are valid colors
105108
// if (colors.some((color) => color instanceof TinyColor && !color.isValid)) {
@@ -170,7 +173,7 @@ function getColorFromRoot(state: State, css: postcss.Root): culori.Color | Keywo
170173
decls[decl.prop].push(decl.value)
171174
})
172175

173-
return getColorFromDecls(decls)
176+
return getColorFromDecls(state, decls)
174177
}
175178

176179
export function getColor(state: State, className: string): culori.Color | KeywordColor | null {
@@ -186,7 +189,7 @@ export function getColor(state: State, className: string): culori.Color | Keywor
186189
if (state.classNames) {
187190
const item = dlv(state.classNames.classNames, [className, '__info'])
188191
if (item && item.__rule) {
189-
return getColorFromDecls(removeMeta(item))
192+
return getColorFromDecls(state, removeMeta(item))
190193
}
191194
}
192195

@@ -215,7 +218,7 @@ export function getColor(state: State, className: string): culori.Color | Keywor
215218
decls[decl.prop] = decl.value
216219
}
217220
})
218-
return getColorFromDecls(decls)
221+
return getColorFromDecls(state, decls)
219222
}
220223

221224
let parts = getClassNameParts(state, className)
@@ -224,7 +227,7 @@ export function getColor(state: State, className: string): culori.Color | Keywor
224227
const item = dlv(state.classNames.classNames, [...parts, '__info'])
225228
if (!item.__rule) return null
226229

227-
return getColorFromDecls(removeMeta(item))
230+
return getColorFromDecls(state, removeMeta(item))
228231
}
229232

230233
export function getColorFromValue(value: unknown): culori.Color | KeywordColor | null {

packages/tailwindcss-language-service/src/util/css-vars.ts

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
11
export function replaceCssVarsWithFallbacks(str: string): string {
2+
return replaceCssVars(str, (name, fallback) => {
3+
if (fallback) {
4+
return fallback
5+
}
6+
7+
// Don't touch it since there's no suitable replacement
8+
return null
9+
})
10+
}
11+
12+
type CssVarReplacer = (name: string, fallback: string | null) => string | null
13+
14+
function replaceCssVars(str: string, replace: CssVarReplacer): string {
215
for (let i = 0; i < str.length; ++i) {
316
if (!str.startsWith('var(', i)) continue
417

@@ -13,13 +26,31 @@ export function replaceCssVarsWithFallbacks(str: string): string {
1326
} else if (str[j] === ',' && depth === 0 && fallbackStart === null) {
1427
fallbackStart = j + 1
1528
} else if (str[j] === ')' && depth === 0) {
29+
let varName: string
30+
let fallback: string | null
31+
1632
if (fallbackStart === null) {
17-
i = j + 1
33+
varName = str.slice(i + 4, j)
34+
fallback = null
35+
} else {
36+
varName = str.slice(i + 4, fallbackStart - 1)
37+
fallback = str.slice(fallbackStart, j)
38+
}
39+
40+
let replacement = replace(varName, fallback)
41+
42+
if (replacement !== null) {
43+
str = str.slice(0, i) + replacement + str.slice(j + 1)
44+
45+
// We don't want to skip past anything here because `replacement`
46+
// might contain more var(…) calls in which case `i` will already
47+
// be pointing at the right spot to start looking for them
1848
break
1949
}
2050

21-
let fallbackEnd = j
22-
str = str.slice(0, i) + str.slice(fallbackStart, fallbackEnd) + str.slice(j + 1)
51+
// It can't be replaced so we can avoid unncessary work by skipping over
52+
// the entire var(…) call.
53+
i = j + 1
2354
break
2455
}
2556
}

0 commit comments

Comments
 (0)