11import { TextDocument , Range , Position } from 'vscode-languageserver'
22import { DocumentClassName , DocumentClassList , State } from './state'
33import lineColumn from 'line-column'
4- import { isCssContext } from './css'
5- import { isHtmlContext } from './html'
4+ import { isCssContext , isCssDoc } from './css'
5+ import { isHtmlContext , isHtmlDoc , isSvelteDoc , isVueDoc } from './html'
66import { isWithinRange } from './isWithinRange'
7- import { isJsContext } from './js'
7+ import { isJsContext , isJsDoc } from './js'
88import { getClassAttributeLexer } from './lexers'
99
1010export function findAll ( re : RegExp , str : string ) : RegExpMatchArray [ ] {
@@ -26,8 +26,8 @@ export function findLast(re: RegExp, str: string): RegExpMatchArray {
2626
2727export function findClassNamesInRange (
2828 doc : TextDocument ,
29- range : Range ,
30- mode : 'html' | 'css'
29+ range ? : Range ,
30+ mode ? : 'html' | 'css'
3131) : DocumentClassName [ ] {
3232 const classLists = findClassListsInRange ( doc , range , mode )
3333 return [ ] . concat . apply (
@@ -66,10 +66,11 @@ export function findClassNamesInRange(
6666
6767export function findClassListsInCssRange (
6868 doc : TextDocument ,
69- range : Range
69+ range ? : Range
7070) : DocumentClassList [ ] {
7171 const text = doc . getText ( range )
7272 const matches = findAll ( / ( @ a p p l y \s + ) (?< classList > [ ^ ; } ] + ) [ ; } ] / g, text )
73+ const globalStart : Position = range ? range . start : { line : 0 , character : 0 }
7374
7475 return matches . map ( ( match ) => {
7576 const start = indexToPosition ( text , match . index + match [ 1 ] . length )
@@ -81,12 +82,14 @@ export function findClassListsInCssRange(
8182 classList : match . groups . classList ,
8283 range : {
8384 start : {
84- line : range . start . line + start . line ,
85- character : range . start . character + start . character ,
85+ line : globalStart . line + start . line ,
86+ character :
87+ ( end . line === 0 ? globalStart . character : 0 ) + start . character ,
8688 } ,
8789 end : {
88- line : range . start . line + end . line ,
89- character : range . start . character + end . character ,
90+ line : globalStart . line + end . line ,
91+ character :
92+ ( end . line === 0 ? globalStart . character : 0 ) + end . character ,
9093 } ,
9194 } ,
9295 }
@@ -172,11 +175,14 @@ export function findClassListsInHtmlRange(
172175 range : {
173176 start : {
174177 line : range . start . line + start . line ,
175- character : range . start . character + start . character ,
178+ character :
179+ ( end . line === 0 ? range . start . character : 0 ) +
180+ start . character ,
176181 } ,
177182 end : {
178183 line : range . start . line + end . line ,
179- character : range . start . character + end . character ,
184+ character :
185+ ( end . line === 0 ? range . start . character : 0 ) + end . character ,
180186 } ,
181187 } ,
182188 }
@@ -199,6 +205,80 @@ export function findClassListsInRange(
199205 return findClassListsInHtmlRange ( doc , range )
200206}
201207
208+ export function findClassListsInDocument (
209+ state : State ,
210+ doc : TextDocument
211+ ) : DocumentClassList [ ] {
212+ if ( isCssDoc ( state , doc ) ) {
213+ return findClassListsInCssRange ( doc )
214+ }
215+
216+ if ( isVueDoc ( doc ) ) {
217+ let text = doc . getText ( )
218+ let blocks = findAll (
219+ / < (?< type > t e m p l a t e | s t y l e | s c r i p t ) \b [ ^ > ] * > .* ?( < \/ \k<type > > | $ ) / gis,
220+ text
221+ )
222+ let htmlRanges : Range [ ] = [ ]
223+ let cssRanges : Range [ ] = [ ]
224+ for ( let i = 0 ; i < blocks . length ; i ++ ) {
225+ let range = {
226+ start : indexToPosition ( text , blocks [ i ] . index ) ,
227+ end : indexToPosition ( text , blocks [ i ] . index + blocks [ i ] [ 0 ] . length ) ,
228+ }
229+ if ( blocks [ i ] . groups . type === 'style' ) {
230+ cssRanges . push ( range )
231+ } else {
232+ htmlRanges . push ( range )
233+ }
234+ }
235+ return [ ] . concat . apply (
236+ [ ] ,
237+ [
238+ ...htmlRanges . map ( ( range ) => findClassListsInHtmlRange ( doc , range ) ) ,
239+ ...cssRanges . map ( ( range ) => findClassListsInCssRange ( doc , range ) ) ,
240+ ]
241+ )
242+ }
243+
244+ if ( isHtmlDoc ( state , doc ) || isJsDoc ( state , doc ) || isSvelteDoc ( doc ) ) {
245+ let text = doc . getText ( )
246+ let styleBlocks = findAll ( / < s t y l e (?: \s [ ^ > ] * > | > ) .* ?( < \/ s t y l e > | $ ) / gis, text )
247+ let htmlRanges : Range [ ] = [ ]
248+ let cssRanges : Range [ ] = [ ]
249+ let currentIndex = 0
250+
251+ for ( let i = 0 ; i < styleBlocks . length ; i ++ ) {
252+ htmlRanges . push ( {
253+ start : indexToPosition ( text , currentIndex ) ,
254+ end : indexToPosition ( text , styleBlocks [ i ] . index ) ,
255+ } )
256+ cssRanges . push ( {
257+ start : indexToPosition ( text , styleBlocks [ i ] . index ) ,
258+ end : indexToPosition (
259+ text ,
260+ styleBlocks [ i ] . index + styleBlocks [ i ] [ 0 ] . length
261+ ) ,
262+ } )
263+ currentIndex = styleBlocks [ i ] . index + styleBlocks [ i ] [ 0 ] . length
264+ }
265+ htmlRanges . push ( {
266+ start : indexToPosition ( text , currentIndex ) ,
267+ end : indexToPosition ( text , text . length ) ,
268+ } )
269+
270+ return [ ] . concat . apply (
271+ [ ] ,
272+ [
273+ ...htmlRanges . map ( ( range ) => findClassListsInHtmlRange ( doc , range ) ) ,
274+ ...cssRanges . map ( ( range ) => findClassListsInCssRange ( doc , range ) ) ,
275+ ]
276+ )
277+ }
278+
279+ return [ ]
280+ }
281+
202282function indexToPosition ( str : string , index : number ) : Position {
203283 const { line, col } = lineColumn ( str + '\n' , index )
204284 return { line : line - 1 , character : col - 1 }
0 commit comments