@markuplint/vue-parser 4.0.0-alpha.2 → 4.0.0-alpha.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.
package/lib/attr.js CHANGED
@@ -1,10 +1,10 @@
1
- const duplicatableAttrs = ['class', 'style'];
1
+ const duplicatableAttrs = new Set(['class', 'style']);
2
2
  export function attr(
3
3
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
4
4
  attr) {
5
5
  if (attr.type !== 'html-attr') {
6
6
  const name = attr.potentialName;
7
- if (duplicatableAttrs.includes(name)) {
7
+ if (duplicatableAttrs.has(name)) {
8
8
  attr.isDuplicatable = true;
9
9
  }
10
10
  return attr;
@@ -30,7 +30,7 @@ attr) {
30
30
  */
31
31
  const [, directive, potentialName, modifier] = attr.name.raw.match(/^(v-bind:|:)([^.]+)(?:\.([^.]+))?$/i) ?? [];
32
32
  if (directive && potentialName) {
33
- if (duplicatableAttrs.includes(potentialName.toLowerCase())) {
33
+ if (duplicatableAttrs.has(potentialName.toLowerCase())) {
34
34
  attr.isDuplicatable = true;
35
35
  }
36
36
  if (!modifier) {
@@ -50,6 +50,7 @@ attr) {
50
50
  _modifier: modifier,
51
51
  };
52
52
  }
53
+ /* eslint-disable unicorn/no-useless-switch-case */
53
54
  // TODO: Supporting for `prop` and `camel` https://github.com/markuplint/markuplint/pull/681
54
55
  case '.prop':
55
56
  case '.camel':
@@ -57,12 +58,13 @@ attr) {
57
58
  const name = `v-bind:${potentialName}${modifier ?? ''}`;
58
59
  return {
59
60
  ...attr,
60
- potentialName: attr.name.raw !== name ? name : undefined,
61
+ potentialName: attr.name.raw === name ? undefined : name,
61
62
  isDirective: true,
62
63
  // @ts-ignore
63
64
  _modifier: modifier,
64
65
  };
65
66
  }
67
+ /* eslint-enable unicorn/no-useless-switch-case */
66
68
  }
67
69
  }
68
70
  }
@@ -85,12 +87,12 @@ attr) {
85
87
  /**
86
88
  * `v-slot`
87
89
  */
88
- const [, , slotName] = attr.name.raw.match(/^(v-slot:|#)(.+)$/i) ?? [];
90
+ const slotName = (attr.name.raw.match(/^(v-slot:|#)(.+)$/i) ?? [])[2];
89
91
  const name = `v-slot:${slotName}`;
90
92
  if (slotName) {
91
93
  return {
92
94
  ...attr,
93
- potentialName: attr.name.raw !== name ? name : undefined,
95
+ potentialName: attr.name.raw === name ? undefined : name,
94
96
  isDirective: true,
95
97
  };
96
98
  }
@@ -98,7 +100,7 @@ attr) {
98
100
  /**
99
101
  * If directives
100
102
  */
101
- if (/^v-/.test(attr.name.raw)) {
103
+ if (attr.name.raw.startsWith('v-')) {
102
104
  return {
103
105
  ...attr,
104
106
  isDirective: true,
package/lib/parse.js CHANGED
@@ -7,26 +7,26 @@ export const parse = (rawCode, options) => {
7
7
  try {
8
8
  ast = vueParse(rawCode);
9
9
  }
10
- catch (err) {
11
- if (err instanceof SyntaxError && 'lineNumber' in err && 'column' in err) {
10
+ catch (error) {
11
+ if (error instanceof SyntaxError && 'lineNumber' in error && 'column' in error) {
12
12
  throw new ParserError(
13
13
  // @ts-ignore
14
- err.message, {
14
+ error.message, {
15
15
  // @ts-ignore
16
- line: err.lineNumber,
16
+ line: error.lineNumber,
17
17
  // @ts-ignore
18
- col: err.column,
18
+ col: error.column,
19
19
  raw: '',
20
20
  });
21
21
  }
22
22
  return {
23
23
  nodeList: [],
24
24
  isFragment: true,
25
- parseError: err instanceof Error ? err.message : new Error(`${err}`).message,
25
+ parseError: error instanceof Error ? error.message : new Error(`${error}`).message,
26
26
  };
27
27
  }
28
28
  const nodeList = ast.templateBody
29
- ? flattenNodes(traverse(ast.templateBody, null, rawCode, options), rawCode)
29
+ ? flattenNodes(traverse(ast.templateBody, null, rawCode, ast.templateBody.comments, options), rawCode)
30
30
  : [];
31
31
  // Remove `</template>`
32
32
  const templateEndTagIndex = nodeList.findIndex(node => /\s*<\/\s*template\s*>\s*/i.test(node.raw));
@@ -46,17 +46,50 @@ export const parse = (rawCode, options) => {
46
46
  };
47
47
  function traverse(
48
48
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
49
- rootNode, parentNode = null, rawHtml, options) {
49
+ rootNode, parentNode = null, rawHtml,
50
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
51
+ comments, options) {
50
52
  const nodeList = [];
51
53
  if (rootNode.type !== 'VElement') {
52
54
  return [];
53
55
  }
54
56
  let prevNode = null;
55
57
  for (const vNode of rootNode.children) {
56
- const node = nodeize(vNode, prevNode, parentNode, rawHtml, options);
58
+ const node = nodeize(vNode, prevNode, parentNode, rawHtml, comments, options);
57
59
  if (!node) {
58
60
  continue;
59
61
  }
62
+ const lastOffset = prevNode?.endOffset ?? parentNode?.endOffset ?? 0;
63
+ const betweenComment = comments.find(comment => {
64
+ return lastOffset <= comment.range[0] && comment.range[1] <= node.startOffset;
65
+ });
66
+ if (betweenComment) {
67
+ const comment = {
68
+ uuid: uuid(),
69
+ raw: `<!--${betweenComment.value}-->`,
70
+ startOffset: betweenComment.range[0],
71
+ endOffset: betweenComment.range[1],
72
+ startLine: betweenComment.loc.start.line,
73
+ endLine: betweenComment.loc.end.line,
74
+ startCol: betweenComment.loc.start.column + 1,
75
+ endCol: betweenComment.loc.end.column + 1,
76
+ nodeName: '#comment',
77
+ type: 'comment',
78
+ parentNode,
79
+ prevNode,
80
+ nextNode: node,
81
+ isFragment: false,
82
+ isGhost: false,
83
+ };
84
+ comment.parentNode = parentNode;
85
+ comment.prevNode = prevNode;
86
+ comment.nextNode = node;
87
+ if (prevNode) {
88
+ prevNode.nextNode = comment;
89
+ }
90
+ nodeList.push(comment);
91
+ prevNode = comment;
92
+ }
60
93
  if (prevNode) {
61
94
  if (node.type !== 'endtag') {
62
95
  prevNode.nextNode = node;
@@ -74,7 +107,9 @@ originNode,
74
107
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
75
108
  prevNode,
76
109
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
77
- parentNode, rawHtml, options) {
110
+ parentNode, rawHtml,
111
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
112
+ comments, options) {
78
113
  const nextNode = null;
79
114
  const startOffset = originNode.range[0];
80
115
  const endOffset = originNode.range[1];
@@ -201,7 +236,7 @@ parentNode, rawHtml, options) {
201
236
  if (endTag) {
202
237
  endTag.pearNode = startTag;
203
238
  }
204
- startTag.childNodes = traverse(originNode, startTag, rawHtml, options);
239
+ startTag.childNodes = traverse(originNode, startTag, rawHtml, comments, options);
205
240
  return startTag;
206
241
  }
207
242
  }
@@ -2,3 +2,4 @@ import * as VueESLintParser from 'vue-eslint-parser';
2
2
  export type VueTokens = VueESLintParser.AST.ESLintProgram;
3
3
  export default function vueParse(vueTemplate: string): VueTokens;
4
4
  export type ASTNode = VueESLintParser.AST.VElement | VueESLintParser.AST.VText | VueESLintParser.AST.VExpressionContainer;
5
+ export type ASTComment = VueESLintParser.AST.Token & VueESLintParser.AST.HasLocation;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markuplint/vue-parser",
3
- "version": "4.0.0-alpha.2",
3
+ "version": "4.0.0-alpha.4",
4
4
  "description": "Vue parser for markuplint",
5
5
  "repository": "git@github.com:markuplint/markuplint.git",
6
6
  "author": "Yusuke Hirao <yusukehirao@me.com>",
@@ -21,11 +21,10 @@
21
21
  "clean": "tsc --build --clean"
22
22
  },
23
23
  "dependencies": {
24
- "@markuplint/html-parser": "4.0.0-alpha.2",
25
- "@markuplint/ml-ast": "4.0.0-alpha.2",
26
- "@markuplint/parser-utils": "4.0.0-alpha.2",
27
- "tslib": "^2.6.2",
24
+ "@markuplint/html-parser": "4.0.0-alpha.4",
25
+ "@markuplint/ml-ast": "4.0.0-alpha.4",
26
+ "@markuplint/parser-utils": "4.0.0-alpha.4",
28
27
  "vue-eslint-parser": "^9.3.1"
29
28
  },
30
- "gitHead": "51ad52c760435641f9bff8685707d8178b0787eb"
29
+ "gitHead": "991b3aef77fde42c79343ee8c807257a35c589d7"
31
30
  }