1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
diff --git a/packages/tailwindcss-language-server/src/util/html.ts b/packages/tailwindcss-language-server/src/util/html.ts
index 97761adc6e19c9ad4e0342018f3b5d597e701bee..fee187f77aaaaa874ac03daa38a0d8f66e284fec 100644
--- a/packages/tailwindcss-language-server/src/util/html.ts
+++ b/packages/tailwindcss-language-server/src/util/html.ts
@@ -1,4 +1,4 @@
-import { TextDocument } from 'vscode-languageserver'
+import { TextDocument, Position } from 'vscode-languageserver'
import { JS_LANGUAGES } from './js'
export const HTML_LANGUAGES = [
@@ -19,12 +19,61 @@ 'nunjucks',
'php',
'razor',
'slim',
- 'svelte',
'twig',
- 'vue',
- ...JS_LANGUAGES
+ ...JS_LANGUAGES,
]
-export function isHtmlDoc(doc: TextDocument): boolean {
+function isHtmlDoc(doc: TextDocument): boolean {
return HTML_LANGUAGES.indexOf(doc.languageId) !== -1
}
+
+function isVueDoc(doc: TextDocument): boolean {
+ return doc.languageId === 'vue'
+}
+
+function isSvelteDoc(doc: TextDocument): boolean {
+ return doc.languageId === 'svelte'
+}
+
+export function isMixedDoc(doc: TextDocument): boolean {
+ return isVueDoc(doc) || isSvelteDoc(doc)
+}
+
+export function isHtmlContext(doc: TextDocument, position: Position): boolean {
+ if (isHtmlDoc(doc)) {
+ return true
+ }
+
+ if (isMixedDoc(doc)) {
+ let str = doc.getText({
+ start: { line: 0, character: 0 },
+ end: position,
+ })
+
+ if (isVueDoc(doc)) {
+ return isInsideTag(str, ['template', 'script'])
+ }
+
+ if (isSvelteDoc(doc)) {
+ return !isInsideTag(str, ['style'])
+ }
+ }
+
+ return false
+}
+
+export function isInsideTag(str: string, tag: string | string[]): boolean {
+ let open = 0
+ let close = 0
+ let match: RegExpExecArray
+ let tags = Array.isArray(tag) ? tag : [tag]
+ let regex = new RegExp(`<(?<slash>/?)(?:${tags.join('|')})\\b`, 'ig')
+ while ((match = regex.exec(str)) !== null) {
+ if (match.groups.slash) {
+ close += 1
+ } else {
+ open += 1
+ }
+ }
+ return open > 0 && open > close
+}
|