@markuplint/svelte-parser 3.7.0 → 3.8.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/lib/attr.js CHANGED
@@ -2,9 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.attr = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const html_parser_1 = require("@markuplint/html-parser");
6
5
  const parser_utils_1 = require("@markuplint/parser-utils");
7
6
  const directive_tokenizer_1 = tslib_1.__importDefault(require("./directive-tokenizer"));
7
+ const mustacheTag = {
8
+ start: '{',
9
+ end: '}',
10
+ };
8
11
  const specificBindDirective = ['bind:group', 'bind:this'];
9
12
  function attr(
10
13
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
@@ -13,29 +16,27 @@ attr, rawHTML) {
13
16
  ? attr.value.some((val) => val.type === 'AttributeShorthand')
14
17
  : false;
15
18
  const { start, end } = attr;
16
- // @ts-ignore
17
19
  if (attr.type === 'Spread') {
18
20
  return {
19
21
  __spreadAttr: true,
20
22
  };
21
23
  }
22
- // @ts-ignore TODO solve type
24
+ let token;
23
25
  if (attr.type === 'Attribute' && !isShorthand) {
26
+ const { raw } = (0, parser_utils_1.sliceFragment)(rawHTML, start, end);
27
+ token = (0, parser_utils_1.parseAttr)(raw, start, rawHTML, {
28
+ valueDelimiters: [...parser_utils_1.defaultValueDelimiters, mustacheTag],
29
+ });
30
+ }
31
+ else {
24
32
  const { raw, startLine, startCol, startOffset } = (0, parser_utils_1.sliceFragment)(rawHTML, start, end);
25
- const token = (0, html_parser_1.attrTokenizer)(raw, startLine, startCol, startOffset);
26
- return token;
33
+ const valueToken = isShorthand
34
+ ? attr.name
35
+ : attr.expression && 'start' in attr.expression && 'end' in attr.expression
36
+ ? (0, parser_utils_1.sliceFragment)(rawHTML, attr.expression.start, attr.expression.end).raw
37
+ : '';
38
+ token = (0, directive_tokenizer_1.default)(raw, valueToken, startLine, startCol, startOffset);
27
39
  }
28
- const { raw, startLine, startCol, startOffset } = (0, parser_utils_1.sliceFragment)(rawHTML, start, end);
29
- const valueToken = isShorthand
30
- ? attr.name
31
- : // @ts-ignore TODO solve type
32
- attr.type === 'Spread'
33
- ? raw.slice(1).slice(0, -1)
34
- : attr.expression && 'start' in attr.expression && 'end' in attr.expression
35
- ? // @ts-ignore
36
- (0, parser_utils_1.sliceFragment)(rawHTML, attr.expression.start, attr.expression.end).raw
37
- : '';
38
- const token = (0, directive_tokenizer_1.default)(raw, valueToken, startLine, startCol, startOffset);
39
40
  if (!specificBindDirective.includes(token.name.raw) && /^bind:/i.test(token.name.raw)) {
40
41
  // Remove "bind:"
41
42
  token.potentialName = token.name.raw.slice(5);
@@ -55,6 +56,9 @@ attr, rawHTML) {
55
56
  token.isDynamicValue = true;
56
57
  }
57
58
  }
59
+ if (token.startQuote.raw === '{' && token.endQuote.raw === '}') {
60
+ token.isDynamicValue = true;
61
+ }
58
62
  return {
59
63
  ...token,
60
64
  };
package/lib/nodeize.js CHANGED
@@ -57,6 +57,7 @@ parentNode, rawHtml, options) {
57
57
  isGhost: false,
58
58
  };
59
59
  }
60
+ case 'InlineComponent':
60
61
  case 'Element': {
61
62
  const children = (_a = originNode.children) !== null && _a !== void 0 ? _a : [];
62
63
  const reEndTag = new RegExp(`</${originNode.name}\\s*>$`, 'i');
@@ -233,7 +234,7 @@ parentNode, rawHtml, options) {
233
234
  return tags;
234
235
  }
235
236
  default: {
236
- return {
237
+ const startTag = {
237
238
  uuid: (0, parser_utils_1.uuid)(),
238
239
  raw,
239
240
  startOffset,
@@ -250,6 +251,42 @@ parentNode, rawHtml, options) {
250
251
  isFragment: false,
251
252
  isGhost: false,
252
253
  };
254
+ let endTag = null;
255
+ if (originNode.children) {
256
+ startTag.childNodes = (0, traverse_1.traverse)(originNode.children, startTag, rawHtml, options);
257
+ const firstChild = startTag.childNodes[0];
258
+ if (firstChild) {
259
+ startTag.endOffset = firstChild.startOffset;
260
+ startTag.endLine = firstChild.startLine;
261
+ startTag.endCol = firstChild.startCol;
262
+ startTag.raw = rawHtml.slice(startTag.startOffset, startTag.endOffset);
263
+ }
264
+ const lastChild = startTag.childNodes[startTag.childNodes.length - 1];
265
+ if (lastChild && lastChild.endOffset > startTag.endOffset) {
266
+ const startOffset = lastChild.endOffset;
267
+ const startLine = lastChild.endLine;
268
+ const startCol = lastChild.endCol;
269
+ const raw = rawHtml.slice(startOffset, endOffset);
270
+ endTag = {
271
+ uuid: (0, parser_utils_1.uuid)(),
272
+ raw,
273
+ startOffset,
274
+ endOffset,
275
+ startLine,
276
+ endLine,
277
+ startCol,
278
+ endCol,
279
+ nodeName: originNode.name || originNode.type,
280
+ type: 'psblock',
281
+ parentNode,
282
+ prevNode,
283
+ nextNode,
284
+ isFragment: false,
285
+ isGhost: false,
286
+ };
287
+ }
288
+ }
289
+ return endTag != null ? [startTag, endTag] : startTag;
253
290
  }
254
291
  }
255
292
  }
@@ -1,4 +1,4 @@
1
- import type { Directive, TemplateNode } from 'svelte/types/compiler/interfaces';
1
+ import type { Directive, TemplateNode, Attribute, SpreadAttribute } from 'svelte/types/compiler/interfaces';
2
2
  export type SvelteNode = TemplateNode;
3
3
  export default function svelteParse(template: string): TemplateNode[];
4
- export type SvelteDirective = Directive;
4
+ export type SvelteDirective = Directive | Attribute | SpreadAttribute;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markuplint/svelte-parser",
3
- "version": "3.7.0",
3
+ "version": "3.8.0",
4
4
  "description": "Svelte parser for markuplint",
5
5
  "repository": "git@github.com:markuplint/markuplint.git",
6
6
  "author": "Yusuke Hirao <yusukehirao@me.com>",
@@ -16,11 +16,11 @@
16
16
  "clean": "tsc --build --clean"
17
17
  },
18
18
  "dependencies": {
19
- "@markuplint/html-parser": "3.8.0",
20
- "@markuplint/ml-ast": "3.1.0",
21
- "@markuplint/parser-utils": "3.8.0",
19
+ "@markuplint/html-parser": "3.9.0",
20
+ "@markuplint/ml-ast": "3.2.0",
21
+ "@markuplint/parser-utils": "3.9.0",
22
22
  "svelte": "^3.58.0",
23
- "tslib": "^2.5.0"
23
+ "tslib": "^2.5.3"
24
24
  },
25
- "gitHead": "af370797bfc887e5a5a2ff57fbaa8392ac98ead2"
25
+ "gitHead": "9547b8dca20736a93e4d01af2d61bee314ba5718"
26
26
  }
@@ -211,7 +211,7 @@ describe('parser', () => {
211
211
  ' [1:19]>[1:35](18,34)value: ␣`abc${def}ghi`␣',
212
212
  ' [1:35]>[1:36](34,35)eQ: }',
213
213
  ' isDirective: true',
214
- ' isDynamicValue: false',
214
+ ' isDynamicValue: true',
215
215
  ],
216
216
  ]);
217
217
  });
@@ -231,7 +231,7 @@ describe('parser', () => {
231
231
  ' [1:31]>[1:38](30,37)value: handler',
232
232
  ' [1:38]>[1:39](37,38)eQ: }',
233
233
  ' isDirective: true',
234
- ' isDynamicValue: false',
234
+ ' isDynamicValue: true',
235
235
  ],
236
236
  ]);
237
237
  });
@@ -505,4 +505,52 @@ describe('Issues', () => {
505
505
  expect(r.nodeList[0].childNodes[4].raw).toBe(r.nodeList[11].raw);
506
506
  expect(r.nodeList[0].childNodes[4].uuid).toBe(r.nodeList[11].uuid);
507
507
  });
508
+
509
+ test('#991', () => {
510
+ const r = parse(`<CustomElement>
511
+ <div>Evaluation doesn't work</div>
512
+ </CustomElement>`);
513
+ const map = nodeListToDebugMaps(r.nodeList);
514
+ expect(map).toStrictEqual([
515
+ '[1:1]>[1:16](0,15)CustomElement: <CustomElement>',
516
+ '[1:16]>[2:2](15,17)#text: ⏎→',
517
+ '[2:2]>[2:7](17,22)div: <div>',
518
+ "[2:7]>[2:30](22,45)#text: Evaluation␣doesn't␣work",
519
+ '[2:30]>[2:36](45,51)div: </div>',
520
+ '[2:36]>[3:1](51,52)#text: ⏎',
521
+ '[3:1]>[3:17](52,68)CustomElement: </CustomElement>',
522
+ ]);
523
+ });
524
+
525
+ test('#991-2', () => {
526
+ const r = parse('<div id={uid()}></div>');
527
+ const map = nodeListToDebugMaps(r.nodeList, true);
528
+ expect(map).toStrictEqual([
529
+ '[1:1]>[1:17](0,16)div: <div␣id={uid()}>',
530
+ '[1:6]>[1:16](5,15)id: id={uid()}',
531
+ ' [1:6]>[1:6](5,5)bN: ',
532
+ ' [1:6]>[1:8](5,7)name: id',
533
+ ' [1:8]>[1:8](7,7)bE: ',
534
+ ' [1:8]>[1:9](7,8)equal: =',
535
+ ' [1:9]>[1:9](8,8)aE: ',
536
+ ' [1:9]>[1:10](8,9)sQ: {',
537
+ ' [1:10]>[1:15](9,14)value: uid()',
538
+ ' [1:15]>[1:16](14,15)eQ: }',
539
+ ' isDirective: false',
540
+ ' isDynamicValue: true',
541
+ '[1:17]>[1:23](16,22)div: </div>',
542
+ ]);
543
+ });
544
+
545
+ test('#991-3', () => {
546
+ const r = parse('<div>\n<!-- It is a comment node -->\n</div>');
547
+ const map = nodeListToDebugMaps(r.nodeList, true);
548
+ expect(map).toStrictEqual([
549
+ '[1:1]>[1:6](0,5)div: <div>',
550
+ '[1:6]>[2:1](5,6)#text: ⏎',
551
+ '[2:1]>[2:30](6,35)Comment: <!--␣It␣is␣a␣comment␣node␣-->',
552
+ '[2:30]>[3:1](35,36)#text: ⏎',
553
+ '[3:1]>[3:7](36,42)div: </div>',
554
+ ]);
555
+ });
508
556
  });
@@ -107,3 +107,35 @@ describe('parser', () => {
107
107
  ]);
108
108
  });
109
109
  });
110
+
111
+ describe('Issues', () => {
112
+ test('#991', () => {
113
+ expect(svelteParse("<CustomElement><div>Evaluation doesn't work</div></CustomElement>")).toEqual([
114
+ {
115
+ type: 'InlineComponent',
116
+ name: 'CustomElement',
117
+ start: 0,
118
+ end: 65,
119
+ attributes: [],
120
+ children: [
121
+ {
122
+ type: 'Element',
123
+ name: 'div',
124
+ start: 15,
125
+ end: 49,
126
+ attributes: [],
127
+ children: [
128
+ {
129
+ type: 'Text',
130
+ start: 20,
131
+ end: 43,
132
+ data: "Evaluation doesn't work",
133
+ raw: "Evaluation doesn't work",
134
+ },
135
+ ],
136
+ },
137
+ ],
138
+ },
139
+ ]);
140
+ });
141
+ });