@markuplint/vue-spec 5.3.0 → 5.5.0

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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,22 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [5.5.0](https://github.com/markuplint/markuplint/compare/v5.4.0...v5.5.0) (2026-11-10)
7
+
8
+ ### Features
9
+
10
+ * **vue-spec:** declare how Vue renders a literal written as code ([aaff283](https://github.com/markuplint/markuplint/commit/aaff283dceed86bd9e8fde1ffe8d3b37055a826c))
11
+ * **vue-spec:** declare that Vue appends the children of a template without a directive to it ([370f2d5](https://github.com/markuplint/markuplint/commit/370f2d5848d693ef8f01c7d3bacaad02a123dfc8))
12
+
13
+
14
+ # [5.4.0](https://github.com/markuplint/markuplint/compare/v5.3.0...v5.4.0) (2026-10-29)
15
+
16
+ **Note:** Version bump only for package @markuplint/vue-spec
17
+
18
+
19
+
20
+
21
+
6
22
  # [5.3.0](https://github.com/markuplint/markuplint/compare/v5.2.0...v5.3.0) (2026-10-21)
7
23
 
8
24
  ### Bug Fixes
package/lib/index.js CHANGED
@@ -47,6 +47,10 @@ const spec = {
47
47
  pattern: '^(?:v-bind:|:)([^.]+)$',
48
48
  potentialName: '$1',
49
49
  isDynamicValue: true,
50
+ // The value is a JavaScript expression that becomes the attribute value, so a literal in it
51
+ // is rendered as Vue renders it (`literalValues` below). The same-name shorthand `:attr`
52
+ // has no value, which `MLAttr` does not read as a literal.
53
+ expressionLanguage: 'javascript',
50
54
  // Vue merges static `class`/`style` with their bound equivalents,
51
55
  // so these attributes may legitimately appear alongside `:class`/`:style`
52
56
  isDuplicatable: ['class', 'style'],
@@ -77,6 +81,51 @@ const spec = {
77
81
  isDynamicValue: true,
78
82
  },
79
83
  ],
84
+ /**
85
+ * Only a `template` with `v-if`, `v-else-if`, `v-else`, `v-for` or `v-slot` is a fragment of Vue
86
+ * (`isFragmentTemplate` of `@vue/compiler-core`). Any other one is an element, which the client
87
+ * creates and appends each child to (`insert` of `nodeOps` in `@vue/runtime-dom` calls
88
+ * `parent.insertBefore`), so the children are in the tree of the document, not in `content`.
89
+ * Known limitations: Vue puts the children in `content` when it renders static markup as a
90
+ * string, and when it hydrates server output it replaces the element with its content.
91
+ */
92
+ templateContent: 'in-place',
93
+ /**
94
+ * How Vue renders a literal in `:attr="…"` (`ssrRenderDynamicAttr` of `@vue/server-renderer`), where it
95
+ * differs from the default of `@markuplint/ml-core`. The docs of Vue say of a boolean attribute:
96
+ *
97
+ * > It will also be included if the value is an empty string, maintaining consistency with `<button disabled="">`.
98
+ *
99
+ * So the table says:
100
+ *
101
+ * - A boolean attribute (`isBooleanAttr` of `@vue/shared`) is present for any truthy value and for the
102
+ * empty string (`includeBooleanAttr`)
103
+ * - `class` and `style` are always output, and a value that is not a string, an array or an object
104
+ * is `""` (`ssrRenderClass`, `ssrRenderStyle`)
105
+ *
106
+ * What it does not tell, which is not expressed by a table (the rendering does not affect a rule, or
107
+ * the markup is invalid and `invalid-attr` reports it):
108
+ *
109
+ * - `:value` of `<input>` and `<option>` sets the DOM property, not the attribute (`textarea` is not
110
+ * output by the server): a literal in it is rendered as the default does
111
+ * - `key` and `ref` are not output by the server, as they are not attributes of the DOM, but a static
112
+ * `key="x"` is seen as an attribute too
113
+ * - The client renders `:disabled="false"` on an element that has no boolean attribute `disabled` as
114
+ * `disabled="false"`; the server does not output it, and the table follows the server
115
+ * - A number other than `0` on `class` and `style` is `""` too, which a table cannot list: it is `"1"` here
116
+ *
117
+ * @see https://vuejs.org/guide/essentials/template-syntax.html#boolean-attributes
118
+ * @see https://github.com/vuejs/core/blob/main/packages/server-renderer/src/helpers/ssrRenderAttrs.ts#ssrRenderDynamicAttr
119
+ * @see https://github.com/vuejs/core/blob/main/packages/shared/src/domAttrConfig.ts#isBooleanAttr
120
+ * @see https://github.com/vuejs/core/blob/main/packages/shared/src/domAttrConfig.ts#includeBooleanAttr
121
+ */
122
+ literalValues: {
123
+ booleanAttrs: { '""': '' },
124
+ attrs: {
125
+ class: { true: '', false: '', null: '', undefined: '', '0': '' },
126
+ style: { true: '', false: '', null: '', undefined: '', '0': '' },
127
+ },
128
+ },
80
129
  def: {
81
130
  '#globalAttrs': {
82
131
  '#extends': {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markuplint/vue-spec",
3
- "version": "5.3.0",
3
+ "version": "5.5.0",
4
4
  "description": "Extended specification for tags and attributes in Vue",
5
5
  "repository": {
6
6
  "type": "git",
@@ -28,7 +28,7 @@
28
28
  "clean": "tsc --build --clean tsconfig.build.json"
29
29
  },
30
30
  "dependencies": {
31
- "@markuplint/ml-spec": "5.3.0"
31
+ "@markuplint/ml-spec": "5.5.0"
32
32
  },
33
- "gitHead": "f587cf0206c8426e57369a48d6d5fb22306eafde"
33
+ "gitHead": "fedebcfd56eaec4642e68643b2f9e10750d810e1"
34
34
  }