@markuplint/svelte-parser 3.10.0 → 4.0.0-alpha.2
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.d.ts +1 -1
- package/lib/attr.js +10 -15
- package/lib/directive-tokenizer.js +24 -28
- package/lib/index.d.ts +1 -1
- package/lib/index.js +2 -6
- package/lib/nodeize.d.ts +1 -1
- package/lib/nodeize.js +38 -42
- package/lib/parse-ctrl-block.d.ts +1 -1
- package/lib/parse-ctrl-block.js +27 -33
- package/lib/parse.js +9 -14
- package/lib/svelte-parser/index.js +4 -8
- package/lib/traverse.d.ts +1 -1
- package/lib/traverse.js +3 -7
- package/package.json +12 -7
- package/test/index.spec.js +0 -556
- package/test/parse-ctrl-block.spec.js +0 -267
- package/test/svelte-parser/index.spec.js +0 -141
package/lib/attr.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { SvelteDirective } from './svelte-parser';
|
|
1
|
+
import type { SvelteDirective } from './svelte-parser/index.js';
|
|
2
2
|
import type { MLASTAttr } from '@markuplint/ml-ast';
|
|
3
3
|
export declare function attr(attr: SvelteDirective, rawHTML: string): MLASTAttr | {
|
|
4
4
|
__spreadAttr: true;
|
package/lib/attr.js
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.attr = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const parser_utils_1 = require("@markuplint/parser-utils");
|
|
6
|
-
const directive_tokenizer_1 = tslib_1.__importDefault(require("./directive-tokenizer"));
|
|
1
|
+
import { defaultValueDelimiters, parseAttr, sliceFragment } from '@markuplint/parser-utils';
|
|
2
|
+
import directiveTokenizer from './directive-tokenizer.js';
|
|
7
3
|
const mustacheTag = {
|
|
8
4
|
start: '{',
|
|
9
5
|
end: '}',
|
|
10
6
|
};
|
|
11
7
|
const specificBindDirective = ['bind:group', 'bind:this'];
|
|
12
|
-
function attr(
|
|
8
|
+
export function attr(
|
|
13
9
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
14
10
|
attr, rawHTML) {
|
|
15
11
|
const isShorthand = attr.value && Array.isArray(attr.value)
|
|
@@ -23,19 +19,19 @@ attr, rawHTML) {
|
|
|
23
19
|
}
|
|
24
20
|
let token;
|
|
25
21
|
if (attr.type === 'Attribute' && !isShorthand) {
|
|
26
|
-
const { raw } =
|
|
27
|
-
token =
|
|
28
|
-
valueDelimiters: [...
|
|
22
|
+
const { raw } = sliceFragment(rawHTML, start, end);
|
|
23
|
+
token = parseAttr(raw, start, rawHTML, {
|
|
24
|
+
valueDelimiters: [...defaultValueDelimiters, mustacheTag],
|
|
29
25
|
});
|
|
30
26
|
}
|
|
31
27
|
else {
|
|
32
|
-
const { raw, startLine, startCol, startOffset } =
|
|
28
|
+
const { raw, startLine, startCol, startOffset } = sliceFragment(rawHTML, start, end);
|
|
33
29
|
const valueToken = isShorthand
|
|
34
30
|
? attr.name
|
|
35
31
|
: attr.expression && 'start' in attr.expression && 'end' in attr.expression
|
|
36
|
-
?
|
|
32
|
+
? sliceFragment(rawHTML, attr.expression.start, attr.expression.end).raw
|
|
37
33
|
: '';
|
|
38
|
-
token = (
|
|
34
|
+
token = directiveTokenizer(raw, valueToken, startLine, startCol, startOffset);
|
|
39
35
|
}
|
|
40
36
|
if (!specificBindDirective.includes(token.name.raw) && /^bind:/i.test(token.name.raw)) {
|
|
41
37
|
// Remove "bind:"
|
|
@@ -49,7 +45,7 @@ attr, rawHTML) {
|
|
|
49
45
|
token.isDynamicValue = true;
|
|
50
46
|
}
|
|
51
47
|
const [baseName, subName] = token.name.raw.split(':');
|
|
52
|
-
if (
|
|
48
|
+
if (baseName?.toLowerCase() === 'class') {
|
|
53
49
|
token.isDuplicatable = true;
|
|
54
50
|
if (subName) {
|
|
55
51
|
token.potentialName = 'class';
|
|
@@ -63,4 +59,3 @@ attr, rawHTML) {
|
|
|
63
59
|
...token,
|
|
64
60
|
};
|
|
65
61
|
}
|
|
66
|
-
exports.attr = attr;
|
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const html_parser_1 = require("@markuplint/html-parser");
|
|
4
|
-
const parser_utils_1 = require("@markuplint/parser-utils");
|
|
1
|
+
import { attrTokenizer } from '@markuplint/html-parser';
|
|
2
|
+
import { tokenizer, uuid } from '@markuplint/parser-utils';
|
|
5
3
|
// eslint-disable-next-line no-control-regex
|
|
6
4
|
const reNameOnly = /^[^\x00-\x1f\x7f-\x9f {>/=]+/;
|
|
7
5
|
// eslint-disable-next-line no-control-regex
|
|
8
6
|
const reBeforeStructure = /^(\s*)([^\x00-\x1f\x7f-\x9f {>/=]+)(\s*)(=)(\s*){(\s*)$/;
|
|
9
7
|
const reBeforeStructureWithoutName = /^{(\s*)$/;
|
|
10
8
|
const reAfterStructure = /(\s*)}/;
|
|
11
|
-
function directiveTokenizer(raw, rawValue, line, col, startOffset) {
|
|
12
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
9
|
+
export default function directiveTokenizer(raw, rawValue, line, col, startOffset) {
|
|
13
10
|
let spacesBeforeAttrString = '';
|
|
14
11
|
let nameChars = '';
|
|
15
12
|
let spacesBeforeEqualChars = '';
|
|
@@ -17,22 +14,22 @@ function directiveTokenizer(raw, rawValue, line, col, startOffset) {
|
|
|
17
14
|
let spacesAfterEqualChars = '';
|
|
18
15
|
let valueChars = '';
|
|
19
16
|
const [before, after] = raw.split(rawValue);
|
|
20
|
-
const beforeMatchedMap = before
|
|
21
|
-
const beforeWithoutNameMatchedMap = before
|
|
22
|
-
const afterMatchedMap = after
|
|
17
|
+
const beforeMatchedMap = before?.match(reBeforeStructure);
|
|
18
|
+
const beforeWithoutNameMatchedMap = before?.match(reBeforeStructureWithoutName);
|
|
19
|
+
const afterMatchedMap = after?.match(reAfterStructure);
|
|
23
20
|
if (beforeMatchedMap && afterMatchedMap) {
|
|
24
|
-
spacesBeforeAttrString =
|
|
25
|
-
nameChars =
|
|
26
|
-
spacesBeforeEqualChars =
|
|
27
|
-
equalChars =
|
|
28
|
-
spacesAfterEqualChars =
|
|
29
|
-
valueChars = (
|
|
21
|
+
spacesBeforeAttrString = beforeMatchedMap[1] ?? '';
|
|
22
|
+
nameChars = beforeMatchedMap[2] ?? '';
|
|
23
|
+
spacesBeforeEqualChars = beforeMatchedMap[3] ?? '';
|
|
24
|
+
equalChars = beforeMatchedMap[4] ?? null;
|
|
25
|
+
spacesAfterEqualChars = beforeMatchedMap[5] ?? '';
|
|
26
|
+
valueChars = (beforeMatchedMap[6] ?? '') + rawValue + (afterMatchedMap[1] ?? '');
|
|
30
27
|
}
|
|
31
28
|
else if (beforeWithoutNameMatchedMap && afterMatchedMap) {
|
|
32
|
-
valueChars = (
|
|
29
|
+
valueChars = (beforeWithoutNameMatchedMap[1] ?? '') + rawValue + (afterMatchedMap[1] ?? '');
|
|
33
30
|
}
|
|
34
31
|
else if (reNameOnly.test(raw)) {
|
|
35
|
-
const token =
|
|
32
|
+
const token = attrTokenizer(raw, line, col, startOffset);
|
|
36
33
|
token.isDirective = true;
|
|
37
34
|
return token;
|
|
38
35
|
}
|
|
@@ -40,42 +37,42 @@ function directiveTokenizer(raw, rawValue, line, col, startOffset) {
|
|
|
40
37
|
throw new SyntaxError('Illegal attribute token');
|
|
41
38
|
}
|
|
42
39
|
let offset = startOffset;
|
|
43
|
-
const attrToken =
|
|
44
|
-
const spacesBeforeName =
|
|
40
|
+
const attrToken = tokenizer(raw, line, col, offset);
|
|
41
|
+
const spacesBeforeName = tokenizer(spacesBeforeAttrString, line, col, offset);
|
|
45
42
|
line = spacesBeforeName.endLine;
|
|
46
43
|
col = spacesBeforeName.endCol;
|
|
47
44
|
offset = spacesBeforeName.endOffset;
|
|
48
|
-
const name =
|
|
45
|
+
const name = tokenizer(nameChars, line, col, offset);
|
|
49
46
|
line = name.endLine;
|
|
50
47
|
col = name.endCol;
|
|
51
48
|
offset = name.endOffset;
|
|
52
|
-
const spacesBeforeEqual =
|
|
49
|
+
const spacesBeforeEqual = tokenizer(spacesBeforeEqualChars, line, col, offset);
|
|
53
50
|
line = spacesBeforeEqual.endLine;
|
|
54
51
|
col = spacesBeforeEqual.endCol;
|
|
55
52
|
offset = spacesBeforeEqual.endOffset;
|
|
56
|
-
const equal =
|
|
53
|
+
const equal = tokenizer(equalChars, line, col, offset);
|
|
57
54
|
line = equal.endLine;
|
|
58
55
|
col = equal.endCol;
|
|
59
56
|
offset = equal.endOffset;
|
|
60
|
-
const spacesAfterEqual =
|
|
57
|
+
const spacesAfterEqual = tokenizer(spacesAfterEqualChars, line, col, offset);
|
|
61
58
|
line = spacesAfterEqual.endLine;
|
|
62
59
|
col = spacesAfterEqual.endCol;
|
|
63
60
|
offset = spacesAfterEqual.endOffset;
|
|
64
|
-
const startQuote =
|
|
61
|
+
const startQuote = tokenizer('{', line, col, offset);
|
|
65
62
|
line = startQuote.endLine;
|
|
66
63
|
col = startQuote.endCol;
|
|
67
64
|
offset = startQuote.endOffset;
|
|
68
|
-
const value =
|
|
65
|
+
const value = tokenizer(valueChars, line, col, offset);
|
|
69
66
|
line = value.endLine;
|
|
70
67
|
col = value.endCol;
|
|
71
68
|
offset = value.endOffset;
|
|
72
|
-
const endQuote =
|
|
69
|
+
const endQuote = tokenizer('}', line, col, offset);
|
|
73
70
|
line = endQuote.endLine;
|
|
74
71
|
col = endQuote.endCol;
|
|
75
72
|
offset = endQuote.endOffset;
|
|
76
73
|
const result = {
|
|
77
74
|
type: 'html-attr',
|
|
78
|
-
uuid:
|
|
75
|
+
uuid: uuid(),
|
|
79
76
|
raw: attrToken.raw,
|
|
80
77
|
startOffset: attrToken.startOffset,
|
|
81
78
|
endOffset: attrToken.endOffset,
|
|
@@ -102,4 +99,3 @@ function directiveTokenizer(raw, rawValue, line, col, startOffset) {
|
|
|
102
99
|
};
|
|
103
100
|
return result;
|
|
104
101
|
}
|
|
105
|
-
exports.default = directiveTokenizer;
|
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
|
-
|
|
2
|
-
|
|
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/nodeize.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { SvelteNode } from './svelte-parser';
|
|
1
|
+
import type { SvelteNode } from './svelte-parser/index.js';
|
|
2
2
|
import type { MLASTNode, MLASTParentNode, ParserOptions } from '@markuplint/ml-ast';
|
|
3
3
|
export declare function nodeize(originNode: SvelteNode, prevNode: MLASTNode | null, parentNode: MLASTParentNode | null, rawHtml: string, options?: ParserOptions): MLASTNode | MLASTNode[] | null;
|
package/lib/nodeize.js
CHANGED
|
@@ -1,26 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const parse_ctrl_block_1 = require("./parse-ctrl-block");
|
|
8
|
-
const traverse_1 = require("./traverse");
|
|
9
|
-
function nodeize(
|
|
1
|
+
import { getNamespace, parseRawTag } from '@markuplint/html-parser';
|
|
2
|
+
import { detectElementType, sliceFragment, uuid } from '@markuplint/parser-utils';
|
|
3
|
+
import { attr } from './attr.js';
|
|
4
|
+
import { parseCtrlBlock } from './parse-ctrl-block.js';
|
|
5
|
+
import { traverse } from './traverse.js';
|
|
6
|
+
export function nodeize(
|
|
10
7
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
11
8
|
originNode,
|
|
12
9
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
13
10
|
prevNode,
|
|
14
11
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
15
12
|
parentNode, rawHtml, options) {
|
|
16
|
-
var _a, _b, _c, _d, _e, _f;
|
|
17
13
|
const nextNode = null;
|
|
18
|
-
const { startOffset, endOffset, startLine, endLine, startCol, endCol, raw } =
|
|
14
|
+
const { startOffset, endOffset, startLine, endLine, startCol, endCol, raw } = sliceFragment(rawHtml, originNode.start, originNode.end);
|
|
19
15
|
const parentNamespace = parentNode && 'namespace' in parentNode ? parentNode.namespace : 'http://www.w3.org/1999/xhtml';
|
|
20
16
|
switch (originNode.type) {
|
|
21
17
|
case 'Text': {
|
|
22
18
|
const node = {
|
|
23
|
-
uuid:
|
|
19
|
+
uuid: uuid(),
|
|
24
20
|
raw,
|
|
25
21
|
startOffset,
|
|
26
22
|
endOffset,
|
|
@@ -40,7 +36,7 @@ parentNode, rawHtml, options) {
|
|
|
40
36
|
}
|
|
41
37
|
case 'MustacheTag': {
|
|
42
38
|
return {
|
|
43
|
-
uuid:
|
|
39
|
+
uuid: uuid(),
|
|
44
40
|
raw,
|
|
45
41
|
startOffset,
|
|
46
42
|
endOffset,
|
|
@@ -59,10 +55,10 @@ parentNode, rawHtml, options) {
|
|
|
59
55
|
}
|
|
60
56
|
case 'InlineComponent':
|
|
61
57
|
case 'Element': {
|
|
62
|
-
const children =
|
|
58
|
+
const children = originNode.children ?? [];
|
|
63
59
|
const reEndTag = new RegExp(`</${originNode.name}\\s*>$`, 'i');
|
|
64
|
-
const startTagEndOffset = children.length > 0 ?
|
|
65
|
-
const startTagLocation =
|
|
60
|
+
const startTagEndOffset = children.length > 0 ? children[0]?.start ?? 0 : raw.replace(reEndTag, '').length + startOffset;
|
|
61
|
+
const startTagLocation = sliceFragment(rawHtml, startOffset, startTagEndOffset);
|
|
66
62
|
let endTag = null;
|
|
67
63
|
if (reEndTag.test(raw)) {
|
|
68
64
|
const endTagRawMatched = raw.match(reEndTag);
|
|
@@ -72,10 +68,10 @@ parentNode, rawHtml, options) {
|
|
|
72
68
|
const endTagRaw = endTagRawMatched[0];
|
|
73
69
|
const endTagStartOffset = startOffset + raw.lastIndexOf(endTagRaw);
|
|
74
70
|
const endTagEndOffset = endTagStartOffset + endTagRaw.length;
|
|
75
|
-
const endTagLocation =
|
|
76
|
-
const namespace =
|
|
71
|
+
const endTagLocation = sliceFragment(rawHtml, endTagStartOffset, endTagEndOffset);
|
|
72
|
+
const namespace = getNamespace(originNode.name, parentNamespace);
|
|
77
73
|
endTag = {
|
|
78
|
-
uuid:
|
|
74
|
+
uuid: uuid(),
|
|
79
75
|
raw: endTagRaw,
|
|
80
76
|
startOffset: endTagStartOffset,
|
|
81
77
|
endOffset: endTagEndOffset,
|
|
@@ -97,18 +93,18 @@ parentNode, rawHtml, options) {
|
|
|
97
93
|
tagCloseChar: '>',
|
|
98
94
|
};
|
|
99
95
|
}
|
|
100
|
-
const directives =
|
|
96
|
+
const directives = originNode.attributes.map(a => attr(a, rawHtml)) ?? [];
|
|
101
97
|
const attributes = directives.filter((d) => !('__spreadAttr' in d));
|
|
102
98
|
const hasSpreadAttr = directives.some(d => '__spreadAttr' in d);
|
|
103
|
-
const tagTokens =
|
|
104
|
-
const namespace =
|
|
99
|
+
const tagTokens = parseRawTag(startTagLocation.raw, startTagLocation.startLine, startTagLocation.startCol, startTagLocation.startOffset);
|
|
100
|
+
const namespace = getNamespace(originNode.name, parentNamespace);
|
|
105
101
|
const startTag = {
|
|
106
|
-
uuid:
|
|
102
|
+
uuid: uuid(),
|
|
107
103
|
...startTagLocation,
|
|
108
104
|
nodeName: originNode.name,
|
|
109
105
|
type: 'starttag',
|
|
110
106
|
namespace,
|
|
111
|
-
elementType:
|
|
107
|
+
elementType: detectElementType(originNode.name, options?.authoredElementName, /[A-Z]|\./),
|
|
112
108
|
attributes,
|
|
113
109
|
hasSpreadAttr,
|
|
114
110
|
parentNode,
|
|
@@ -126,22 +122,22 @@ parentNode, rawHtml, options) {
|
|
|
126
122
|
endTag.pearNode = startTag;
|
|
127
123
|
}
|
|
128
124
|
if (originNode.children) {
|
|
129
|
-
startTag.childNodes =
|
|
125
|
+
startTag.childNodes = traverse(originNode.children, startTag, rawHtml, options);
|
|
130
126
|
}
|
|
131
127
|
return startTag;
|
|
132
128
|
}
|
|
133
129
|
case 'IfBlock': {
|
|
134
|
-
const ifBlocks =
|
|
130
|
+
const ifBlocks = parseCtrlBlock('if', originNode, raw, rawHtml, startOffset, parentNode, prevNode, nextNode, options);
|
|
135
131
|
return ifBlocks;
|
|
136
132
|
}
|
|
137
133
|
case 'EachBlock': {
|
|
138
|
-
return
|
|
134
|
+
return parseCtrlBlock('each', originNode, raw, rawHtml, startOffset, parentNode, prevNode, nextNode, options);
|
|
139
135
|
}
|
|
140
136
|
case 'AwaitBlock': {
|
|
141
137
|
const pendingNode = originNode.pending;
|
|
142
|
-
const pendingTag =
|
|
138
|
+
const pendingTag = sliceFragment(rawHtml, originNode.start, pendingNode.start);
|
|
143
139
|
const pending = {
|
|
144
|
-
uuid:
|
|
140
|
+
uuid: uuid(),
|
|
145
141
|
...pendingTag,
|
|
146
142
|
nodeName: pendingNode.type,
|
|
147
143
|
type: 'psblock',
|
|
@@ -152,14 +148,14 @@ parentNode, rawHtml, options) {
|
|
|
152
148
|
isGhost: false,
|
|
153
149
|
};
|
|
154
150
|
if (pendingNode.children) {
|
|
155
|
-
pending.childNodes =
|
|
151
|
+
pending.childNodes = traverse(pendingNode.children, pending, rawHtml, options);
|
|
156
152
|
}
|
|
157
153
|
let then = null;
|
|
158
154
|
if (originNode.then) {
|
|
159
155
|
const thenNode = originNode.then;
|
|
160
|
-
const thenTag =
|
|
156
|
+
const thenTag = sliceFragment(rawHtml, thenNode.start, (thenNode.children && thenNode.children[0] && thenNode.children[0].start) ?? thenNode.end);
|
|
161
157
|
then = {
|
|
162
|
-
uuid:
|
|
158
|
+
uuid: uuid(),
|
|
163
159
|
...thenTag,
|
|
164
160
|
nodeName: thenNode.type,
|
|
165
161
|
type: 'psblock',
|
|
@@ -170,15 +166,16 @@ parentNode, rawHtml, options) {
|
|
|
170
166
|
isGhost: false,
|
|
171
167
|
};
|
|
172
168
|
if (thenNode.children) {
|
|
173
|
-
then.childNodes =
|
|
169
|
+
then.childNodes = traverse(thenNode.children, then, rawHtml, options);
|
|
174
170
|
}
|
|
175
171
|
}
|
|
176
172
|
let awaitCatch = null;
|
|
177
173
|
if (originNode.catch) {
|
|
178
174
|
const awaitCatchNode = originNode.catch;
|
|
179
|
-
const awaitCatchTag =
|
|
175
|
+
const awaitCatchTag = sliceFragment(rawHtml, awaitCatchNode.start, (awaitCatchNode.children && awaitCatchNode.children[0] && awaitCatchNode.children[0].start) ??
|
|
176
|
+
awaitCatchNode.end);
|
|
180
177
|
awaitCatch = {
|
|
181
|
-
uuid:
|
|
178
|
+
uuid: uuid(),
|
|
182
179
|
...awaitCatchTag,
|
|
183
180
|
nodeName: awaitCatchNode.type,
|
|
184
181
|
type: 'psblock',
|
|
@@ -189,7 +186,7 @@ parentNode, rawHtml, options) {
|
|
|
189
186
|
isGhost: false,
|
|
190
187
|
};
|
|
191
188
|
if (awaitCatchNode.children) {
|
|
192
|
-
awaitCatch.childNodes =
|
|
189
|
+
awaitCatch.childNodes = traverse(awaitCatchNode.children, awaitCatch, rawHtml, options);
|
|
193
190
|
}
|
|
194
191
|
}
|
|
195
192
|
const reEndTag = new RegExp('{/await}$', 'i');
|
|
@@ -202,9 +199,9 @@ parentNode, rawHtml, options) {
|
|
|
202
199
|
const endTagRaw = endTagRawMatched[0];
|
|
203
200
|
const endTagStartOffset = startOffset + raw.indexOf(endTagRaw);
|
|
204
201
|
const endTagEndOffset = endTagStartOffset + endTagRaw.length;
|
|
205
|
-
const endTagLocation =
|
|
202
|
+
const endTagLocation = sliceFragment(rawHtml, endTagStartOffset, endTagEndOffset);
|
|
206
203
|
endTag = {
|
|
207
|
-
uuid:
|
|
204
|
+
uuid: uuid(),
|
|
208
205
|
raw: endTagRaw,
|
|
209
206
|
startOffset: endTagStartOffset,
|
|
210
207
|
endOffset: endTagEndOffset,
|
|
@@ -235,7 +232,7 @@ parentNode, rawHtml, options) {
|
|
|
235
232
|
}
|
|
236
233
|
default: {
|
|
237
234
|
const startTag = {
|
|
238
|
-
uuid:
|
|
235
|
+
uuid: uuid(),
|
|
239
236
|
raw,
|
|
240
237
|
startOffset,
|
|
241
238
|
endOffset,
|
|
@@ -253,7 +250,7 @@ parentNode, rawHtml, options) {
|
|
|
253
250
|
};
|
|
254
251
|
let endTag = null;
|
|
255
252
|
if (originNode.children) {
|
|
256
|
-
startTag.childNodes =
|
|
253
|
+
startTag.childNodes = traverse(originNode.children, startTag, rawHtml, options);
|
|
257
254
|
const firstChild = startTag.childNodes[0];
|
|
258
255
|
if (firstChild) {
|
|
259
256
|
startTag.endOffset = firstChild.startOffset;
|
|
@@ -268,7 +265,7 @@ parentNode, rawHtml, options) {
|
|
|
268
265
|
const startCol = lastChild.endCol;
|
|
269
266
|
const raw = rawHtml.slice(startOffset, endOffset);
|
|
270
267
|
endTag = {
|
|
271
|
-
uuid:
|
|
268
|
+
uuid: uuid(),
|
|
272
269
|
raw,
|
|
273
270
|
startOffset,
|
|
274
271
|
endOffset,
|
|
@@ -290,4 +287,3 @@ parentNode, rawHtml, options) {
|
|
|
290
287
|
}
|
|
291
288
|
}
|
|
292
289
|
}
|
|
293
|
-
exports.nodeize = nodeize;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { SvelteNode } from './svelte-parser';
|
|
1
|
+
import type { SvelteNode } from './svelte-parser/index.js';
|
|
2
2
|
import type { MLASTNode, MLASTParentNode, MLASTPreprocessorSpecificBlock, ParserOptions } from '@markuplint/ml-ast';
|
|
3
3
|
export declare function parseCtrlBlock(ctrlName: 'if' | 'each', originNode: SvelteNode, raw: string, rawHtml: string, startOffset: number, parentNode: MLASTParentNode | null, prevNode: MLASTNode | null, nextNode: MLASTNode | null, options?: ParserOptions): MLASTPreprocessorSpecificBlock[];
|
package/lib/parse-ctrl-block.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const parser_utils_1 = require("@markuplint/parser-utils");
|
|
5
|
-
const traverse_1 = require("./traverse");
|
|
6
|
-
function parseCtrlBlock(ctrlName,
|
|
1
|
+
import { sliceFragment, uuid } from '@markuplint/parser-utils';
|
|
2
|
+
import { traverse } from './traverse.js';
|
|
3
|
+
export function parseCtrlBlock(ctrlName,
|
|
7
4
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
8
5
|
originNode, raw, rawHtml, startOffset,
|
|
9
6
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
@@ -12,16 +9,15 @@ parentNode,
|
|
|
12
9
|
prevNode,
|
|
13
10
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
14
11
|
nextNode, options) {
|
|
15
|
-
var _a, _b, _c, _d, _e;
|
|
16
12
|
if (ctrlName === 'if') {
|
|
17
13
|
return parseIfBlock(originNode, raw, rawHtml, startOffset, originNode.start, parentNode, prevNode, nextNode, options);
|
|
18
14
|
}
|
|
19
|
-
const children =
|
|
15
|
+
const children = originNode.children ?? [];
|
|
20
16
|
const reEndTag = new RegExp('{/each}$', 'i');
|
|
21
|
-
const startTagEndOffset = children.length > 0 ?
|
|
22
|
-
const startTagLocation =
|
|
17
|
+
const startTagEndOffset = children.length > 0 ? children[0]?.start ?? 0 : raw.replace(reEndTag, '').length + startOffset;
|
|
18
|
+
const startTagLocation = sliceFragment(rawHtml, startOffset, startTagEndOffset);
|
|
23
19
|
const tag = {
|
|
24
|
-
uuid:
|
|
20
|
+
uuid: uuid(),
|
|
25
21
|
...startTagLocation,
|
|
26
22
|
nodeName: originNode.type,
|
|
27
23
|
type: 'psblock',
|
|
@@ -32,15 +28,15 @@ nextNode, options) {
|
|
|
32
28
|
isGhost: false,
|
|
33
29
|
};
|
|
34
30
|
if (originNode.children) {
|
|
35
|
-
tag.childNodes =
|
|
31
|
+
tag.childNodes = traverse(originNode.children, tag, rawHtml, options);
|
|
36
32
|
}
|
|
37
33
|
let elseTag = null;
|
|
38
34
|
if (originNode.else) {
|
|
39
35
|
const elseNode = originNode.else;
|
|
40
|
-
const elseTagStartOffset = children.length > 0 ?
|
|
41
|
-
const elseTagLocation =
|
|
36
|
+
const elseTagStartOffset = children.length > 0 ? children[children.length - 1]?.end ?? 0 : startTagLocation.endOffset;
|
|
37
|
+
const elseTagLocation = sliceFragment(rawHtml, elseTagStartOffset, elseNode.start);
|
|
42
38
|
elseTag = {
|
|
43
|
-
uuid:
|
|
39
|
+
uuid: uuid(),
|
|
44
40
|
...elseTagLocation,
|
|
45
41
|
nodeName: elseNode.type,
|
|
46
42
|
type: 'psblock',
|
|
@@ -51,7 +47,7 @@ nextNode, options) {
|
|
|
51
47
|
isGhost: false,
|
|
52
48
|
};
|
|
53
49
|
if (elseNode.children) {
|
|
54
|
-
elseTag.childNodes =
|
|
50
|
+
elseTag.childNodes = traverse(elseNode.children, elseTag, rawHtml, options);
|
|
55
51
|
}
|
|
56
52
|
}
|
|
57
53
|
let endTag = null;
|
|
@@ -60,9 +56,9 @@ nextNode, options) {
|
|
|
60
56
|
const endTagRaw = endTagRawMatched[0];
|
|
61
57
|
const endTagStartOffset = originNode.end - endTagRaw.length;
|
|
62
58
|
const endTagEndOffset = originNode.end;
|
|
63
|
-
const endTagLocation =
|
|
59
|
+
const endTagLocation = sliceFragment(rawHtml, endTagStartOffset, endTagEndOffset);
|
|
64
60
|
endTag = {
|
|
65
|
-
uuid:
|
|
61
|
+
uuid: uuid(),
|
|
66
62
|
raw: endTagRaw,
|
|
67
63
|
startOffset: endTagStartOffset,
|
|
68
64
|
endOffset: endTagEndOffset,
|
|
@@ -88,7 +84,6 @@ nextNode, options) {
|
|
|
88
84
|
}
|
|
89
85
|
return tags;
|
|
90
86
|
}
|
|
91
|
-
exports.parseCtrlBlock = parseCtrlBlock;
|
|
92
87
|
function parseIfBlock(
|
|
93
88
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
94
89
|
originNode, raw, rawHtml, statementStartOffset, tokenStartOffset,
|
|
@@ -98,12 +93,11 @@ parentNode,
|
|
|
98
93
|
prevNode,
|
|
99
94
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
100
95
|
nextNode, options) {
|
|
101
|
-
|
|
102
|
-
const
|
|
103
|
-
const
|
|
104
|
-
const startTagLocation = (0, parser_utils_1.sliceFragment)(rawHtml, tokenStartOffset, startTagEndOffset);
|
|
96
|
+
const children = originNode.children ?? [];
|
|
97
|
+
const startTagEndOffset = children[0]?.start ?? tokenStartOffset;
|
|
98
|
+
const startTagLocation = sliceFragment(rawHtml, tokenStartOffset, startTagEndOffset);
|
|
105
99
|
const tag = {
|
|
106
|
-
uuid:
|
|
100
|
+
uuid: uuid(),
|
|
107
101
|
...startTagLocation,
|
|
108
102
|
nodeName: originNode.elseif ? 'ElseIfBlock' : originNode.type,
|
|
109
103
|
type: 'psblock',
|
|
@@ -114,21 +108,21 @@ nextNode, options) {
|
|
|
114
108
|
isGhost: false,
|
|
115
109
|
};
|
|
116
110
|
if (originNode.children) {
|
|
117
|
-
tag.childNodes =
|
|
111
|
+
tag.childNodes = traverse(originNode.children, tag, rawHtml, options);
|
|
118
112
|
}
|
|
119
113
|
const elseOrElseIfTags = [];
|
|
120
114
|
if (originNode.else) {
|
|
121
115
|
const elseNode = originNode.else;
|
|
122
|
-
const elseTagStartOffset = children.length > 0 ?
|
|
123
|
-
const elseTagLocation =
|
|
116
|
+
const elseTagStartOffset = children.length > 0 ? children[children.length - 1]?.end ?? 0 : startTagLocation.endOffset;
|
|
117
|
+
const elseTagLocation = sliceFragment(rawHtml, elseTagStartOffset, elseNode.start);
|
|
124
118
|
if (elseNode.children) {
|
|
125
|
-
if (elseNode.children.length === 1 &&
|
|
126
|
-
const elseIfTags = parseIfBlock(elseNode.children[0], elseTagLocation.raw, rawHtml, statementStartOffset,
|
|
119
|
+
if (elseNode.children.length === 1 && elseNode.children[0]?.type === 'IfBlock') {
|
|
120
|
+
const elseIfTags = parseIfBlock(elseNode.children[0], elseTagLocation.raw, rawHtml, statementStartOffset, originNode.children?.[0]?.end ?? startTagLocation.endOffset, parentNode, null, null, options);
|
|
127
121
|
elseOrElseIfTags.push(...elseIfTags);
|
|
128
122
|
}
|
|
129
123
|
else {
|
|
130
124
|
const elseTag = {
|
|
131
|
-
uuid:
|
|
125
|
+
uuid: uuid(),
|
|
132
126
|
...elseTagLocation,
|
|
133
127
|
nodeName: elseNode.type,
|
|
134
128
|
type: 'psblock',
|
|
@@ -138,7 +132,7 @@ nextNode, options) {
|
|
|
138
132
|
isFragment: false,
|
|
139
133
|
isGhost: false,
|
|
140
134
|
};
|
|
141
|
-
elseTag.childNodes =
|
|
135
|
+
elseTag.childNodes = traverse(elseNode.children, elseTag, rawHtml, options);
|
|
142
136
|
elseOrElseIfTags.push(elseTag);
|
|
143
137
|
}
|
|
144
138
|
}
|
|
@@ -153,9 +147,9 @@ nextNode, options) {
|
|
|
153
147
|
const endTagRaw = endTagRawMatched[0];
|
|
154
148
|
const endTagStartOffset = originNode.end - endTagRaw.length;
|
|
155
149
|
const endTagEndOffset = originNode.end;
|
|
156
|
-
const endTagLocation =
|
|
150
|
+
const endTagLocation = sliceFragment(rawHtml, endTagStartOffset, endTagEndOffset);
|
|
157
151
|
const endTag = {
|
|
158
|
-
uuid:
|
|
152
|
+
uuid: uuid(),
|
|
159
153
|
raw: endTagRaw,
|
|
160
154
|
startOffset: endTagStartOffset,
|
|
161
155
|
endOffset: endTagEndOffset,
|
package/lib/parse.js
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const svelte_parser_1 = tslib_1.__importDefault(require("./svelte-parser"));
|
|
7
|
-
const traverse_1 = require("./traverse");
|
|
8
|
-
const parse = (rawCode, options) => {
|
|
9
|
-
const blocks = (0, parser_utils_1.ignoreBlock)(rawCode, [
|
|
1
|
+
import { flattenNodes, ParserError, ignoreBlock, restoreNode } from '@markuplint/parser-utils';
|
|
2
|
+
import svelteParse from './svelte-parser/index.js';
|
|
3
|
+
import { traverse } from './traverse.js';
|
|
4
|
+
export const parse = (rawCode, options) => {
|
|
5
|
+
const blocks = ignoreBlock(rawCode, [
|
|
10
6
|
{
|
|
11
7
|
type: 'Script',
|
|
12
8
|
start: /<script/,
|
|
@@ -20,13 +16,13 @@ const parse = (rawCode, options) => {
|
|
|
20
16
|
], '-');
|
|
21
17
|
let ast;
|
|
22
18
|
try {
|
|
23
|
-
ast = (
|
|
19
|
+
ast = svelteParse(blocks.replaced);
|
|
24
20
|
}
|
|
25
21
|
catch (err) {
|
|
26
22
|
if (err instanceof Error && 'start' in err && 'end' in err && 'frame' in err) {
|
|
27
23
|
// @ts-ignore
|
|
28
24
|
const raw = rawCode.slice(err.start.character, err.end.character);
|
|
29
|
-
throw new
|
|
25
|
+
throw new ParserError(
|
|
30
26
|
// @ts-ignore
|
|
31
27
|
err.message + '\n' + err.frame, {
|
|
32
28
|
// @ts-ignore
|
|
@@ -42,11 +38,10 @@ const parse = (rawCode, options) => {
|
|
|
42
38
|
parseError: err instanceof Error ? err.message : new Error(`${err}`).message,
|
|
43
39
|
};
|
|
44
40
|
}
|
|
45
|
-
const nodes =
|
|
46
|
-
const nodeList =
|
|
41
|
+
const nodes = traverse(ast, null, blocks.replaced, options);
|
|
42
|
+
const nodeList = restoreNode(flattenNodes(nodes, blocks.replaced), blocks);
|
|
47
43
|
return {
|
|
48
44
|
nodeList,
|
|
49
45
|
isFragment: true,
|
|
50
46
|
};
|
|
51
47
|
};
|
|
52
|
-
exports.parse = parse;
|
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
function svelteParse(template) {
|
|
5
|
-
var _a;
|
|
6
|
-
const ast = (0, compiler_1.parse)(template, { customElement: true });
|
|
1
|
+
import { parse } from 'svelte/compiler';
|
|
2
|
+
export default function svelteParse(template) {
|
|
3
|
+
const ast = parse(template, { customElement: true });
|
|
7
4
|
const start = ast.html.start;
|
|
8
|
-
const children =
|
|
5
|
+
const children = ast.html.children ?? [];
|
|
9
6
|
if (children[0] && children[0].end === start) {
|
|
10
7
|
children.shift();
|
|
11
8
|
}
|
|
12
9
|
return children;
|
|
13
10
|
}
|
|
14
|
-
exports.default = svelteParse;
|
package/lib/traverse.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { SvelteNode } from './svelte-parser';
|
|
1
|
+
import type { SvelteNode } from './svelte-parser/index.js';
|
|
2
2
|
import type { MLASTNode, MLASTParentNode, ParserOptions } from '@markuplint/ml-ast';
|
|
3
3
|
export declare function traverse(astNodes: readonly SvelteNode[], parentNode: MLASTParentNode | null | undefined, rawHtml: string, options?: ParserOptions): MLASTNode[];
|