@markuplint/vue-parser 3.9.0 → 4.0.0-alpha.1

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/lib/attr.js CHANGED
@@ -1,11 +1,7 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.attr = void 0;
4
1
  const duplicatableAttrs = ['class', 'style'];
5
- function attr(
2
+ export function attr(
6
3
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
7
4
  attr) {
8
- var _a, _b, _c, _d;
9
5
  if (attr.type !== 'html-attr') {
10
6
  const name = attr.potentialName;
11
7
  if (duplicatableAttrs.includes(name)) {
@@ -17,7 +13,7 @@ attr) {
17
13
  /**
18
14
  * `v-on`
19
15
  */
20
- const [, directive, potentialName, modifier] = (_a = attr.name.raw.match(/^(v-on:|@)([^.]+)(?:\.([^.]+))?$/i)) !== null && _a !== void 0 ? _a : [];
16
+ const [, directive, potentialName, modifier] = attr.name.raw.match(/^(v-on:|@)([^.]+)(?:\.([^.]+))?$/i) ?? [];
21
17
  if (directive && potentialName) {
22
18
  return {
23
19
  ...attr,
@@ -32,7 +28,7 @@ attr) {
32
28
  /**
33
29
  * `v-bind`
34
30
  */
35
- const [, directive, potentialName, modifier] = (_b = attr.name.raw.match(/^(v-bind:|:)([^.]+)(?:\.([^.]+))?$/i)) !== null && _b !== void 0 ? _b : [];
31
+ const [, directive, potentialName, modifier] = attr.name.raw.match(/^(v-bind:|:)([^.]+)(?:\.([^.]+))?$/i) ?? [];
36
32
  if (directive && potentialName) {
37
33
  if (duplicatableAttrs.includes(potentialName.toLowerCase())) {
38
34
  attr.isDuplicatable = true;
@@ -58,7 +54,7 @@ attr) {
58
54
  case '.prop':
59
55
  case '.camel':
60
56
  default: {
61
- const name = `v-bind:${potentialName}${modifier !== null && modifier !== void 0 ? modifier : ''}`;
57
+ const name = `v-bind:${potentialName}${modifier ?? ''}`;
62
58
  return {
63
59
  ...attr,
64
60
  potentialName: attr.name.raw !== name ? name : undefined,
@@ -74,7 +70,7 @@ attr) {
74
70
  /**
75
71
  * `v-model`
76
72
  */
77
- const [, directive, modifier] = (_c = attr.name.raw.match(/^(v-model)(?:\.([^.]+))?$/i)) !== null && _c !== void 0 ? _c : [];
73
+ const [, directive, modifier] = attr.name.raw.match(/^(v-model)(?:\.([^.]+))?$/i) ?? [];
78
74
  if (directive) {
79
75
  // TODO: Supporting for `v-model` https://github.com/markuplint/markuplint/pull/681
80
76
  return {
@@ -89,7 +85,7 @@ attr) {
89
85
  /**
90
86
  * `v-slot`
91
87
  */
92
- const [, , slotName] = (_d = attr.name.raw.match(/^(v-slot:|#)(.+)$/i)) !== null && _d !== void 0 ? _d : [];
88
+ const [, , slotName] = attr.name.raw.match(/^(v-slot:|#)(.+)$/i) ?? [];
93
89
  const name = `v-slot:${slotName}`;
94
90
  if (slotName) {
95
91
  return {
@@ -110,4 +106,3 @@ attr) {
110
106
  }
111
107
  return attr;
112
108
  }
113
- exports.attr = attr;
package/lib/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { parse } from './parse';
1
+ export { parse } from './parse.js';
2
2
  export declare const endTag = "xml";
package/lib/index.js CHANGED
@@ -1,6 +1,2 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.endTag = exports.parse = void 0;
4
- var parse_1 = require("./parse");
5
- Object.defineProperty(exports, "parse", { enumerable: true, get: function () { return parse_1.parse; } });
6
- exports.endTag = 'xml';
1
+ export { parse } from './parse.js';
2
+ export const endTag = 'xml';
package/lib/parse.js CHANGED
@@ -1,19 +1,15 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parse = void 0;
4
- const tslib_1 = require("tslib");
5
- const html_parser_1 = require("@markuplint/html-parser");
6
- const parser_utils_1 = require("@markuplint/parser-utils");
7
- const attr_1 = require("./attr");
8
- const vue_parser_1 = tslib_1.__importDefault(require("./vue-parser"));
9
- const parse = (rawCode, options) => {
1
+ import { parseRawTag } from '@markuplint/html-parser';
2
+ import { flattenNodes, getEndCol, getEndLine, uuid, ParserError, detectElementType } from '@markuplint/parser-utils';
3
+ import { attr } from './attr.js';
4
+ import vueParse from './vue-parser/index.js';
5
+ export const parse = (rawCode, options) => {
10
6
  let ast;
11
7
  try {
12
- ast = (0, vue_parser_1.default)(rawCode);
8
+ ast = vueParse(rawCode);
13
9
  }
14
10
  catch (err) {
15
11
  if (err instanceof SyntaxError && 'lineNumber' in err && 'column' in err) {
16
- throw new parser_utils_1.ParserError(
12
+ throw new ParserError(
17
13
  // @ts-ignore
18
14
  err.message, {
19
15
  // @ts-ignore
@@ -30,14 +26,14 @@ const parse = (rawCode, options) => {
30
26
  };
31
27
  }
32
28
  const nodeList = ast.templateBody
33
- ? (0, parser_utils_1.flattenNodes)(traverse(ast.templateBody, null, rawCode, options), rawCode)
29
+ ? flattenNodes(traverse(ast.templateBody, null, rawCode, options), rawCode)
34
30
  : [];
35
31
  // Remove `</template>`
36
32
  const templateEndTagIndex = nodeList.findIndex(node => /\s*<\/\s*template\s*>\s*/i.test(node.raw));
37
33
  if (templateEndTagIndex !== -1) {
38
34
  const templateEndTag = nodeList[templateEndTagIndex];
39
35
  for (const node of nodeList) {
40
- if (node.nextNode && node.nextNode.uuid === (templateEndTag === null || templateEndTag === void 0 ? void 0 : templateEndTag.uuid)) {
36
+ if (node.nextNode && node.nextNode.uuid === templateEndTag?.uuid) {
41
37
  node.nextNode = null;
42
38
  }
43
39
  }
@@ -48,7 +44,6 @@ const parse = (rawCode, options) => {
48
44
  isFragment: true,
49
45
  };
50
46
  };
51
- exports.parse = parse;
52
47
  function traverse(
53
48
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
54
49
  rootNode, parentNode = null, rawHtml, options) {
@@ -87,11 +82,11 @@ parentNode, rawHtml, options) {
87
82
  const endLine = originNode.loc.end.line;
88
83
  const startCol = originNode.loc.start.column + 1;
89
84
  const endCol = originNode.loc.end.column + 1;
90
- const raw = rawHtml.slice(startOffset, endOffset !== null && endOffset !== void 0 ? endOffset : startOffset);
85
+ const raw = rawHtml.slice(startOffset, endOffset ?? startOffset);
91
86
  switch (originNode.type) {
92
87
  case 'VText': {
93
88
  const node = {
94
- uuid: (0, parser_utils_1.uuid)(),
89
+ uuid: uuid(),
95
90
  raw,
96
91
  startOffset,
97
92
  endOffset,
@@ -111,7 +106,7 @@ parentNode, rawHtml, options) {
111
106
  }
112
107
  case 'VExpressionContainer': {
113
108
  return {
114
- uuid: (0, parser_utils_1.uuid)(),
109
+ uuid: uuid(),
115
110
  raw,
116
111
  startOffset,
117
112
  endOffset,
@@ -131,16 +126,16 @@ parentNode, rawHtml, options) {
131
126
  default: {
132
127
  const tagLoc = originNode.startTag;
133
128
  const startTagRaw = rawHtml.slice(tagLoc.range[0], tagLoc.range[1]);
134
- const tagTokens = (0, html_parser_1.parseRawTag)(startTagRaw, startLine, startCol, startOffset);
129
+ const tagTokens = parseRawTag(startTagRaw, startLine, startCol, startOffset);
135
130
  const tagName = tagTokens.tagName;
136
131
  let endTag = null;
137
132
  const endTagLoc = originNode.endTag;
138
133
  if (endTagLoc) {
139
134
  const endTagRaw = rawHtml.slice(endTagLoc.range[0], endTagLoc.range[1]);
140
- const endTagTokens = (0, html_parser_1.parseRawTag)(endTagRaw, endTagLoc.loc.start.line, endTagLoc.loc.start.column, endTagLoc.range[0]);
135
+ const endTagTokens = parseRawTag(endTagRaw, endTagLoc.loc.start.line, endTagLoc.loc.start.column, endTagLoc.range[0]);
141
136
  const endTagName = endTagTokens.tagName;
142
137
  endTag = {
143
- uuid: (0, parser_utils_1.uuid)(),
138
+ uuid: uuid(),
144
139
  raw: endTagRaw,
145
140
  startOffset: endTagLoc.range[0],
146
141
  endOffset: endTagLoc.range[1],
@@ -163,18 +158,18 @@ parentNode, rawHtml, options) {
163
158
  };
164
159
  }
165
160
  const startTag = {
166
- uuid: (0, parser_utils_1.uuid)(),
161
+ uuid: uuid(),
167
162
  raw: startTagRaw,
168
163
  startOffset,
169
164
  endOffset: startOffset + startTagRaw.length,
170
165
  startLine,
171
- endLine: (0, parser_utils_1.getEndLine)(startTagRaw, startLine),
166
+ endLine: getEndLine(startTagRaw, startLine),
172
167
  startCol,
173
- endCol: (0, parser_utils_1.getEndCol)(startTagRaw, startCol),
168
+ endCol: getEndCol(startTagRaw, startCol),
174
169
  nodeName: tagName,
175
170
  type: 'starttag',
176
171
  namespace: originNode.namespace,
177
- elementType: (0, parser_utils_1.detectElementType)(tagName, options === null || options === void 0 ? void 0 : options.authoredElementName,
172
+ elementType: detectElementType(tagName, options?.authoredElementName,
178
173
  /**
179
174
  * @see https://vuejs.org/api/built-in-components.html
180
175
  * @see https://vuejs.org/api/built-in-special-elements.html
@@ -190,7 +185,7 @@ parentNode, rawHtml, options) {
190
185
  // Backward compatibility
191
186
  /^[A-Z]/,
192
187
  ]),
193
- attributes: tagTokens.attrs.map(attr_1.attr),
188
+ attributes: tagTokens.attrs.map(attr),
194
189
  hasSpreadAttr: false,
195
190
  parentNode,
196
191
  prevNode,
@@ -1,9 +1,5 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const tslib_1 = require("tslib");
4
- const VueESLintParser = tslib_1.__importStar(require("vue-eslint-parser"));
5
- function vueParse(vueTemplate) {
1
+ import * as VueESLintParser from 'vue-eslint-parser';
2
+ export default function vueParse(vueTemplate) {
6
3
  const ast = VueESLintParser.parse(vueTemplate, { parser: false });
7
4
  return ast;
8
5
  }
9
- exports.default = vueParse;
package/package.json CHANGED
@@ -1,12 +1,17 @@
1
1
  {
2
2
  "name": "@markuplint/vue-parser",
3
- "version": "3.9.0",
3
+ "version": "4.0.0-alpha.1",
4
4
  "description": "Vue parser for markuplint",
5
5
  "repository": "git@github.com:markuplint/markuplint.git",
6
6
  "author": "Yusuke Hirao <yusukehirao@me.com>",
7
7
  "license": "MIT",
8
8
  "private": false,
9
- "main": "lib/index.js",
9
+ "type": "module",
10
+ "exports": {
11
+ ".": {
12
+ "import": "./lib/index.js"
13
+ }
14
+ },
10
15
  "types": "lib/index.d.ts",
11
16
  "publishConfig": {
12
17
  "access": "public"
@@ -16,11 +21,11 @@
16
21
  "clean": "tsc --build --clean"
17
22
  },
18
23
  "dependencies": {
19
- "@markuplint/html-parser": "3.10.0",
20
- "@markuplint/ml-ast": "3.2.0",
21
- "@markuplint/parser-utils": "3.10.0",
22
- "tslib": "^2.6.0",
24
+ "@markuplint/html-parser": "4.0.0-alpha.1",
25
+ "@markuplint/ml-ast": "4.0.0-alpha.1",
26
+ "@markuplint/parser-utils": "4.0.0-alpha.1",
27
+ "tslib": "^2.6.1",
23
28
  "vue-eslint-parser": "^9.3.1"
24
29
  },
25
- "gitHead": "4ab20276db48a6acb29a923ea8666890ca853442"
30
+ "gitHead": "22502ee22a378ae766033d687dbc0443e5ed35dc"
26
31
  }
@@ -1,455 +0,0 @@
1
- const { nodeListToDebugMaps } = require('@markuplint/parser-utils');
2
-
3
- const { parse } = require('../lib/');
4
-
5
- describe('parser', () => {
6
- it('empty', () => {
7
- const doc = parse('');
8
- expect(doc.nodeList).toStrictEqual([]);
9
- expect(doc.nodeList.length).toBe(0);
10
- });
11
-
12
- it('syntax error', () => {
13
- expect(() => {
14
- parse('"');
15
- }).toThrow('Unterminated string constant');
16
- });
17
-
18
- it('silent syntax error', () => {
19
- const doc = parse('<!--');
20
- expect(doc.nodeList).toStrictEqual([]);
21
- expect(doc.nodeList.length).toBe(0);
22
- });
23
-
24
- it('template empty', () => {
25
- const doc = parse('<template></template>');
26
- expect(doc.nodeList).toStrictEqual([]);
27
- expect(doc.nodeList.length).toBe(0);
28
- });
29
-
30
- it('<div />', () => {
31
- const doc = parse('<template><div /></template>');
32
- expect(doc.nodeList[0].nodeName).toBe('div');
33
- expect(doc.nodeList.length).toBe(1);
34
- });
35
-
36
- it('<div></div>', () => {
37
- const doc = parse('<template><div></div></template>');
38
- expect(doc.nodeList[0].nodeName).toBe('div');
39
- expect(doc.nodeList[1].nodeName).toBe('div');
40
- expect(doc.nodeList.length).toBe(2);
41
- });
42
-
43
- it('text only', () => {
44
- const doc = parse('<template>text</template>');
45
- expect(doc.nodeList[0].nodeName).toBe('#text');
46
- expect(doc.nodeList[0].raw).toBe('text');
47
- expect(doc.nodeList.length).toBe(1);
48
- });
49
-
50
- it('fragments', () => {
51
- const doc = parse('<template><header></header><main></main><footer></footer></template>');
52
- expect(doc.nodeList[0].nodeName).toBe('header');
53
- expect(doc.nodeList[1].nodeName).toBe('header');
54
- expect(doc.nodeList[2].nodeName).toBe('main');
55
- expect(doc.nodeList[3].nodeName).toBe('main');
56
- expect(doc.nodeList[4].nodeName).toBe('footer');
57
- expect(doc.nodeList[5].nodeName).toBe('footer');
58
- expect(doc.nodeList.length).toBe(6);
59
- });
60
-
61
- it('standard code', () => {
62
- const doc = parse(`
63
- <template>
64
- <script>
65
- const i = 0;
66
- </script>
67
- <!comment-node>
68
- {{ CodeExpression }}
69
- <div>
70
- text&amp;div
71
- </div>
72
- <table>
73
- <tr>
74
- <th>header</th>
75
- <td>cell</td>
76
- </tr>
77
- </table>
78
- <table>
79
- <tbody>
80
- <tr>
81
- <th>header</th>
82
- <td>cell</td>
83
- </tr>
84
- </tbody>
85
- </table>
86
- <img src="path/to" />
87
- invalid-indent
88
-
89
- <?template engine;
90
- $var = '<html attr="value">text</html>'
91
- ?>
92
-
93
- <%template engine;
94
- $var = '<html attr="value">text</html>'
95
- %>
96
-
97
- </expected>
98
- <div>
99
- text-node
100
- </template>
101
- `);
102
- const map = nodeListToDebugMaps(doc.nodeList);
103
- expect(map).toStrictEqual([
104
- '[2:12]>[3:3](12,15)#text: ⏎→→',
105
- '[3:3]>[3:11](15,23)script: <script>',
106
- '[3:11]>[5:3](23,42)#text: ⏎→→→const␣i␣=␣0;⏎→→',
107
- '[5:3]>[5:12](42,51)script: </script>',
108
- '[5:12]>[7:3](51,72)#text: ⏎→→⏎→→',
109
- '[7:3]>[7:23](72,92)#vue-expression-container: {{␣CodeExpression␣}}',
110
- '[7:23]>[8:3](92,95)#text: ⏎→→',
111
- '[8:3]>[8:8](95,100)div: <div>',
112
- '[8:8]>[10:3](100,119)#text: ⏎→→→text&amp;div⏎→→',
113
- '[10:3]>[10:9](119,125)div: </div>',
114
- '[10:9]>[11:3](125,128)#text: ⏎→→',
115
- '[11:3]>[11:10](128,135)table: <table>',
116
- '[11:10]>[12:4](135,139)#text: ⏎→→→',
117
- '[12:4]>[12:8](139,143)tr: <tr>',
118
- '[12:8]>[13:5](143,148)#text: ⏎→→→→',
119
- '[13:5]>[13:9](148,152)th: <th>',
120
- '[13:9]>[13:15](152,158)#text: header',
121
- '[13:15]>[13:20](158,163)th: </th>',
122
- '[13:20]>[14:5](163,168)#text: ⏎→→→→',
123
- '[14:5]>[14:9](168,172)td: <td>',
124
- '[14:9]>[14:13](172,176)#text: cell',
125
- '[14:13]>[14:18](176,181)td: </td>',
126
- '[14:18]>[15:4](181,185)#text: ⏎→→→',
127
- '[15:4]>[15:9](185,190)tr: </tr>',
128
- '[15:9]>[16:3](190,193)#text: ⏎→→',
129
- '[16:3]>[16:11](193,201)table: </table>',
130
- '[16:11]>[17:3](201,204)#text: ⏎→→',
131
- '[17:3]>[17:10](204,211)table: <table>',
132
- '[17:10]>[18:4](211,215)#text: ⏎→→→',
133
- '[18:4]>[18:11](215,222)tbody: <tbody>',
134
- '[18:11]>[19:5](222,227)#text: ⏎→→→→',
135
- '[19:5]>[19:9](227,231)tr: <tr>',
136
- '[19:9]>[20:6](231,237)#text: ⏎→→→→→',
137
- '[20:6]>[20:10](237,241)th: <th>',
138
- '[20:10]>[20:16](241,247)#text: header',
139
- '[20:16]>[20:21](247,252)th: </th>',
140
- '[20:21]>[21:6](252,258)#text: ⏎→→→→→',
141
- '[21:6]>[21:10](258,262)td: <td>',
142
- '[21:10]>[21:14](262,266)#text: cell',
143
- '[21:14]>[21:19](266,271)td: </td>',
144
- '[21:19]>[22:5](271,276)#text: ⏎→→→→',
145
- '[22:5]>[22:10](276,281)tr: </tr>',
146
- '[22:10]>[23:4](281,285)#text: ⏎→→→',
147
- '[23:4]>[23:12](285,293)tbody: </tbody>',
148
- '[23:12]>[24:3](293,296)#text: ⏎→→',
149
- '[24:3]>[24:11](296,304)table: </table>',
150
- '[24:11]>[25:3](304,307)#text: ⏎→→',
151
- '[25:3]>[25:24](307,328)img: <img␣src="path/to"␣/>',
152
- "[25:24]>[33:12](328,451)#text: ⏎→→→→invalid-indent⏎⏎→→text'⏎→→?>⏎⏎→→<%template␣engine;⏎→→→$var␣=␣'",
153
- '[33:12]>[33:31](451,470)html: <html␣attr="value">',
154
- '[33:31]>[33:35](470,474)#text: text',
155
- '[33:35]>[33:42](474,481)html: </html>',
156
- "[33:42]>[37:3](481,505)#text: '⏎→→%>⏎⏎→→⏎→→",
157
- '[37:3]>[37:8](505,510)div: <div>',
158
- '[37:8]>[39:2](510,523)#text: ⏎→text-node⏎→',
159
- ]);
160
- });
161
-
162
- it('<template>', () => {
163
- const doc = parse(`
164
- <template>
165
- <script>
166
- const i = 0;
167
- </script>
168
- <!comment-node>
169
- <!-- html-comment -->
170
- <div>
171
- text&amp;div
172
- </div>
173
- <table>
174
- <tr>
175
- <th>header</th>
176
- <td>cell</td>
177
- </tr>
178
- </table>
179
- <table>
180
- <tbody>
181
- <tr>
182
- <th>header</th>
183
- <td>cell</td>
184
- </tr>
185
- </tbody>
186
- </table>
187
- <img src="path/to" />
188
- invalid-indent
189
-
190
- <?template engine;
191
- $var = '<html attr="value">text</html>'
192
- ?>
193
-
194
- <%template engine;
195
- $var = '<html attr="value">text</html>'
196
- %>
197
-
198
- </expected>
199
- <div>
200
- text-node
201
- </template>
202
- `);
203
- const map = nodeListToDebugMaps(doc.nodeList);
204
- expect(map).toStrictEqual([
205
- '[2:12]>[3:3](12,15)#text: ⏎→→',
206
- '[3:3]>[3:11](15,23)script: <script>',
207
- '[3:11]>[5:3](23,42)#text: ⏎→→→const␣i␣=␣0;⏎→→',
208
- '[5:3]>[5:12](42,51)script: </script>',
209
- '[5:12]>[8:3](51,96)#text: ⏎→→⏎→→⏎→→',
210
- '[8:3]>[8:8](96,101)div: <div>',
211
- '[8:8]>[10:3](101,120)#text: ⏎→→→text&amp;div⏎→→',
212
- '[10:3]>[10:9](120,126)div: </div>',
213
- '[10:9]>[11:3](126,129)#text: ⏎→→',
214
- '[11:3]>[11:10](129,136)table: <table>',
215
- '[11:10]>[12:4](136,140)#text: ⏎→→→',
216
- '[12:4]>[12:8](140,144)tr: <tr>',
217
- '[12:8]>[13:5](144,149)#text: ⏎→→→→',
218
- '[13:5]>[13:9](149,153)th: <th>',
219
- '[13:9]>[13:15](153,159)#text: header',
220
- '[13:15]>[13:20](159,164)th: </th>',
221
- '[13:20]>[14:5](164,169)#text: ⏎→→→→',
222
- '[14:5]>[14:9](169,173)td: <td>',
223
- '[14:9]>[14:13](173,177)#text: cell',
224
- '[14:13]>[14:18](177,182)td: </td>',
225
- '[14:18]>[15:4](182,186)#text: ⏎→→→',
226
- '[15:4]>[15:9](186,191)tr: </tr>',
227
- '[15:9]>[16:3](191,194)#text: ⏎→→',
228
- '[16:3]>[16:11](194,202)table: </table>',
229
- '[16:11]>[17:3](202,205)#text: ⏎→→',
230
- '[17:3]>[17:10](205,212)table: <table>',
231
- '[17:10]>[18:4](212,216)#text: ⏎→→→',
232
- '[18:4]>[18:11](216,223)tbody: <tbody>',
233
- '[18:11]>[19:5](223,228)#text: ⏎→→→→',
234
- '[19:5]>[19:9](228,232)tr: <tr>',
235
- '[19:9]>[20:6](232,238)#text: ⏎→→→→→',
236
- '[20:6]>[20:10](238,242)th: <th>',
237
- '[20:10]>[20:16](242,248)#text: header',
238
- '[20:16]>[20:21](248,253)th: </th>',
239
- '[20:21]>[21:6](253,259)#text: ⏎→→→→→',
240
- '[21:6]>[21:10](259,263)td: <td>',
241
- '[21:10]>[21:14](263,267)#text: cell',
242
- '[21:14]>[21:19](267,272)td: </td>',
243
- '[21:19]>[22:5](272,277)#text: ⏎→→→→',
244
- '[22:5]>[22:10](277,282)tr: </tr>',
245
- '[22:10]>[23:4](282,286)#text: ⏎→→→',
246
- '[23:4]>[23:12](286,294)tbody: </tbody>',
247
- '[23:12]>[24:3](294,297)#text: ⏎→→',
248
- '[24:3]>[24:11](297,305)table: </table>',
249
- '[24:11]>[25:3](305,308)#text: ⏎→→',
250
- '[25:3]>[25:24](308,329)img: <img␣src="path/to"␣/>',
251
- "[25:24]>[33:12](329,452)#text: ⏎→→→→invalid-indent⏎⏎→→text'⏎→→?>⏎⏎→→<%template␣engine;⏎→→→$var␣=␣'",
252
- '[33:12]>[33:31](452,471)html: <html␣attr="value">',
253
- '[33:31]>[33:35](471,475)#text: text',
254
- '[33:35]>[33:42](475,482)html: </html>',
255
- "[33:42]>[37:3](482,506)#text: '⏎→→%>⏎⏎→→⏎→→",
256
- '[37:3]>[37:8](506,511)div: <div>',
257
- '[37:8]>[39:2](511,524)#text: ⏎→text-node⏎→',
258
- ]);
259
- });
260
-
261
- it('<noscript>', () => {
262
- const doc = parse(`
263
- <template>
264
- <noscript>
265
- <div>test</div>
266
- <expected>
267
- </expected2>
268
- </noscript>
269
- </template>
270
- `);
271
- const map = nodeListToDebugMaps(doc.nodeList);
272
- expect(map).toStrictEqual([
273
- '[2:12]>[3:2](12,14)#text: ⏎→',
274
- '[3:2]>[3:12](14,24)noscript: <noscript>',
275
- '[3:12]>[7:2](24,72)#text: ⏎→→<div>test</div>⏎→→<expected>⏎→→</expected2>⏎→',
276
- '[7:2]>[7:13](72,83)noscript: </noscript>',
277
- '[7:13]>[8:2](83,85)#text: ⏎→',
278
- ]);
279
- });
280
-
281
- it('UUID', () => {
282
- const doc = parse(
283
- '<template><x-wrap><x-before><span>title</span></x-before><x-after><div>test</div></x-after></x-wrap></template>',
284
- );
285
- // const map = nodeListToDebugMaps(doc.nodeList);
286
- // console.log(map);
287
- // console.log(doc.nodeList.map((n, i) => `${i}: ${n.uuid} ${n.raw.trim()}`));
288
-
289
- // <x-wrap>
290
- expect(doc.nodeList[0].parentNode).toEqual(null);
291
- expect(doc.nodeList[0].prevNode).toEqual(null);
292
- expect(doc.nodeList[0].nextNode).toEqual(null);
293
- // @ts-ignore
294
- expect(doc.nodeList[0].pearNode.uuid).toEqual(doc.nodeList[11].uuid);
295
-
296
- // </x-wrap>
297
- expect(doc.nodeList[11].parentNode).toEqual(null);
298
- // @ts-ignore
299
- expect(doc.nodeList[11].pearNode.uuid).toEqual(doc.nodeList[0].uuid);
300
-
301
- // <x-before>
302
- // @ts-ignore
303
- expect(doc.nodeList[1].parentNode.uuid).toEqual(doc.nodeList[0].uuid);
304
- // @ts-ignore
305
- expect(doc.nodeList[1].prevNode).toEqual(null);
306
- // @ts-ignore
307
- expect(doc.nodeList[1].nextNode.uuid).toEqual(doc.nodeList[6].uuid);
308
- // @ts-ignore
309
- expect(doc.nodeList[1].pearNode.uuid).toEqual(doc.nodeList[5].uuid);
310
-
311
- // </x-before>
312
- // @ts-ignore
313
- expect(doc.nodeList[5].parentNode.uuid).toEqual(doc.nodeList[0].uuid);
314
- // @ts-ignore
315
- expect(doc.nodeList[5].pearNode.uuid).toEqual(doc.nodeList[1].uuid);
316
-
317
- // <x-after>
318
- // @ts-ignore
319
- expect(doc.nodeList[6].parentNode.uuid).toEqual(doc.nodeList[0].uuid);
320
- // @ts-ignore
321
- expect(doc.nodeList[6].prevNode.uuid).toEqual(doc.nodeList[1].uuid);
322
- // @ts-ignore
323
- expect(doc.nodeList[6].nextNode).toEqual(null);
324
- // @ts-ignore
325
- expect(doc.nodeList[6].pearNode.uuid).toEqual(doc.nodeList[10].uuid);
326
-
327
- // </x-after>
328
- // @ts-ignore
329
- expect(doc.nodeList[10].parentNode.uuid).toEqual(doc.nodeList[0].uuid);
330
- // @ts-ignore
331
- expect(doc.nodeList[10].pearNode.uuid).toEqual(doc.nodeList[6].uuid);
332
- });
333
-
334
- it('attributes', () => {
335
- const doc = parse(
336
- '<template><div v-if="bool" data-attr v-bind:data-attr2="variable" @click.once="event" v-on:click.foobar="event"></div></template>',
337
- );
338
- // @ts-ignore
339
- expect(doc.nodeList[0].attributes[0].raw).toBe('v-if="bool"');
340
- // @ts-ignore
341
- expect(doc.nodeList[0].attributes[0].isDirective).toBeTruthy();
342
- // @ts-ignore
343
- expect(doc.nodeList[0].attributes[1].raw).toBe('data-attr');
344
- // @ts-ignore
345
- expect(doc.nodeList[0].attributes[1].isDirective).toBeUndefined();
346
- // @ts-ignore
347
- expect(doc.nodeList[0].attributes[2].raw).toBe('v-bind:data-attr2="variable"');
348
- // @ts-ignore
349
- expect(doc.nodeList[0].attributes[2].potentialName).toBe('data-attr2');
350
- // @ts-ignore
351
- expect(doc.nodeList[0].attributes[3].isDirective).toBeFalsy();
352
- // @ts-ignore
353
- expect(doc.nodeList[0].attributes[4].isDirective).toBeFalsy();
354
- });
355
-
356
- it('namespace', () => {
357
- const doc = parse('<template><div><svg><text /></svg></div></template>');
358
- expect(doc.nodeList[0].nodeName).toBe('div');
359
- expect(doc.nodeList[0].namespace).toBe('http://www.w3.org/1999/xhtml');
360
- expect(doc.nodeList[1].nodeName).toBe('svg');
361
- expect(doc.nodeList[1].namespace).toBe('http://www.w3.org/2000/svg');
362
- expect(doc.nodeList[2].nodeName).toBe('text');
363
- expect(doc.nodeList[2].namespace).toBe('http://www.w3.org/2000/svg');
364
- });
365
-
366
- it('elementType', () => {
367
- expect(parse('<template><div/></template>').nodeList[0].elementType).toBe('html');
368
- expect(parse('<template><Div/></template>').nodeList[0].elementType).toBe('authored');
369
- expect(parse('<template><x-div/></template>').nodeList[0].elementType).toBe('web-component');
370
- expect(parse('<template><foo/></template>').nodeList[0].elementType).toBe('html');
371
- expect(parse('<template><Foo/></template>').nodeList[0].elementType).toBe('authored');
372
- expect(parse('<template><div><Foo/></div></template>').nodeList[1].elementType).toBe('authored');
373
- expect(parse('<template><div><Component/></div></template>').nodeList[1].elementType).toBe('authored');
374
- expect(parse('<template><svg><Component/></svg></template>').nodeList[1].elementType).toBe('authored');
375
- expect(parse('<template><svg><feBlend/></svg></template>').nodeList[1].elementType).toBe('html');
376
- expect(parse('<template><component/></template>').nodeList[0].elementType).toBe('authored');
377
- expect(parse('<template><slot/></template>').nodeList[0].elementType).toBe('authored');
378
- expect(parse('<template><Transition/></template>').nodeList[0].elementType).toBe('authored');
379
- expect(parse('<template><transition/></template>').nodeList[0].elementType).toBe('html');
380
- });
381
-
382
- it('Directives', () => {
383
- const doc = parse(`
384
- <template>
385
- <div>
386
- <template #header></template>
387
- </div>
388
- </template>
389
- `);
390
- const map = nodeListToDebugMaps(doc.nodeList, true);
391
- expect(map).toStrictEqual([
392
- '[2:12]>[3:3](12,15)#text: ⏎→→',
393
- '[3:3]>[3:8](15,20)div: <div>',
394
- '[3:8]>[4:4](20,24)#text: ⏎→→→',
395
- '[4:4]>[4:22](24,42)template: <template␣#header>',
396
- '[4:14]>[4:21](34,41)v-slot:header: #header',
397
- ' [4:13]>[4:14](33,34)bN: ␣',
398
- ' [4:14]>[4:21](34,41)name: #header',
399
- ' [4:21]>[4:21](41,41)bE: ',
400
- ' [4:21]>[4:21](41,41)equal: ',
401
- ' [4:21]>[4:21](41,41)aE: ',
402
- ' [4:21]>[4:21](41,41)sQ: ',
403
- ' [4:21]>[4:21](41,41)value: ',
404
- ' [4:21]>[4:21](41,41)eQ: ',
405
- ' isDirective: true',
406
- ' isDynamicValue: false',
407
- ' potentialName: v-slot:header',
408
- '[4:33]>[5:3](53,56)#text: ⏎→→',
409
- '[5:3]>[5:9](56,62)div: </div>',
410
- '[5:9]>[6:2](62,64)#text: ⏎→',
411
- ]);
412
- });
413
- });
414
-
415
- describe('Issues', () => {
416
- test('#783', () => {
417
- const doc = parse(`
418
- <template>
419
- <button @click.stop="foo" v-on:click.stop="bar">...</button>
420
- </template>
421
- `);
422
- const map = nodeListToDebugMaps(doc.nodeList, true);
423
- expect(map).toStrictEqual([
424
- '[2:12]>[3:3](12,15)#text: ⏎→→',
425
- '[3:3]>[3:51](15,63)button: <button␣@click.stop="foo"␣v-on:click.stop="bar">',
426
- '[3:11]>[3:28](23,40)onclick: @click.stop="foo"',
427
- ' [3:10]>[3:11](22,23)bN: ␣',
428
- ' [3:11]>[3:22](23,34)name: @click.stop',
429
- ' [3:22]>[3:22](34,34)bE: ',
430
- ' [3:22]>[3:23](34,35)equal: =',
431
- ' [3:23]>[3:23](35,35)aE: ',
432
- ' [3:23]>[3:24](35,36)sQ: "',
433
- ' [3:24]>[3:27](36,39)value: foo',
434
- ' [3:27]>[3:28](39,40)eQ: "',
435
- ' isDirective: false',
436
- ' isDynamicValue: true',
437
- ' potentialName: onclick',
438
- '[3:29]>[3:50](41,62)onclick: v-on:click.stop="bar"',
439
- ' [3:28]>[3:29](40,41)bN: ␣',
440
- ' [3:29]>[3:44](41,56)name: v-on:click.stop',
441
- ' [3:44]>[3:44](56,56)bE: ',
442
- ' [3:44]>[3:45](56,57)equal: =',
443
- ' [3:45]>[3:45](57,57)aE: ',
444
- ' [3:45]>[3:46](57,58)sQ: "',
445
- ' [3:46]>[3:49](58,61)value: bar',
446
- ' [3:49]>[3:50](61,62)eQ: "',
447
- ' isDirective: false',
448
- ' isDynamicValue: true',
449
- ' potentialName: onclick',
450
- '[3:51]>[3:54](63,66)#text: ...',
451
- '[3:54]>[3:63](66,75)button: </button>',
452
- '[3:63]>[4:2](75,77)#text: ⏎→',
453
- ]);
454
- });
455
- });