Skip to content

Commit 4c0cff6

Browse files
committed
make invalidApply quick fix work with multiple selectors
1 parent 614154c commit 4c0cff6

File tree

1 file changed

+45
-3
lines changed

1 file changed

+45
-3
lines changed

src/lsp/providers/codeActions/provideInvalidApplyCodeActions.ts

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ import detectIndent from 'detect-indent'
1919
import isObject from '../../../util/isObject'
2020
import { cssObjToAst } from '../../util/cssObjToAst'
2121
import dset from 'dset'
22+
import selectorParser from 'postcss-selector-parser'
23+
import { logFull } from '../../util/logFull'
24+
import { flatten } from '../../../util/array'
2225

2326
export async function provideInvalidApplyCodeActions(
2427
state: State,
@@ -119,7 +122,8 @@ export async function provideInvalidApplyCodeActions(
119122
new RegExp(outputIndent, 'g'),
120123
documentIndent.indent
121124
)
122-
}),
125+
})
126+
.replace(/^(\s+)(.*?[^{}]\n)(\S)/gm, '$1$2$1$3'),
123127
})
124128

125129
return false
@@ -205,9 +209,12 @@ function classNameToAst(
205209
for (let i = 1; i <= path.length; i++) {
206210
dset(obj, path.slice(0, i), {})
207211
}
212+
213+
selector = appendPseudosToSelector(selector, pseudo)
214+
if (selector === null) return null
215+
208216
let rule = {
209-
// TODO: use proper selector parser
210-
[selector + pseudo.join('')]: {
217+
[selector]: {
211218
[`@apply ${classNameParts[classNameParts.length - 1]}${
212219
important ? ' !important' : ''
213220
}`]: '',
@@ -221,3 +228,38 @@ function classNameToAst(
221228

222229
return cssObjToAst(obj, state.modules.postcss)
223230
}
231+
232+
function appendPseudosToSelector(
233+
selector: string,
234+
pseudos: string[]
235+
): string | null {
236+
if (pseudos.length === 0) return selector
237+
238+
let canTransform = true
239+
240+
let transformedSelector = selectorParser((selectors) => {
241+
flatten(selectors.split((_) => true)).forEach((sel) => {
242+
// @ts-ignore
243+
for (let i = sel.nodes.length - 1; i >= 0; i--) {
244+
// @ts-ignore
245+
if (sel.nodes[i].type !== 'pseudo') {
246+
break
247+
// @ts-ignore
248+
} else if (pseudos.includes(sel.nodes[i].value)) {
249+
canTransform = false
250+
break
251+
}
252+
}
253+
if (canTransform) {
254+
pseudos.forEach((p) => {
255+
// @ts-ignore
256+
sel.append(selectorParser.pseudo({ value: p }))
257+
})
258+
}
259+
})
260+
}).processSync(selector)
261+
262+
if (!canTransform) return null
263+
264+
return transformedSelector
265+
}

0 commit comments

Comments
 (0)