@vue/language-service 2.2.0 → 2.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/data/language-blocks/zh-cn.json +6 -6
  2. package/data/model-modifiers/zh-cn.json +1 -1
  3. package/data/template/it.json +5 -5
  4. package/index.js +12 -8
  5. package/lib/ideFeatures/nameCasing.js +6 -6
  6. package/lib/plugins/css.js +59 -0
  7. package/lib/plugins/utils.d.ts +3 -0
  8. package/lib/plugins/utils.js +14 -0
  9. package/lib/plugins/vue-autoinsert-dotvalue.d.ts +0 -9
  10. package/lib/plugins/vue-autoinsert-dotvalue.js +31 -50
  11. package/lib/plugins/vue-autoinsert-self-closing.d.ts +2 -0
  12. package/lib/plugins/vue-autoinsert-self-closing.js +33 -0
  13. package/lib/plugins/vue-complete-define-assignment.js +6 -5
  14. package/lib/plugins/vue-directive-comments.d.ts +4 -0
  15. package/lib/plugins/vue-directive-comments.js +4 -0
  16. package/lib/plugins/vue-document-drop.js +5 -5
  17. package/lib/plugins/vue-document-links.js +5 -4
  18. package/lib/plugins/vue-extract-file.d.ts +2 -1
  19. package/lib/plugins/vue-extract-file.js +12 -7
  20. package/lib/plugins/vue-inlayhints.d.ts +1 -1
  21. package/lib/plugins/vue-inlayhints.js +11 -11
  22. package/lib/plugins/vue-sfc.js +48 -7
  23. package/lib/plugins/vue-template/autoinsert-self-closing-tags.d.ts +6 -0
  24. package/lib/plugins/vue-template/autoinsert-self-closing-tags.js +39 -0
  25. package/lib/plugins/vue-template/autoinsert-selfClosingTags.d.ts +1 -0
  26. package/lib/plugins/vue-template/autoinsert-selfClosingTags.js +3 -0
  27. package/lib/plugins/vue-template/autoinsert-selfclosing-tags.d.ts +1 -0
  28. package/lib/plugins/vue-template/autoinsert-selfclosing-tags.js +3 -0
  29. package/lib/plugins/vue-template.js +40 -50
  30. package/package.json +8 -7
@@ -8,7 +8,7 @@
8
8
  "name": "src",
9
9
  "description": {
10
10
  "kind": "markdown",
11
- "value": "如果你更喜欢将 `*.vue` 组件分散到多个文件中,可以为一个语块使用 `src` 这个 attribute 来导入一个外部文件:\n\n```vue\n<template src=\"./template.html\"></template>\n<style src=\"./style.css\"></style>\n<script src=\"./script.js\"></script>\n```\n\n请注意 `src` 导入和 JS 模块导入遵循相同的路径解析规则,这意味着:\n\n- 相对路径需要以 `./` 开头\n- 你也可以从 npm 依赖中导入资源\n\n```vue\n<!-- 从所安装的 \"todomvc-app-css\" npm 包中导入一个文件 -->\n<style src=\"todomvc-app-css/index.css\" />\n```\n\n`src` 导入对自定义语块也同样适用:\n\n```vue\n<unit-test src=\"./unit-test.js\">\n</unit-test>\n```"
11
+ "value": "如果你更喜欢将 `*.vue` 组件分散到多个文件中,可以为一个语块使用 `src` 这个 attribute 来导入一个外部文件:\n\n```vue\n<template src=\"./template.html\"></template>\n<style src=\"./style.css\"></style>\n<script src=\"./script.js\"></script>\n```\n\n请注意 `src` 导入和 JS 模块导入遵循相同的路径解析规则,这意味着:\n\n- 相对路径需要以 `./` 开头\n- 你也可以从 npm 依赖中导入资源\n\n```vue\n<!-- 从所安装的 \"todomvc-app-css\" npm 包中导入一个文件 -->\n<style src=\"todomvc-app-css/index.css\" />\n```\n\n`src` 导入对自定义语块也同样适用:\n\n```vue\n<unit-test src=\"./unit-test.js\">\n</unit-test>\n```\n\n:::warning 注意\n在 `src` 中使用别名时,不要以 `~` 开头,后面的任何内容都会被解释为模块请求。这意味着你可以引用 node 模块中的资源:\n```vue\n<img src=\"~some-npm-package/foo.png\">\n```\n:::"
12
12
  },
13
13
  "references": "api/sfc-spec.html#src-imports"
14
14
  },
@@ -42,7 +42,7 @@
42
42
  "name": "src",
43
43
  "description": {
44
44
  "kind": "markdown",
45
- "value": "如果你更喜欢将 `*.vue` 组件分散到多个文件中,可以为一个语块使用 `src` 这个 attribute 来导入一个外部文件:\n\n```vue\n<template src=\"./template.html\"></template>\n<style src=\"./style.css\"></style>\n<script src=\"./script.js\"></script>\n```\n\n请注意 `src` 导入和 JS 模块导入遵循相同的路径解析规则,这意味着:\n\n- 相对路径需要以 `./` 开头\n- 你也可以从 npm 依赖中导入资源\n\n```vue\n<!-- 从所安装的 \"todomvc-app-css\" npm 包中导入一个文件 -->\n<style src=\"todomvc-app-css/index.css\" />\n```\n\n`src` 导入对自定义语块也同样适用:\n\n```vue\n<unit-test src=\"./unit-test.js\">\n</unit-test>\n```"
45
+ "value": "如果你更喜欢将 `*.vue` 组件分散到多个文件中,可以为一个语块使用 `src` 这个 attribute 来导入一个外部文件:\n\n```vue\n<template src=\"./template.html\"></template>\n<style src=\"./style.css\"></style>\n<script src=\"./script.js\"></script>\n```\n\n请注意 `src` 导入和 JS 模块导入遵循相同的路径解析规则,这意味着:\n\n- 相对路径需要以 `./` 开头\n- 你也可以从 npm 依赖中导入资源\n\n```vue\n<!-- 从所安装的 \"todomvc-app-css\" npm 包中导入一个文件 -->\n<style src=\"todomvc-app-css/index.css\" />\n```\n\n`src` 导入对自定义语块也同样适用:\n\n```vue\n<unit-test src=\"./unit-test.js\">\n</unit-test>\n```\n\n:::warning 注意\n在 `src` 中使用别名时,不要以 `~` 开头,后面的任何内容都会被解释为模块请求。这意味着你可以引用 node 模块中的资源:\n```vue\n<img src=\"~some-npm-package/foo.png\">\n```\n:::"
46
46
  },
47
47
  "references": "api/sfc-spec.html#src-imports"
48
48
  },
@@ -103,7 +103,7 @@
103
103
  "name": "src",
104
104
  "description": {
105
105
  "kind": "markdown",
106
- "value": "如果你更喜欢将 `*.vue` 组件分散到多个文件中,可以为一个语块使用 `src` 这个 attribute 来导入一个外部文件:\n\n```vue\n<template src=\"./template.html\"></template>\n<style src=\"./style.css\"></style>\n<script src=\"./script.js\"></script>\n```\n\n请注意 `src` 导入和 JS 模块导入遵循相同的路径解析规则,这意味着:\n\n- 相对路径需要以 `./` 开头\n- 你也可以从 npm 依赖中导入资源\n\n```vue\n<!-- 从所安装的 \"todomvc-app-css\" npm 包中导入一个文件 -->\n<style src=\"todomvc-app-css/index.css\" />\n```\n\n`src` 导入对自定义语块也同样适用:\n\n```vue\n<unit-test src=\"./unit-test.js\">\n</unit-test>\n```"
106
+ "value": "如果你更喜欢将 `*.vue` 组件分散到多个文件中,可以为一个语块使用 `src` 这个 attribute 来导入一个外部文件:\n\n```vue\n<template src=\"./template.html\"></template>\n<style src=\"./style.css\"></style>\n<script src=\"./script.js\"></script>\n```\n\n请注意 `src` 导入和 JS 模块导入遵循相同的路径解析规则,这意味着:\n\n- 相对路径需要以 `./` 开头\n- 你也可以从 npm 依赖中导入资源\n\n```vue\n<!-- 从所安装的 \"todomvc-app-css\" npm 包中导入一个文件 -->\n<style src=\"todomvc-app-css/index.css\" />\n```\n\n`src` 导入对自定义语块也同样适用:\n\n```vue\n<unit-test src=\"./unit-test.js\">\n</unit-test>\n```\n\n:::warning 注意\n在 `src` 中使用别名时,不要以 `~` 开头,后面的任何内容都会被解释为模块请求。这意味着你可以引用 node 模块中的资源:\n```vue\n<img src=\"~some-npm-package/foo.png\">\n```\n:::"
107
107
  },
108
108
  "references": "api/sfc-spec.html#src-imports"
109
109
  },
@@ -149,7 +149,7 @@
149
149
  "valueSet": "v",
150
150
  "description": {
151
151
  "kind": "markdown",
152
- "value": "一个 `<style module>` 标签会被编译为 [CSS Modules](https://github.com/css-modules/css-modules) 并且将生成的 CSS class 作为 `$style` 对象暴露给组件:\n\n```vue\n<template>\n <p :class=\"$style.red\">This should be red</p>\n</template>\n\n<style module>\n.red {\n color: red;\n}\n</style>\n```\n\n得出的 class 将被哈希化以避免冲突,实现了同样的将 CSS 仅作用于当前组件的效果。\n\n参考 [CSS Modules spec](https://github.com/css-modules/css-modules) 以查看更多详情,例如 [global exceptions](https://github.com/css-modules/css-modules/blob/master/docs/composition.md#exceptions) 和 [composition](https://github.com/css-modules/css-modules/blob/master/docs/composition.md#composition)。\n\n### 自定义注入名称 \n\n你可以通过给 `module` attribute 一个值来自定义注入 class 对象的属性名:\n\n```vue\n<template>\n <p :class=\"classes.red\">red</p>\n</template>\n\n<style module=\"classes\">\n.red {\n color: red;\n}\n</style>\n```\n\n### 与组合式 API 一同使用 \n\n可以通过 `useCssModule` API 在 `setup()` 和 `<script setup>` 中访问注入的 class。对于使用了自定义注入名称的 `<style module>` 块,`useCssModule` 接收一个匹配的 `module` attribute 值作为第一个参数:\n\n```js\nimport { useCssModule } from 'vue'\n\n// 在 setup() 作用域中...\n// 默认情况下,返回 <style module> 的 class\nuseCssModule()\n\n// 具名情况下,返回 <style module=\"classes\"> 的 class\nuseCssModule('classes')\n```"
152
+ "value": "一个 `<style module>` 标签会被编译为 [CSS Modules](https://github.com/css-modules/css-modules) 并且将生成的 CSS class 作为 `$style` 对象暴露给组件:\n\n```vue\n<template>\n <p :class=\"$style.red\">This should be red</p>\n</template>\n\n<style module>\n.red {\n color: red;\n}\n</style>\n```\n\n得出的 class 将被哈希化以避免冲突,实现了同样的将 CSS 仅作用于当前组件的效果。\n\n参考 [CSS Modules spec](https://github.com/css-modules/css-modules) 以查看更多详情,例如 [global exceptions](https://github.com/css-modules/css-modules/blob/master/docs/composition.md#exceptions) 和 [composition](https://github.com/css-modules/css-modules/blob/master/docs/composition.md#composition)。\n\n### 自定义注入名称 \n\n你可以通过给 `module` attribute 一个值来自定义注入 class 对象的属性名:\n\n```vue\n<template>\n <p :class=\"classes.red\">red</p>\n</template>\n\n<style module=\"classes\">\n.red {\n color: red;\n}\n</style>\n```\n\n### 与组合式 API 一同使用 \n\n可以通过 `useCssModule` API 在 `setup()` 和 `<script setup>` 中访问注入的 class。对于使用了自定义注入名称的 `<style module>` 块,`useCssModule` 接收一个匹配的 `module` attribute 值作为第一个参数:\n\n```js\nimport { useCssModule } from 'vue'\n\n// 在 setup() 作用域中...\n// 默认情况下,返回 <style module> 的 class\nuseCssModule()\n\n// 具名情况下,返回 <style module=\"classes\"> 的 class\nuseCssModule('classes')\n```\n\n- **示例**\n\n```vue\n<script setup lang=\"ts\">\nimport { useCssModule } from 'vue'\n\nconst classes = useCssModule()\n</script>\n\n<template>\n <p :class=\"classes.red\">red</p>\n</template>\n\n<style module>\n.red {\n color: red;\n}\n</style>\n```"
153
153
  },
154
154
  "references": "api/sfc-css-features.html#css-modules"
155
155
  }
@@ -167,7 +167,7 @@
167
167
  "name": "src",
168
168
  "description": {
169
169
  "kind": "markdown",
170
- "value": "如果你更喜欢将 `*.vue` 组件分散到多个文件中,可以为一个语块使用 `src` 这个 attribute 来导入一个外部文件:\n\n```vue\n<template src=\"./template.html\"></template>\n<style src=\"./style.css\"></style>\n<script src=\"./script.js\"></script>\n```\n\n请注意 `src` 导入和 JS 模块导入遵循相同的路径解析规则,这意味着:\n\n- 相对路径需要以 `./` 开头\n- 你也可以从 npm 依赖中导入资源\n\n```vue\n<!-- 从所安装的 \"todomvc-app-css\" npm 包中导入一个文件 -->\n<style src=\"todomvc-app-css/index.css\" />\n```\n\n`src` 导入对自定义语块也同样适用:\n\n```vue\n<unit-test src=\"./unit-test.js\">\n</unit-test>\n```"
170
+ "value": "如果你更喜欢将 `*.vue` 组件分散到多个文件中,可以为一个语块使用 `src` 这个 attribute 来导入一个外部文件:\n\n```vue\n<template src=\"./template.html\"></template>\n<style src=\"./style.css\"></style>\n<script src=\"./script.js\"></script>\n```\n\n请注意 `src` 导入和 JS 模块导入遵循相同的路径解析规则,这意味着:\n\n- 相对路径需要以 `./` 开头\n- 你也可以从 npm 依赖中导入资源\n\n```vue\n<!-- 从所安装的 \"todomvc-app-css\" npm 包中导入一个文件 -->\n<style src=\"todomvc-app-css/index.css\" />\n```\n\n`src` 导入对自定义语块也同样适用:\n\n```vue\n<unit-test src=\"./unit-test.js\">\n</unit-test>\n```\n\n:::warning 注意\n在 `src` 中使用别名时,不要以 `~` 开头,后面的任何内容都会被解释为模块请求。这意味着你可以引用 node 模块中的资源:\n```vue\n<img src=\"~some-npm-package/foo.png\">\n```\n:::"
171
171
  },
172
172
  "references": "api/sfc-spec.html#src-imports"
173
173
  }
@@ -193,7 +193,7 @@
193
193
  "name": "src",
194
194
  "description": {
195
195
  "kind": "markdown",
196
- "value": "如果你更喜欢将 `*.vue` 组件分散到多个文件中,可以为一个语块使用 `src` 这个 attribute 来导入一个外部文件:\n\n```vue\n<template src=\"./template.html\"></template>\n<style src=\"./style.css\"></style>\n<script src=\"./script.js\"></script>\n```\n\n请注意 `src` 导入和 JS 模块导入遵循相同的路径解析规则,这意味着:\n\n- 相对路径需要以 `./` 开头\n- 你也可以从 npm 依赖中导入资源\n\n```vue\n<!-- 从所安装的 \"todomvc-app-css\" npm 包中导入一个文件 -->\n<style src=\"todomvc-app-css/index.css\" />\n```\n\n`src` 导入对自定义语块也同样适用:\n\n```vue\n<unit-test src=\"./unit-test.js\">\n</unit-test>\n```"
196
+ "value": "如果你更喜欢将 `*.vue` 组件分散到多个文件中,可以为一个语块使用 `src` 这个 attribute 来导入一个外部文件:\n\n```vue\n<template src=\"./template.html\"></template>\n<style src=\"./style.css\"></style>\n<script src=\"./script.js\"></script>\n```\n\n请注意 `src` 导入和 JS 模块导入遵循相同的路径解析规则,这意味着:\n\n- 相对路径需要以 `./` 开头\n- 你也可以从 npm 依赖中导入资源\n\n```vue\n<!-- 从所安装的 \"todomvc-app-css\" npm 包中导入一个文件 -->\n<style src=\"todomvc-app-css/index.css\" />\n```\n\n`src` 导入对自定义语块也同样适用:\n\n```vue\n<unit-test src=\"./unit-test.js\">\n</unit-test>\n```\n\n:::warning 注意\n在 `src` 中使用别名时,不要以 `~` 开头,后面的任何内容都会被解释为模块请求。这意味着你可以引用 node 模块中的资源:\n```vue\n<img src=\"~some-npm-package/foo.png\">\n```\n:::"
197
197
  },
198
198
  "references": "api/sfc-spec.html#src-imports"
199
199
  }
@@ -13,7 +13,7 @@
13
13
  "name": "number",
14
14
  "description": {
15
15
  "kind": "markdown",
16
- "value": "如果你想让用户输入自动转换为数字,你可以在 `v-model` 后添加 `.number` 修饰符来管理输入:\n\n```html\n<input v-model.number=\"age\" />\n```\n\n如果该值无法被 `parseFloat()` 处理,那么将返回原始值。\n\n`number` 修饰符会在输入框有 `type=\"number\"` 时自动启用。"
16
+ "value": "如果你想让用户输入自动转换为数字,你可以在 `v-model` 后添加 `.number` 修饰符来管理输入:\n\n```html\n<input v-model.number=\"age\" />\n```\n\n如果该值无法被 `parseFloat()` 处理,那么将返回原始值。特别是当输入为空时 (例如用户清空输入字段之后),会返回一个空字符串。这种行为与 [DOM 属性 valueAsNumber](https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLInputElement#valueasnumber) 有所不同。\n\n`number` 修饰符会在输入框有 `type=\"number\"` 时自动启用。"
17
17
  },
18
18
  "references": "guide/essentials/forms.html#number"
19
19
  },
@@ -5,7 +5,7 @@
5
5
  "name": "Transition",
6
6
  "description": {
7
7
  "kind": "markdown",
8
- "value": "\nProvides animated transition effects to a **single** element or component.\n\n- **Props**\n\n ```ts\n interface TransitionProps {\n /**\n * Used to automatically generate transition CSS class names.\n * e.g. `name: 'fade'` will auto expand to `.fade-enter`,\n * `.fade-enter-active`, etc.\n */\n name?: string\n /**\n * Whether to apply CSS transition classes.\n * Default: true\n */\n css?: boolean\n /**\n * Specifies the type of transition events to wait for to\n * determine transition end timing.\n * Default behavior is auto detecting the type that has\n * longer duration.\n */\n type?: 'transition' | 'animation'\n /**\n * Specifies explicit durations of the transition.\n * Default behavior is wait for the first `transitionend`\n * or `animationend` event on the root transition element.\n */\n duration?: number | { enter: number; leave: number }\n /**\n * Controls the timing sequence of leaving/entering transitions.\n * Default behavior is simultaneous.\n */\n mode?: 'in-out' | 'out-in' | 'default'\n /**\n * Whether to apply transition on initial render.\n * Default: false\n */\n appear?: boolean\n\n /**\n * Props for customizing transition classes.\n * Use kebab-case in templates, e.g. enter-from-class=\"xxx\"\n */\n enterFromClass?: string\n enterActiveClass?: string\n enterToClass?: string\n appearFromClass?: string\n appearActiveClass?: string\n appearToClass?: string\n leaveFromClass?: string\n leaveActiveClass?: string\n leaveToClass?: string\n }\n ```\n\n- **Events**\n\n - `@before-enter`\n - `@before-leave`\n - `@enter`\n - `@leave`\n - `@appear`\n - `@after-enter`\n - `@after-leave`\n - `@after-appear`\n - `@enter-cancelled`\n - `@leave-cancelled` (`v-show` only)\n - `@appear-cancelled`\n\n- **Example**\n\n Simple element:\n\n ```html\n <Transition>\n <div v-if=\"ok\">toggled content</div>\n </Transition>\n ```\n\n Forcing a transition by changing the `key` attribute:\n\n ```html\n <Transition>\n <div :key=\"text\">{{ text }}</div>\n </Transition>\n ```\n\n Dynamic component, with transition mode + animate on appear:\n\n ```html\n <Transition name=\"fade\" mode=\"out-in\" appear>\n <component :is=\"view\"></component>\n </Transition>\n ```\n\n Listening to transition events:\n\n ```html\n <Transition @after-enter=\"onTransitionComplete\">\n <div v-show=\"ok\">toggled content</div>\n </Transition>\n ```\n\n- **See also** [`<Transition>` Guide](https://it.vuejs.org/guide/built-ins/transition.html)\n"
8
+ "value": "\nFornisce un'animazione di transizione a un **solo** elemento o componente.\n\n- **Props**\n\n ```ts\n interface TransitionProps {\n /**\n * Usato per generare automaticamente classi CSS per le transizioni.\n * Per esempio `name: 'fade'` verrà automaticamente espanso in `.fade-enter`,\n * `.fade-enter-active`, etc.\n */\n name?: string\n /**\n * Definisce se applicare le classi di transizione CSS.\n * Predefinito: true\n */\n css?: boolean\n /**\n * Specifica il tipo di evento di transizione da attendere\n * per determinare la tempistica della fine della transizione.\n * Il comportamento predefinito rileva automaticamente il tipo che ha\n * la durata maggiore.\n */\n type?: 'transition' | 'animation'\n /**\n * Specifica esplicitamente la durata della transizione.\n * Il comportamento predefinito è di attendere il primo evento\n * `transitionend` o `animationend` nel root dell'elemento transition.\n */\n duration?: number | { enter: number; leave: number }\n /**\n * Controlla la sequenza temporale delle transizioni di uscita/entrata.\n * Il comportamento predefinito è simultaneo\n */\n mode?: 'in-out' | 'out-in' | 'default'\n /**\n * Definisce se applicare la transizione al rendering iniziale.\n * Predefinito: false\n */\n appear?: boolean\n\n /**\n * Props per personalizzare le classi di transizione.\n * Usa il kebab-case nei template, per esempio enter-from-class=\"xxx\"\n */\n enterFromClass?: string\n enterActiveClass?: string\n enterToClass?: string\n appearFromClass?: string\n appearActiveClass?: string\n appearToClass?: string\n leaveFromClass?: string\n leaveActiveClass?: string\n leaveToClass?: string\n }\n ```\n\n- **Eventi**\n\n - `@before-enter`\n - `@before-leave`\n - `@enter`\n - `@leave`\n - `@appear`\n - `@after-enter`\n - `@after-leave`\n - `@after-appear`\n - `@enter-cancelled`\n - `@leave-cancelled` (solo `v-show`)\n - `@appear-cancelled`\n\n- **Esempio**\n\n Elemento semplice:\n\n ```html\n <Transition>\n <div v-if=\"ok\">contenuto attivato</div>\n </Transition>\n ```\n\n Forzare una transizione cambiando l'attributo `key`:\n\n ```html\n <Transition>\n <div :key=\"text\">{{ text }}</div>\n </Transition>\n ```\n\n Componente dinamico, con modalità di transizione + animazione in entrata:\n\n ```html\n <Transition name=\"fade\" mode=\"out-in\" appear>\n <component :is=\"view\"></component>\n </Transition>\n ```\n\n Ascolto eventi transizione:\n\n ```html\n <Transition @after-enter=\"onTransitionComplete\">\n <div v-show=\"ok\">toggled content</div>\n </Transition>\n ```\n\n- **Vedi anche** [Guida `<Transition>`](https://it.vuejs.org/guide/built-ins/transition.html)\n"
9
9
  },
10
10
  "attributes": [],
11
11
  "references": "api/built-in-components.html#transition"
@@ -14,7 +14,7 @@
14
14
  "name": "TransitionGroup",
15
15
  "description": {
16
16
  "kind": "markdown",
17
- "value": "\nProvides transition effects for **multiple** elements or components in a list.\n\n- **Props**\n\n `<TransitionGroup>` accepts the same props as `<Transition>` except `mode`, plus two additional props:\n\n ```ts\n interface TransitionGroupProps extends Omit<TransitionProps, 'mode'> {\n /**\n * If not defined, renders as a fragment.\n */\n tag?: string\n /**\n * For customizing the CSS class applied during move transitions.\n * Use kebab-case in templates, e.g. move-class=\"xxx\"\n */\n moveClass?: string\n }\n ```\n\n- **Events**\n\n `<TransitionGroup>` emits the same events as `<Transition>`.\n\n- **Details**\n\n By default, `<TransitionGroup>` doesn't render a wrapper DOM element, but one can be defined via the `tag` prop.\n\n Note that every child in a `<transition-group>` must be [**uniquely keyed**](https://it.vuejs.org/guide/essentials/list.html#maintaining-state-with-key) for the animations to work properly.\n\n `<TransitionGroup>` supports moving transitions via CSS transform. When a child's position on screen has changed after an update, it will get applied a moving CSS class (auto generated from the `name` attribute or configured with the `move-class` prop). If the CSS `transform` property is \"transition-able\" when the moving class is applied, the element will be smoothly animated to its destination using the [FLIP technique](https://aerotwist.com/blog/flip-your-animations/).\n\n- **Example**\n\n ```html\n <TransitionGroup tag=\"ul\" name=\"slide\">\n <li v-for=\"item in items\" :key=\"item.id\">\n {{ item.text }}\n </li>\n </TransitionGroup>\n ```\n\n- **See also** [Guide - TransitionGroup](https://it.vuejs.org/guide/built-ins/transition-group.html)\n"
17
+ "value": "\nFornisce effetti di transizione per elementi **multipli** o componenti in un elenco.\n\n- **Props**\n\n `<TransitionGroup>` accetta le stesse props di `<Transition>` tranne `mode`, più due prop aggiuntive:\n\n ```ts\n interface TransitionGroupProps extends Omit<TransitionProps, 'mode'> {\n /**\n * Se non definito, renderizza come un fragment\n */\n tag?: string\n /**\n * Per personalizzare la classe CSS applicata durante la transizione.\n * Usa il kebab-case nel template, per esempio move-class=\"xxx\"\n */\n moveClass?: string\n }\n ```\n\n- **Eventi**\n\n `<TransitionGroup>` emette gli stessi eventi di `<Transition>`.\n\n- **Dettagli**\n\n Di default, `<TransitionGroup>` non renderizza un elemento DOM wrapper, ma uno può essere definito attraverso la prop `tag`.\n\n Nota che ogni figlio in `<transition-group>` deve avere una [**chiave univoca**](https://it.vuejs.org/guide/essentials/list.html#maintaining-state-with-key) per l'animazione per funzionare correttamente.\n\n `<TransitionGroup>` supporta le transizioni tramite trasformazione CSS. Quando la posizione di un figlio nello schermo cambia dopo un aggiornamento, gli verrà applicata una classe CSS di movimento (generata automaticamente dall'attributo `name` o configurato con la prop `move-class`). Se la proprietà CSS `transform` è \"transition-able\" quando la classe di movimento è applicata, l'elemento verrà animato fluidamente alla sua destinazione usando la [tecnica FLIP](https://aerotwist.com/blog/flip-your-animations/).\n\n- **Esempio**\n\n ```html\n <TransitionGroup tag=\"ul\" name=\"slide\">\n <li v-for=\"item in items\" :key=\"item.id\">\n {{ item.text }}\n </li>\n </TransitionGroup>\n ```\n\n- **Vedi anche** [Guida - TransitionGroup](https://it.vuejs.org/guide/built-ins/transition-group.html)\n"
18
18
  },
19
19
  "attributes": [],
20
20
  "references": "api/built-in-components.html#transitiongroup"
@@ -23,7 +23,7 @@
23
23
  "name": "KeepAlive",
24
24
  "description": {
25
25
  "kind": "markdown",
26
- "value": "\nCaches dynamically toggled components wrapped inside.\n\n- **Props**\n\n ```ts\n interface KeepAliveProps {\n /**\n * If specified, only components with names matched by\n * `include` will be cached.\n */\n include?: MatchPattern\n /**\n * Any component with a name matched by `exclude` will\n * not be cached.\n */\n exclude?: MatchPattern\n /**\n * The maximum number of component instances to cache.\n */\n max?: number | string\n }\n\n type MatchPattern = string | RegExp | (string | RegExp)[]\n ```\n\n- **Details**\n\n When wrapped around a dynamic component, `<KeepAlive>` caches the inactive component instances without destroying them.\n\n There can only be one active component instance as the direct child of `<KeepAlive>` at any time.\n\n When a component is toggled inside `<KeepAlive>`, its `activated` and `deactivated` lifecycle hooks will be invoked accordingly, providing an alternative to `mounted` and `unmounted`, which are not called. This applies to the direct child of `<KeepAlive>` as well as to all of its descendants.\n\n- **Example**\n\n Utilizzo Base:\n\n ```html\n <KeepAlive>\n <component :is=\"view\"></component>\n </KeepAlive>\n ```\n\n When used with `v-if` / `v-else` branches, there must be only one component rendered at a time:\n\n ```html\n <KeepAlive>\n <comp-a v-if=\"a > 1\"></comp-a>\n <comp-b v-else></comp-b>\n </KeepAlive>\n ```\n\n Used together with `<Transition>`:\n\n ```html\n <Transition>\n <KeepAlive>\n <component :is=\"view\"></component>\n </KeepAlive>\n </Transition>\n ```\n\n Using `include` / `exclude`:\n\n ```html\n <!-- comma-delimited string -->\n <KeepAlive include=\"a,b\">\n <component :is=\"view\"></component>\n </KeepAlive>\n\n <!-- regex (use `v-bind`) -->\n <KeepAlive :include=\"/a|b/\">\n <component :is=\"view\"></component>\n </KeepAlive>\n\n <!-- Array (use `v-bind`) -->\n <KeepAlive :include=\"['a', 'b']\">\n <component :is=\"view\"></component>\n </KeepAlive>\n ```\n\n Usage with `max`:\n\n ```html\n <KeepAlive :max=\"10\">\n <component :is=\"view\"></component>\n </KeepAlive>\n ```\n\n- **See also** [Guide - KeepAlive](https://it.vuejs.org/guide/built-ins/keep-alive.html)\n"
26
+ "value": "\nMemorizza nella cache i componenti attivati/disattivati ​​dinamicamente racchiusi all'interno.\n\n- **Props**\n\n ```ts\n interface KeepAliveProps {\n /**\n * Se specificata, solo i componenti con gli stessi nomi corrispondenti a \n * `include` saranno memorizzati nella cache.\n */\n include?: MatchPattern\n /**\n * Qualsiasi componente con un nome corrispondente a `exclude`\n * non verrà memorizzato nella cache.\n */\n exclude?: MatchPattern\n /**\n * Il numero massimo di istanze del componente da memorizzare nella cache.\n */\n max?: number | string\n }\n\n type MatchPattern = string | RegExp | (string | RegExp)[]\n ```\n\n- **Dettagli**\n\n Quando racchiuso in un componente dinamico, `<KeepAlive>` memorizza nella cache le istanze dei componenti inattivi senza distruggerle.\n\n Ci può essere solo un'istanza di un componente come figlio diretto di `<KeepAlive>` in qualsiasi momento.\n\n Quando un componente è azionato dentro `<KeepAlive>`, i suoi lifecycle hooks `activated` e `deactivated` verranno richiamati di conseguenza, offrendo un alternativa a `mounted` e `unmounted`, che non sono chiamati. Questo si applica ai figli diretti di `<KeepAlive>` e anche a tutti i suoi discendenti.\n\n- **Esempio**\n\n Utilizzo Base:\n\n ```html\n <KeepAlive>\n <component :is=\"view\"></component>\n </KeepAlive>\n ```\n Quando usato con `v-if` / `v-else`, ci deve essere solo un componente renderizzato alla volta:\n\n ```html\n <KeepAlive>\n <comp-a v-if=\"a > 1\"></comp-a>\n <comp-b v-else></comp-b>\n </KeepAlive>\n ```\n Usato insieme a `<Transition>`:\n\n ```html\n <Transition>\n <KeepAlive>\n <component :is=\"view\"></component>\n </KeepAlive>\n </Transition>\n ```\n Usando `include` / `exclude`: \n\n ```html\n <!-- stringa con delimitatore virgola -->\n <KeepAlive include=\"a,b\">\n <component :is=\"view\"></component>\n </KeepAlive>\n\n <!-- regex (usando `v-bind`) -->\n <KeepAlive :include=\"/a|b/\">\n <component :is=\"view\"></component>\n </KeepAlive>\n\n <!-- Array (usando `v-bind`) -->\n <KeepAlive :include=\"['a', 'b']\">\n <component :is=\"view\"></component>\n </KeepAlive>\n ```\n Utilizzo con `max`:\n\n ```html\n <KeepAlive :max=\"10\">\n <component :is=\"view\"></component>\n </KeepAlive>\n ```\n\n- **Vedi anche** [Guida - KeepAlive](https://it.vuejs.org/guide/built-ins/keep-alive.html)\n"
27
27
  },
28
28
  "attributes": [],
29
29
  "references": "api/built-in-components.html#keepalive"
@@ -32,7 +32,7 @@
32
32
  "name": "Teleport",
33
33
  "description": {
34
34
  "kind": "markdown",
35
- "value": "\nRenders its slot content to another part of the DOM.\n\n- **Props**\n\n ```ts\n interface TeleportProps {\n /**\n * Required. Specify target container.\n * Can either be a selector or an actual element.\n */\n to: string | HTMLElement\n /**\n * When `true`, the content will remain in its original\n * location instead of moved into the target container.\n * Can be changed dynamically.\n */\n disabled?: boolean\n }\n ```\n\n- **Example**\n\n Specifying target container:\n\n ```html\n <teleport to=\"#some-id\" />\n <teleport to=\".some-class\" />\n <teleport to=\"[data-teleport]\" />\n ```\n\n Conditionally disabling:\n\n ```html\n <teleport to=\"#popup\" :disabled=\"displayVideoInline\">\n <video src=\"./my-movie.mp4\">\n </teleport>\n ```\n\n- **See also** [Guide - Teleport](https://it.vuejs.org/guide/built-ins/teleport.html)\n"
35
+ "value": "\nRenderizza il contenuto dello slot in un' altra parte del DOM.\n\n- **Props**\n\n ```ts\n interface TeleportProps {\n /**\n * Obbligatoria. Specifica il container di destinazione.\n * Può essere sia un selettore o un elemento reale.\n */\n to: string | HTMLElement\n /**\n * Quando `true`, il contenuto resterà nella posizione\n * originale invece di essere spostato nel container di destinazione.\n * Può essere cambiato dinamicamente.\n */\n disabled?: boolean\n }\n ```\n\n- **Esempio**\n\n Specificando un container di destinazione\n\n ```html\n <teleport to=\"#some-id\" />\n <teleport to=\".some-class\" />\n <teleport to=\"[data-teleport]\" />\n ```\n Disabilitazione condizionale:\n\n ```html\n <teleport to=\"#popup\" :disabled=\"displayVideoInline\">\n <video src=\"./my-movie.mp4\">\n </teleport>\n ```\n\n- **Vedi anche** [Guida - Teleport](https://it.vuejs.org/guide/built-ins/teleport.html)\n"
36
36
  },
37
37
  "attributes": [],
38
38
  "references": "api/built-in-components.html#teleport"
@@ -41,7 +41,7 @@
41
41
  "name": "Suspense",
42
42
  "description": {
43
43
  "kind": "markdown",
44
- "value": "\nUsed for orchestrating nested async dependencies in a component tree.\n\n- **Props**\n\n ```ts\n interface SuspenseProps {\n timeout?: string | number\n }\n ```\n\n- **Events**\n\n - `@resolve`\n - `@pending`\n - `@fallback`\n\n- **Details**\n\n `<Suspense>` accepts two slots: the `#default` slot and the `#fallback` slot. It will display the content of the fallback slot while rendering the default slot in memory.\n\n If it encounters async dependencies ([Async Components](https://it.vuejs.org/guide/components/async.html) and components with [`async setup()`](https://it.vuejs.org/guide/built-ins/suspense.html#async-setup)) while rendering the default slot, it will wait until all of them are resolved before displaying the default slot.\n\n- **See also** [Guide - Suspense](https://it.vuejs.org/guide/built-ins/suspense.html)\n"
44
+ "value": "\nUsato per orchestrare dipendenze asincrone annidate in un albero di componenti.\n\n- **Props**\n\n ```ts\n interface SuspenseProps {\n timeout?: string | number\n }\n ```\n\n- **Eventi**\n\n - `@resolve`\n - `@pending`\n - `@fallback`\n\n- **Dettagli**\n\n `<Suspense>` accetta due slots: lo slot di `#default` e lo slot `#fallback`. Mostrerà il contenuto dello slot di fallback mentre renderizza lo slot default in memoria.\n\n Se incontra dipendenze asincrone ([Componente asincrono](https://it.vuejs.org/guide/components/async.html) e componenti con [`async setup()`](https://it.vuejs.org/guide/built-ins/suspense.html#async-setup)) mentre renderizza lo slot di default, aspetterà fino a quando tutti sono risolti prima di visualizzare lo slot di default.\n\n- **Vedi anche** [Guida - Suspense](https://it.vuejs.org/guide/built-ins/suspense.html)\n"
45
45
  },
46
46
  "attributes": [],
47
47
  "references": "api/built-in-components.html#suspense"
package/index.js CHANGED
@@ -44,7 +44,11 @@ const vue_twoslash_queries_1 = require("./lib/plugins/vue-twoslash-queries");
44
44
  const language_core_1 = require("@vue/language-core");
45
45
  const common_1 = require("@vue/typescript-plugin/lib/common");
46
46
  const collectExtractProps_1 = require("@vue/typescript-plugin/lib/requests/collectExtractProps");
47
- const componentInfos_1 = require("@vue/typescript-plugin/lib/requests/componentInfos");
47
+ const getComponentDirectives_1 = require("@vue/typescript-plugin/lib/requests/getComponentDirectives");
48
+ const getComponentEvents_1 = require("@vue/typescript-plugin/lib/requests/getComponentEvents");
49
+ const getComponentNames_1 = require("@vue/typescript-plugin/lib/requests/getComponentNames");
50
+ const getComponentProps_1 = require("@vue/typescript-plugin/lib/requests/getComponentProps");
51
+ const getElementAttrs_1 = require("@vue/typescript-plugin/lib/requests/getElementAttrs");
48
52
  const getImportPathForFile_1 = require("@vue/typescript-plugin/lib/requests/getImportPathForFile");
49
53
  const getPropertiesAtLocation_1 = require("@vue/typescript-plugin/lib/requests/getPropertiesAtLocation");
50
54
  const vscode_uri_1 = require("vscode-uri");
@@ -106,19 +110,19 @@ function getFullLanguageServicePlugins(ts, { disableAutoImportCache } = {}) {
106
110
  return await getImportPathForFile_1.getImportPathForFile.apply(requestContext, args);
107
111
  },
108
112
  async getComponentEvents(...args) {
109
- return await componentInfos_1.getComponentEvents.apply(requestContext, args);
113
+ return await getComponentEvents_1.getComponentEvents.apply(requestContext, args);
114
+ },
115
+ async getComponentDirectives(...args) {
116
+ return await getComponentDirectives_1.getComponentDirectives.apply(requestContext, args);
110
117
  },
111
118
  async getComponentNames(...args) {
112
- return await componentInfos_1.getComponentNames.apply(requestContext, args);
119
+ return await getComponentNames_1.getComponentNames.apply(requestContext, args);
113
120
  },
114
121
  async getComponentProps(...args) {
115
- return await componentInfos_1.getComponentProps.apply(requestContext, args);
122
+ return await getComponentProps_1.getComponentProps.apply(requestContext, args);
116
123
  },
117
124
  async getElementAttrs(...args) {
118
- return await componentInfos_1.getElementAttrs.apply(requestContext, args);
119
- },
120
- async getTemplateContextProps(...args) {
121
- return await componentInfos_1.getTemplateContextProps.apply(requestContext, args);
125
+ return await getElementAttrs_1.getElementAttrs.apply(requestContext, args);
122
126
  },
123
127
  async getQuickInfoAtPosition(fileName, position) {
124
128
  const languageService = context.getLanguageService();
@@ -17,7 +17,7 @@ async function convertTagName(context, uri, casing, tsPluginClient) {
17
17
  if (!(root instanceof language_core_1.VueVirtualCode)) {
18
18
  return;
19
19
  }
20
- const { template } = root._sfc;
20
+ const { template } = root.sfc;
21
21
  if (!template) {
22
22
  return;
23
23
  }
@@ -52,7 +52,7 @@ async function convertAttrName(context, uri, casing, tsPluginClient) {
52
52
  if (!(root instanceof language_core_1.VueVirtualCode)) {
53
53
  return;
54
54
  }
55
- const { template } = root._sfc;
55
+ const { template } = root.sfc;
56
56
  if (!template) {
57
57
  return;
58
58
  }
@@ -132,8 +132,8 @@ async function detect(context, uri) {
132
132
  }
133
133
  function getTagNameCase(file) {
134
134
  const result = new Set();
135
- if (file._sfc.template?.ast) {
136
- for (const element of vue.forEachElementNode(file._sfc.template.ast)) {
135
+ if (file.sfc.template?.ast) {
136
+ for (const element of vue.forEachElementNode(file.sfc.template.ast)) {
137
137
  if (element.tagType === 1) {
138
138
  if (element.tag !== (0, language_core_1.hyphenateTag)(element.tag)) {
139
139
  // TagName
@@ -157,7 +157,7 @@ function getTemplateTagsAndAttrs(sourceFile) {
157
157
  if (!(sourceFile instanceof vue.VueVirtualCode)) {
158
158
  return;
159
159
  }
160
- const ast = sourceFile._sfc.template?.ast;
160
+ const ast = sourceFile.sfc.template?.ast;
161
161
  const tags = new Map();
162
162
  if (ast) {
163
163
  for (const node of vue.forEachElementNode(ast)) {
@@ -197,6 +197,6 @@ function getTemplateTagsAndAttrs(sourceFile) {
197
197
  });
198
198
  map.set(sourceFile, getter);
199
199
  }
200
- return map.get(sourceFile).get() ?? new Map();
200
+ return map.get(sourceFile)() ?? new Map();
201
201
  }
202
202
  //# sourceMappingURL=nameCasing.js.map
@@ -1,13 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.create = create;
4
+ const language_core_1 = require("@vue/language-core");
4
5
  const volar_service_css_1 = require("volar-service-css");
6
+ const vscode_uri_1 = require("vscode-uri");
5
7
  function create() {
6
8
  const base = (0, volar_service_css_1.create)({ scssDocumentSelector: ['scss', 'postcss'] });
7
9
  return {
8
10
  ...base,
9
11
  create(context) {
10
12
  const baseInstance = base.create(context);
13
+ const { 'css/languageService': getCssLs, 'css/stylesheet': getStylesheet, } = baseInstance.provide;
11
14
  return {
12
15
  ...baseInstance,
13
16
  async provideDiagnostics(document, token) {
@@ -19,7 +22,63 @@ function create() {
19
22
  }
20
23
  return diagnostics;
21
24
  },
25
+ /**
26
+ * If the editing position is within the virtual code and navigation is enabled,
27
+ * skip the CSS renaming feature.
28
+ */
29
+ provideRenameRange(document, position) {
30
+ do {
31
+ const uri = vscode_uri_1.URI.parse(document.uri);
32
+ const decoded = context.decodeEmbeddedDocumentUri(uri);
33
+ const sourceScript = decoded && context.language.scripts.get(decoded[0]);
34
+ const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
35
+ if (!sourceScript?.generated || !virtualCode?.id.startsWith('style_')) {
36
+ break;
37
+ }
38
+ const root = sourceScript.generated.root;
39
+ if (!(root instanceof language_core_1.VueVirtualCode)) {
40
+ break;
41
+ }
42
+ const block = root.sfc.styles.find(style => style.name === decoded[1]);
43
+ if (!block) {
44
+ break;
45
+ }
46
+ let script;
47
+ for (const [key, value] of sourceScript.generated.embeddedCodes) {
48
+ if (key.startsWith('script_')) {
49
+ script = value;
50
+ break;
51
+ }
52
+ }
53
+ if (!script) {
54
+ break;
55
+ }
56
+ const offset = document.offsetAt(position) + block.startTagEnd;
57
+ for (const { sourceOffsets, lengths, data } of script.mappings) {
58
+ if (!sourceOffsets.length
59
+ || !data.navigation
60
+ || typeof data.navigation === 'object' && !data.navigation.shouldRename) {
61
+ continue;
62
+ }
63
+ const start = sourceOffsets[0];
64
+ const end = sourceOffsets.at(-1) + lengths.at(-1);
65
+ if (offset >= start && offset <= end) {
66
+ return;
67
+ }
68
+ }
69
+ } while (0);
70
+ return worker(document, (stylesheet, cssLs) => {
71
+ return cssLs.prepareRename(document, position, stylesheet);
72
+ });
73
+ }
22
74
  };
75
+ function worker(document, callback) {
76
+ const cssLs = getCssLs(document);
77
+ if (!cssLs) {
78
+ return;
79
+ }
80
+ return callback(getStylesheet(document, cssLs), cssLs);
81
+ }
23
82
  },
24
83
  };
25
84
  }
@@ -0,0 +1,3 @@
1
+ import type { TextDocument } from 'vscode-languageserver-textdocument';
2
+ export declare function sleep(ms: number): Promise<unknown>;
3
+ export declare function isTsDocument(document: TextDocument): boolean;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sleep = sleep;
4
+ exports.isTsDocument = isTsDocument;
5
+ function sleep(ms) {
6
+ return new Promise(resolve => setTimeout(resolve, ms));
7
+ }
8
+ function isTsDocument(document) {
9
+ return document.languageId === 'javascript' ||
10
+ document.languageId === 'typescript' ||
11
+ document.languageId === 'javascriptreact' ||
12
+ document.languageId === 'typescriptreact';
13
+ }
14
+ //# sourceMappingURL=utils.js.map
@@ -1,11 +1,2 @@
1
1
  import type { LanguageServiceContext, LanguageServicePlugin } from '@volar/language-service';
2
- import type * as ts from 'typescript';
3
- import type { TextDocument } from 'vscode-languageserver-textdocument';
4
2
  export declare function create(ts: typeof import('typescript'), getTsPluginClient?: (context: LanguageServiceContext) => typeof import('@vue/typescript-plugin/lib/client') | undefined): LanguageServicePlugin;
5
- export declare function isTsDocument(document: TextDocument): boolean;
6
- export declare function isCharacterTyping(document: TextDocument, change: {
7
- text: string;
8
- rangeOffset: number;
9
- rangeLength: number;
10
- }): boolean;
11
- export declare function isBlacklistNode(ts: typeof import('typescript'), node: ts.Node, pos: number, allowAccessDotValue: boolean): boolean;
@@ -1,20 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.create = create;
4
- exports.isTsDocument = isTsDocument;
5
- exports.isCharacterTyping = isCharacterTyping;
6
- exports.isBlacklistNode = isBlacklistNode;
7
4
  const language_core_1 = require("@vue/language-core");
8
5
  const vscode_uri_1 = require("vscode-uri");
9
- const asts = new WeakMap();
10
- function getAst(ts, fileName, snapshot, scriptKind) {
11
- let ast = asts.get(snapshot);
12
- if (!ast) {
13
- ast = ts.createSourceFile(fileName, snapshot.getText(0, snapshot.getLength()), ts.ScriptTarget.Latest, undefined, scriptKind);
14
- asts.set(snapshot, ast);
15
- }
16
- return ast;
17
- }
6
+ const utils_1 = require("./utils");
18
7
  function create(ts, getTsPluginClient) {
19
8
  return {
20
9
  name: 'vue-autoinsert-dotvalue',
@@ -33,7 +22,7 @@ function create(ts, getTsPluginClient) {
33
22
  if (document.offsetAt(selection) !== change.rangeOffset + change.text.length) {
34
23
  return;
35
24
  }
36
- if (!isTsDocument(document)) {
25
+ if (!(0, utils_1.isTsDocument)(document)) {
37
26
  return;
38
27
  }
39
28
  if (!isCharacterTyping(document, change)) {
@@ -41,7 +30,7 @@ function create(ts, getTsPluginClient) {
41
30
  }
42
31
  const req = ++currentReq;
43
32
  // Wait for tsserver to sync
44
- await sleep(250);
33
+ await (0, utils_1.sleep)(250);
45
34
  if (req !== currentReq) {
46
35
  return;
47
36
  }
@@ -53,41 +42,42 @@ function create(ts, getTsPluginClient) {
53
42
  const decoded = context.decodeEmbeddedDocumentUri(uri);
54
43
  const sourceScript = decoded && context.language.scripts.get(decoded[0]);
55
44
  const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
56
- if (!sourceScript) {
45
+ if (!sourceScript?.generated || !virtualCode) {
46
+ return;
47
+ }
48
+ const root = sourceScript.generated.root;
49
+ if (!(root instanceof language_core_1.VueVirtualCode)) {
50
+ return;
51
+ }
52
+ const { sfc } = root;
53
+ const blocks = [sfc.script, sfc.scriptSetup].filter(block => !!block);
54
+ if (!blocks.length) {
57
55
  return;
58
56
  }
59
- let ast;
60
57
  let sourceCodeOffset = document.offsetAt(selection);
61
- const fileName = context.project.typescript?.uriConverter.asFileName(sourceScript.id)
62
- ?? sourceScript.id.fsPath.replace(/\\/g, '/');
63
- if (sourceScript.generated) {
64
- const serviceScript = sourceScript.generated.languagePlugin.typescript?.getServiceScript(sourceScript.generated.root);
65
- if (!serviceScript || serviceScript?.code !== virtualCode) {
66
- return;
67
- }
68
- ast = getAst(ts, fileName, virtualCode.snapshot, serviceScript.scriptKind);
69
- let mapped = false;
70
- for (const [_sourceScript, map] of context.language.maps.forEach(virtualCode)) {
71
- for (const [sourceOffset] of map.toSourceLocation(document.offsetAt(selection))) {
72
- sourceCodeOffset = sourceOffset;
73
- mapped = true;
74
- break;
75
- }
76
- if (mapped) {
77
- break;
78
- }
58
+ let mapped = false;
59
+ for (const [, map] of context.language.maps.forEach(virtualCode)) {
60
+ for (const [sourceOffset] of map.toSourceLocation(sourceCodeOffset)) {
61
+ sourceCodeOffset = sourceOffset;
62
+ mapped = true;
63
+ break;
79
64
  }
80
- if (!mapped) {
81
- return;
65
+ if (mapped) {
66
+ break;
82
67
  }
83
68
  }
84
- else {
85
- ast = getAst(ts, fileName, sourceScript.snapshot);
86
- }
87
- if (isBlacklistNode(ts, ast, document.offsetAt(selection), false)) {
69
+ if (!mapped) {
88
70
  return;
89
71
  }
90
- const props = await tsPluginClient?.getPropertiesAtLocation(fileName, sourceCodeOffset) ?? [];
72
+ for (const { ast, startTagEnd, endTagStart } of blocks) {
73
+ if (sourceCodeOffset < startTagEnd || sourceCodeOffset > endTagStart) {
74
+ continue;
75
+ }
76
+ if (isBlacklistNode(ts, ast, sourceCodeOffset - startTagEnd, false)) {
77
+ return;
78
+ }
79
+ }
80
+ const props = await tsPluginClient?.getPropertiesAtLocation(root.fileName, sourceCodeOffset) ?? [];
91
81
  if (props.some(prop => prop === 'value')) {
92
82
  return '${1:.value}';
93
83
  }
@@ -96,15 +86,6 @@ function create(ts, getTsPluginClient) {
96
86
  },
97
87
  };
98
88
  }
99
- function sleep(ms) {
100
- return new Promise(resolve => setTimeout(resolve, ms));
101
- }
102
- function isTsDocument(document) {
103
- return document.languageId === 'javascript' ||
104
- document.languageId === 'typescript' ||
105
- document.languageId === 'javascriptreact' ||
106
- document.languageId === 'typescriptreact';
107
- }
108
89
  const charReg = /\w/;
109
90
  function isCharacterTyping(document, change) {
110
91
  const lastCharacter = change.text[change.text.length - 1];
@@ -0,0 +1,2 @@
1
+ import type { LanguageServicePlugin } from '@volar/language-service';
2
+ export declare function create(): LanguageServicePlugin;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.create = create;
4
+ function create() {
5
+ return {
6
+ name: 'vue-autoinsert-selfClosing',
7
+ capabilities: {
8
+ autoInsertionProvider: {
9
+ triggerCharacters: ['/'],
10
+ configurationSections: ['vue.autoInsert.selfClosing'],
11
+ },
12
+ },
13
+ create(context) {
14
+ return {
15
+ async provideAutoInsertSnippet(document, selection, change) {
16
+ if (document.languageId !== 'html') {
17
+ return;
18
+ }
19
+ const enabled = await context.env.getConfiguration?.('vue.autoInsert.selfClosing') ?? true;
20
+ if (!enabled) {
21
+ return;
22
+ }
23
+ if (change.text === '{}'
24
+ && document.getText().slice(change.rangeOffset - 1, change.rangeOffset + 3) === '{{}}'
25
+ && document.offsetAt(selection) === change.rangeOffset + 1) {
26
+ return ` $0 `;
27
+ }
28
+ },
29
+ };
30
+ },
31
+ };
32
+ }
33
+ //# sourceMappingURL=vue-autoinsert-self-closing.js.map
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.create = create;
4
4
  const language_core_1 = require("@vue/language-core");
5
5
  const vscode_uri_1 = require("vscode-uri");
6
- const vue_autoinsert_dotvalue_1 = require("./vue-autoinsert-dotvalue");
6
+ const utils_1 = require("./utils");
7
7
  function create() {
8
8
  return {
9
9
  name: 'vue-complete-define-assignment',
@@ -14,7 +14,7 @@ function create() {
14
14
  return {
15
15
  isAdditionalCompletion: true,
16
16
  async provideCompletionItems(document) {
17
- if (!(0, vue_autoinsert_dotvalue_1.isTsDocument)(document)) {
17
+ if (!(0, utils_1.isTsDocument)(document)) {
18
18
  return;
19
19
  }
20
20
  const enabled = await context.env.getConfiguration?.('vue.complete.defineAssignment') ?? true;
@@ -32,9 +32,10 @@ function create() {
32
32
  if (!(root instanceof language_core_1.VueVirtualCode)) {
33
33
  return;
34
34
  }
35
- const codegen = language_core_1.tsCodegen.get(root._sfc);
36
- const scriptSetup = root._sfc.scriptSetup;
37
- const scriptSetupRanges = codegen?.scriptSetupRanges.get();
35
+ const { sfc } = root;
36
+ const codegen = language_core_1.tsCodegen.get(sfc);
37
+ const scriptSetup = sfc.scriptSetup;
38
+ const scriptSetupRanges = codegen?.getScriptSetupRanges();
38
39
  if (!scriptSetup || !scriptSetupRanges) {
39
40
  return;
40
41
  }
@@ -1,2 +1,6 @@
1
1
  import type { LanguageServicePlugin } from '@volar/language-service';
2
+ /**
3
+ * A language service plugin that provides completion for Vue directive comments,
4
+ * e.g. if user is writing `<!-- |` in they'll be provided completions for `@vue-expect-error`, `@vue-generic`, etc.
5
+ */
2
6
  export declare function create(): LanguageServicePlugin;
@@ -8,6 +8,10 @@ const cmds = [
8
8
  ['vue-generic', 'vue-generic {$1}'],
9
9
  ];
10
10
  const directiveCommentReg = /<!--\s*@/;
11
+ /**
12
+ * A language service plugin that provides completion for Vue directive comments,
13
+ * e.g. if user is writing `<!-- |` in they'll be provided completions for `@vue-expect-error`, `@vue-generic`, etc.
14
+ */
11
15
  function create() {
12
16
  return {
13
17
  name: 'vue-directive-comments',