@markuplint/astro-parser 3.0.0-alpha.6 → 3.0.0-dev.176
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/README.md +4 -4
- package/lib/astro-parser.d.ts +11 -11
- package/lib/astro-parser.js +11 -16
- package/lib/attr-tokenizer.d.ts +8 -2
- package/lib/attr-tokenizer.js +52 -69
- package/lib/parse.js +162 -135
- package/package.json +8 -7
- package/test/astro-parser.spec.js +444 -0
- package/test/parse.spec.js +483 -0
- package/tsconfig.test.json +0 -3
- package/tsconfig.tsbuildinfo +0 -1
package/README.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# @markuplint/astro-parser
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@markuplint/astro-parser)
|
|
4
|
-
|
|
5
|
-
[
|
|
4
|
+
|
|
5
|
+
Use **markuplint** with [**Astro**](https://astro.build/).
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
9
|
-
```
|
|
9
|
+
```shell
|
|
10
10
|
$ npm install -D @markuplint/astro-parser
|
|
11
11
|
|
|
12
12
|
$ yarn add -D @markuplint/astro-parser
|
|
@@ -14,7 +14,7 @@ $ yarn add -D @markuplint/astro-parser
|
|
|
14
14
|
|
|
15
15
|
## Usage
|
|
16
16
|
|
|
17
|
-
Add `parser` option
|
|
17
|
+
Add `parser` option to your [configuration](https://markuplint.dev/configuration/#properties/parser).
|
|
18
18
|
|
|
19
19
|
```json
|
|
20
20
|
{
|
package/lib/astro-parser.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
};
|
|
11
|
-
export declare function astroParse(code: string):
|
|
1
|
+
import type { RootNode } from '@astrojs/compiler/shared/ast';
|
|
2
|
+
export type {
|
|
3
|
+
RootNode,
|
|
4
|
+
ElementNode,
|
|
5
|
+
CustomElementNode,
|
|
6
|
+
ComponentNode,
|
|
7
|
+
FragmentNode,
|
|
8
|
+
AttributeNode,
|
|
9
|
+
Node,
|
|
10
|
+
} from '@astrojs/compiler/shared/ast';
|
|
11
|
+
export declare function astroParse(code: string): RootNode;
|
package/lib/astro-parser.js
CHANGED
|
@@ -1,22 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.astroParse =
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
Object.defineProperty(exports, "AstroCompileError", { enumerable: true, get: function () { return parser_2.CompileError; } });
|
|
3
|
+
exports.astroParse = void 0;
|
|
4
|
+
const parser_utils_1 = require("@markuplint/parser-utils");
|
|
5
|
+
const astro_eslint_parser_1 = require("astro-eslint-parser");
|
|
7
6
|
function astroParse(code) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
catch (e) {
|
|
16
|
-
if (e instanceof parser_1.CompileError) {
|
|
17
|
-
return e;
|
|
18
|
-
}
|
|
19
|
-
throw e;
|
|
7
|
+
const { result } = (0, astro_eslint_parser_1.parseTemplate)(code);
|
|
8
|
+
if (result.diagnostics[0]) {
|
|
9
|
+
const error = result.diagnostics[0];
|
|
10
|
+
throw new parser_utils_1.ParserError(error.text, {
|
|
11
|
+
line: error.location.line,
|
|
12
|
+
col: error.location.column,
|
|
13
|
+
});
|
|
20
14
|
}
|
|
15
|
+
return result.ast;
|
|
21
16
|
}
|
|
22
17
|
exports.astroParse = astroParse;
|
package/lib/attr-tokenizer.d.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AttributeNode } from './astro-parser';
|
|
2
2
|
import type { MLASTHTMLAttr } from '@markuplint/ml-ast';
|
|
3
|
-
export declare function attrTokenizer(
|
|
3
|
+
export declare function attrTokenizer(
|
|
4
|
+
attr: AttributeNode,
|
|
5
|
+
nextAttr: AttributeNode | null,
|
|
6
|
+
rawHtml: string,
|
|
7
|
+
startTag: string,
|
|
8
|
+
startTagEndOffset: number,
|
|
9
|
+
): MLASTHTMLAttr;
|
package/lib/attr-tokenizer.js
CHANGED
|
@@ -2,78 +2,61 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.attrTokenizer = void 0;
|
|
4
4
|
const parser_utils_1 = require("@markuplint/parser-utils");
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const name = (0, parser_utils_1.createTokenFromRawCode)(attr.name, spacesBeforeName.endOffset, rawHtml);
|
|
18
|
-
let rawValue;
|
|
19
|
-
let rawValueStart;
|
|
20
|
-
if (
|
|
21
|
-
//
|
|
22
|
-
!attr.value ||
|
|
23
|
-
// @ts-ignore
|
|
24
|
-
attr.value === true ||
|
|
25
|
-
//
|
|
26
|
-
attr.value.length === 0) {
|
|
27
|
-
rawValue = '';
|
|
28
|
-
rawValueStart = name.endOffset;
|
|
5
|
+
const mustacheTag = {
|
|
6
|
+
start: '{',
|
|
7
|
+
end: '}',
|
|
8
|
+
};
|
|
9
|
+
function attrTokenizer(
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
11
|
+
attr,
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
13
|
+
nextAttr, rawHtml, startTag, startTagEndOffset) {
|
|
14
|
+
var _a, _b, _c;
|
|
15
|
+
if (!attr.position) {
|
|
16
|
+
throw new TypeError("Attr doesn't have position");
|
|
29
17
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
18
|
+
if (attr.position.end) {
|
|
19
|
+
throw new TypeError('Node may is an attribute because it has end position');
|
|
20
|
+
}
|
|
21
|
+
let nextAttrBeforeSpaceOffset;
|
|
22
|
+
if (nextAttr) {
|
|
23
|
+
if (!nextAttr.position) {
|
|
24
|
+
throw new TypeError("NextAttr doesn't have position");
|
|
25
|
+
}
|
|
26
|
+
if (nextAttr.position.end) {
|
|
27
|
+
throw new TypeError('NextAttr Node may is an attribute because it has end position');
|
|
28
|
+
}
|
|
29
|
+
nextAttrBeforeSpaceOffset = (0, parser_utils_1.getSpaceBefore)(nextAttr.position.start.offset, rawHtml).startOffset;
|
|
33
30
|
}
|
|
34
31
|
else {
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
const close = (_b = (_a = /(\/?>)$/.exec(startTag)) === null || _a === void 0 ? void 0 : _a[1]) !== null && _b !== void 0 ? _b : '';
|
|
33
|
+
nextAttrBeforeSpaceOffset = startTagEndOffset - close.length;
|
|
34
|
+
}
|
|
35
|
+
const { raw, startOffset } = (0, parser_utils_1.sliceFragment)(rawHtml, attr.position.start.offset, nextAttrBeforeSpaceOffset);
|
|
36
|
+
const result = (0, parser_utils_1.parseAttr)(raw, startOffset, rawHtml, {
|
|
37
|
+
valueDelimiters: [...parser_utils_1.defaultValueDelimiters, mustacheTag],
|
|
38
|
+
});
|
|
39
|
+
if (result.startQuote.raw === mustacheTag.start) {
|
|
40
|
+
result.isDynamicValue = true;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Detects Template Directive
|
|
44
|
+
*
|
|
45
|
+
* @see https://docs.astro.build/en/reference/directives-reference/
|
|
46
|
+
*/
|
|
47
|
+
const [, directive] = (_c = result.name.raw.match(/^([^:]+):([^:]+)$/)) !== null && _c !== void 0 ? _c : [];
|
|
48
|
+
if (directive) {
|
|
49
|
+
const lowerCaseDirectiveName = directive.toLowerCase();
|
|
50
|
+
switch (lowerCaseDirectiveName) {
|
|
51
|
+
case 'class': {
|
|
52
|
+
result.potentialName = lowerCaseDirectiveName;
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
default: {
|
|
56
|
+
result.isDirective = true;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
37
59
|
}
|
|
38
|
-
|
|
39
|
-
const eq = (0, parser_utils_1.sliceFragment)(rawHtml, name.endOffset, value.startOffset);
|
|
40
|
-
const eqRegexp = /^(?<bs>\s*)(?<eq>=)(?<as>\s*)(?<squot>"|'|{)?$/g;
|
|
41
|
-
const exp = eqRegexp.exec(eq.raw);
|
|
42
|
-
const bsChar = ((_c = exp === null || exp === void 0 ? void 0 : exp.groups) === null || _c === void 0 ? void 0 : _c.bs) || '';
|
|
43
|
-
const eqChar = ((_d = exp === null || exp === void 0 ? void 0 : exp.groups) === null || _d === void 0 ? void 0 : _d.eq) || '';
|
|
44
|
-
const asChar = ((_e = exp === null || exp === void 0 ? void 0 : exp.groups) === null || _e === void 0 ? void 0 : _e.as) || '';
|
|
45
|
-
const squotChar = ((_f = exp === null || exp === void 0 ? void 0 : exp.groups) === null || _f === void 0 ? void 0 : _f.squot) || '';
|
|
46
|
-
const spacesBeforeEqual = (0, parser_utils_1.createTokenFromRawCode)(bsChar, name.endOffset, rawHtml);
|
|
47
|
-
const equal = (0, parser_utils_1.createTokenFromRawCode)(eqChar, spacesBeforeEqual.endOffset, rawHtml);
|
|
48
|
-
const spacesAfterEqual = (0, parser_utils_1.createTokenFromRawCode)(asChar, equal.endOffset, rawHtml);
|
|
49
|
-
const startQuote = (0, parser_utils_1.createTokenFromRawCode)(squotChar, spacesAfterEqual.endOffset, rawHtml);
|
|
50
|
-
const endQuote = (0, parser_utils_1.createTokenFromRawCode)(squotChar === '{' ? '}' : squotChar, value.endOffset, rawHtml);
|
|
51
|
-
return {
|
|
52
|
-
type: 'html-attr',
|
|
53
|
-
uuid: (0, parser_utils_1.uuid)(),
|
|
54
|
-
raw: attrToken.raw,
|
|
55
|
-
startOffset: attrToken.startOffset,
|
|
56
|
-
endOffset: attrToken.endOffset,
|
|
57
|
-
startLine: attrToken.startLine,
|
|
58
|
-
endLine: attrToken.endLine,
|
|
59
|
-
startCol: attrToken.startCol,
|
|
60
|
-
endCol: attrToken.endCol,
|
|
61
|
-
spacesBeforeName,
|
|
62
|
-
name,
|
|
63
|
-
spacesBeforeEqual,
|
|
64
|
-
equal,
|
|
65
|
-
spacesAfterEqual,
|
|
66
|
-
startQuote,
|
|
67
|
-
value,
|
|
68
|
-
endQuote,
|
|
69
|
-
isDuplicatable: false,
|
|
70
|
-
isDynamicValue,
|
|
71
|
-
nodeName: name.raw,
|
|
72
|
-
parentNode: null,
|
|
73
|
-
nextNode: null,
|
|
74
|
-
prevNode: null,
|
|
75
|
-
isFragment: false,
|
|
76
|
-
isGhost: false,
|
|
77
|
-
};
|
|
60
|
+
return result;
|
|
78
61
|
}
|
|
79
62
|
exports.attrTokenizer = attrTokenizer;
|
package/lib/parse.js
CHANGED
|
@@ -5,52 +5,42 @@ const html_parser_1 = require("@markuplint/html-parser");
|
|
|
5
5
|
const parser_utils_1 = require("@markuplint/parser-utils");
|
|
6
6
|
const astro_parser_1 = require("./astro-parser");
|
|
7
7
|
const attr_tokenizer_1 = require("./attr-tokenizer");
|
|
8
|
-
const parse = (rawCode, options) => {
|
|
8
|
+
const parse = (rawCode, options = {}) => {
|
|
9
|
+
var _a, _b;
|
|
9
10
|
const ast = (0, astro_parser_1.astroParse)(rawCode);
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
const htmlRawNodeList = traverse(ast.html, null, 'http://www.w3.org/1999/xhtml', rawCode);
|
|
24
|
-
if (ast.style) {
|
|
25
|
-
const styleNodes = parseStyle(ast.style, 'http://www.w3.org/1999/xhtml', rawCode, 0, options);
|
|
26
|
-
htmlRawNodeList.push(...styleNodes);
|
|
27
|
-
}
|
|
28
|
-
const nodeList = (0, html_parser_1.flattenNodes)(htmlRawNodeList, rawCode);
|
|
29
|
-
// Remove `</template>`
|
|
30
|
-
const templateEndTagIndex = nodeList.findIndex(node => /\s*<\/\s*template\s*>\s*/i.test(node.raw));
|
|
31
|
-
if (templateEndTagIndex !== -1) {
|
|
32
|
-
const templateEndTag = nodeList[templateEndTagIndex];
|
|
33
|
-
for (const node of nodeList) {
|
|
34
|
-
if (node.nextNode && node.nextNode.uuid === templateEndTag.uuid) {
|
|
35
|
-
node.nextNode = null;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
nodeList.splice(templateEndTagIndex, 1);
|
|
11
|
+
const htmlRawNodeList = traverse(ast, null, 'http://www.w3.org/1999/xhtml', rawCode, 0, options);
|
|
12
|
+
const firstOffset = (_b = (_a = htmlRawNodeList[0]) === null || _a === void 0 ? void 0 : _a.startOffset) !== null && _b !== void 0 ? _b : 0;
|
|
13
|
+
if (firstOffset > 0) {
|
|
14
|
+
const head = rawCode.slice(0, firstOffset);
|
|
15
|
+
const ast = (0, html_parser_1.parse)(head, {
|
|
16
|
+
...options,
|
|
17
|
+
ignoreFrontMatter: true,
|
|
18
|
+
});
|
|
19
|
+
const headNodes = ast.nodeList.filter(node => {
|
|
20
|
+
return !node.isGhost;
|
|
21
|
+
});
|
|
22
|
+
htmlRawNodeList.unshift(...headNodes);
|
|
39
23
|
}
|
|
24
|
+
const nodeList = (0, parser_utils_1.flattenNodes)(htmlRawNodeList, rawCode);
|
|
40
25
|
return {
|
|
41
26
|
nodeList,
|
|
42
27
|
isFragment: true,
|
|
43
28
|
};
|
|
44
29
|
};
|
|
45
30
|
exports.parse = parse;
|
|
46
|
-
function traverse(
|
|
31
|
+
function traverse(
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
33
|
+
rootNode, parentNode = null, scopeNS, rawHtml, offset, options, inExpression) {
|
|
47
34
|
const nodeList = [];
|
|
48
|
-
if (!rootNode
|
|
35
|
+
if (!('children' in rootNode)) {
|
|
36
|
+
return nodeList;
|
|
37
|
+
}
|
|
38
|
+
if (rootNode.children.length === 0) {
|
|
49
39
|
return nodeList;
|
|
50
40
|
}
|
|
51
41
|
let prevNode = null;
|
|
52
42
|
for (const astNode of rootNode.children) {
|
|
53
|
-
const node = nodeize(astNode, prevNode, parentNode, scopeNS, rawHtml, offset, options);
|
|
43
|
+
const node = nodeize(astNode, prevNode, parentNode, scopeNS, rawHtml, offset, options, inExpression);
|
|
54
44
|
if (!node) {
|
|
55
45
|
continue;
|
|
56
46
|
}
|
|
@@ -68,22 +58,34 @@ function traverse(rootNode, parentNode = null, scopeNS, rawHtml, offset, options
|
|
|
68
58
|
}
|
|
69
59
|
return nodeList;
|
|
70
60
|
}
|
|
71
|
-
function nodeize(
|
|
72
|
-
|
|
61
|
+
function nodeize(
|
|
62
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
63
|
+
originNode,
|
|
64
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
65
|
+
prevNode,
|
|
66
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
67
|
+
parentNode, scopeNS, rawHtml, offset = 0, options, inExpression) {
|
|
68
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
69
|
+
if (!originNode.position) {
|
|
70
|
+
throw new TypeError("Node doesn't have position");
|
|
71
|
+
}
|
|
73
72
|
const nextNode = null;
|
|
74
|
-
const startOffset = originNode.start + offset;
|
|
75
|
-
const endOffset = originNode.end + offset;
|
|
73
|
+
const startOffset = originNode.position.start.offset + offset;
|
|
74
|
+
const endOffset = ((_b = (_a = originNode.position.end) === null || _a === void 0 ? void 0 : _a.offset) !== null && _b !== void 0 ? _b : originNode.position.start.offset) + offset;
|
|
76
75
|
const { startLine, endLine, startCol, endCol, raw } = (0, parser_utils_1.sliceFragment)(rawHtml, startOffset, endOffset);
|
|
77
76
|
if (scopeNS === 'http://www.w3.org/1999/xhtml' &&
|
|
78
|
-
originNode.type === '
|
|
79
|
-
((
|
|
77
|
+
originNode.type === 'element' &&
|
|
78
|
+
((_c = originNode.name) === null || _c === void 0 ? void 0 : _c.toLowerCase()) === 'svg') {
|
|
80
79
|
scopeNS = 'http://www.w3.org/2000/svg';
|
|
81
80
|
}
|
|
82
81
|
else if (scopeNS === 'http://www.w3.org/2000/svg' && parentNode && parentNode.nodeName === 'foreignObject') {
|
|
83
82
|
scopeNS = 'http://www.w3.org/1999/xhtml';
|
|
84
83
|
}
|
|
85
84
|
switch (originNode.type) {
|
|
86
|
-
case '
|
|
85
|
+
case 'text': {
|
|
86
|
+
if (inExpression) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
87
89
|
const node = {
|
|
88
90
|
uuid: (0, parser_utils_1.uuid)(),
|
|
89
91
|
raw,
|
|
@@ -103,18 +105,36 @@ function nodeize(originNode, prevNode, parentNode, scopeNS, rawHtml, offset = 0,
|
|
|
103
105
|
};
|
|
104
106
|
return node;
|
|
105
107
|
}
|
|
106
|
-
case '
|
|
107
|
-
|
|
108
|
-
|
|
108
|
+
case 'expression': {
|
|
109
|
+
let _endOffset = endOffset;
|
|
110
|
+
let _startLine = startLine;
|
|
111
|
+
let _endLine = endLine;
|
|
112
|
+
let _startCol = startCol;
|
|
113
|
+
let _endCol = endCol;
|
|
114
|
+
let _raw = raw;
|
|
115
|
+
let closeExpression = null;
|
|
116
|
+
const firstChild = originNode.children[0];
|
|
117
|
+
const lastChild = originNode.children[originNode.children.length - 1];
|
|
118
|
+
if (firstChild && lastChild && firstChild !== lastChild) {
|
|
119
|
+
_endOffset = (_f = (_e = (_d = firstChild.position) === null || _d === void 0 ? void 0 : _d.end) === null || _e === void 0 ? void 0 : _e.offset) !== null && _f !== void 0 ? _f : endOffset;
|
|
120
|
+
const startLoc = (0, parser_utils_1.sliceFragment)(rawHtml, startOffset, _endOffset);
|
|
121
|
+
_startLine = startLoc.startLine;
|
|
122
|
+
_endLine = startLoc.endLine;
|
|
123
|
+
_startCol = startLoc.startCol;
|
|
124
|
+
_endCol = startLoc.endCol;
|
|
125
|
+
_raw = startLoc.raw;
|
|
126
|
+
const closeStartOffset = (_h = (_g = lastChild.position) === null || _g === void 0 ? void 0 : _g.start.offset) !== null && _h !== void 0 ? _h : startOffset;
|
|
127
|
+
const closeLoc = (0, parser_utils_1.sliceFragment)(rawHtml, closeStartOffset, endOffset);
|
|
128
|
+
closeExpression = {
|
|
109
129
|
uuid: (0, parser_utils_1.uuid)(),
|
|
110
|
-
raw,
|
|
111
|
-
startOffset,
|
|
112
|
-
endOffset,
|
|
113
|
-
startLine,
|
|
114
|
-
endLine,
|
|
115
|
-
startCol,
|
|
116
|
-
endCol,
|
|
117
|
-
nodeName:
|
|
130
|
+
raw: closeLoc.raw,
|
|
131
|
+
startOffset: closeStartOffset,
|
|
132
|
+
endOffset: closeLoc.endOffset,
|
|
133
|
+
startLine: closeLoc.startLine,
|
|
134
|
+
endLine: closeLoc.endLine,
|
|
135
|
+
startCol: closeLoc.startCol,
|
|
136
|
+
endCol: closeLoc.endCol,
|
|
137
|
+
nodeName: 'MustacheTag',
|
|
118
138
|
type: 'psblock',
|
|
119
139
|
parentNode,
|
|
120
140
|
prevNode,
|
|
@@ -123,53 +143,32 @@ function nodeize(originNode, prevNode, parentNode, scopeNS, rawHtml, offset = 0,
|
|
|
123
143
|
isGhost: false,
|
|
124
144
|
};
|
|
125
145
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
const prevBlockEndOffset = prevBlock ? prevBlock.endOffset : originNode.start;
|
|
146
|
-
const loc = (0, parser_utils_1.sliceFragment)(rawHtml, prevBlockEndOffset + i, prevBlockEndOffset + i + chunk.length);
|
|
147
|
-
blocks.push({
|
|
148
|
-
uuid: (0, parser_utils_1.uuid)(),
|
|
149
|
-
raw: chunk,
|
|
150
|
-
startOffset: loc.startOffset,
|
|
151
|
-
endOffset: loc.endOffset,
|
|
152
|
-
startLine: loc.startLine,
|
|
153
|
-
endLine: loc.endLine,
|
|
154
|
-
startCol: loc.startCol,
|
|
155
|
-
endCol: loc.endCol,
|
|
156
|
-
nodeName: originNode.type,
|
|
157
|
-
type: 'psblock',
|
|
158
|
-
parentNode,
|
|
159
|
-
prevNode,
|
|
160
|
-
nextNode,
|
|
161
|
-
isFragment: false,
|
|
162
|
-
isGhost: false,
|
|
163
|
-
});
|
|
164
|
-
stub = stub.slice(i + chunk.length);
|
|
146
|
+
const node = {
|
|
147
|
+
uuid: (0, parser_utils_1.uuid)(),
|
|
148
|
+
raw: _raw,
|
|
149
|
+
startOffset,
|
|
150
|
+
endOffset: _endOffset,
|
|
151
|
+
startLine: _startLine,
|
|
152
|
+
endLine: _endLine,
|
|
153
|
+
startCol: _startCol,
|
|
154
|
+
endCol: _endCol,
|
|
155
|
+
nodeName: 'MustacheTag',
|
|
156
|
+
type: 'psblock',
|
|
157
|
+
parentNode,
|
|
158
|
+
prevNode,
|
|
159
|
+
nextNode,
|
|
160
|
+
isFragment: false,
|
|
161
|
+
isGhost: false,
|
|
162
|
+
};
|
|
163
|
+
if (originNode.children.length > 0) {
|
|
164
|
+
node.childNodes = traverse(originNode, parentNode, scopeNS, rawHtml, offset, options, true);
|
|
165
165
|
}
|
|
166
|
-
if (
|
|
167
|
-
|
|
168
|
-
blocks[0].childNodes = childNodes;
|
|
166
|
+
if (closeExpression) {
|
|
167
|
+
return [node, closeExpression];
|
|
169
168
|
}
|
|
170
|
-
return
|
|
169
|
+
return node;
|
|
171
170
|
}
|
|
172
|
-
case '
|
|
171
|
+
case 'comment': {
|
|
173
172
|
return {
|
|
174
173
|
uuid: (0, parser_utils_1.uuid)(),
|
|
175
174
|
raw,
|
|
@@ -188,9 +187,11 @@ function nodeize(originNode, prevNode, parentNode, scopeNS, rawHtml, offset = 0,
|
|
|
188
187
|
isGhost: false,
|
|
189
188
|
};
|
|
190
189
|
}
|
|
191
|
-
case '
|
|
192
|
-
case '
|
|
193
|
-
|
|
190
|
+
case 'component':
|
|
191
|
+
case 'custom-element':
|
|
192
|
+
case 'fragment':
|
|
193
|
+
case 'element': {
|
|
194
|
+
if (((_j = originNode.name) === null || _j === void 0 ? void 0 : _j.toLowerCase()) === '!doctype') {
|
|
194
195
|
return {
|
|
195
196
|
uuid: (0, parser_utils_1.uuid)(),
|
|
196
197
|
raw,
|
|
@@ -212,46 +213,74 @@ function nodeize(originNode, prevNode, parentNode, scopeNS, rawHtml, offset = 0,
|
|
|
212
213
|
isGhost: false,
|
|
213
214
|
};
|
|
214
215
|
}
|
|
215
|
-
return parseElement(originNode
|
|
216
|
-
}
|
|
217
|
-
case 'Fragment': {
|
|
218
|
-
return originNode.children ? traverse(originNode, parentNode, scopeNS, rawHtml, offset) : null;
|
|
216
|
+
return parseElement(originNode, scopeNS, rawHtml, startLine, startCol, startOffset, parentNode, prevNode, nextNode, offset, options);
|
|
219
217
|
}
|
|
220
218
|
default: {
|
|
221
219
|
return null;
|
|
222
220
|
}
|
|
223
221
|
}
|
|
224
222
|
}
|
|
225
|
-
function parseElement(
|
|
226
|
-
|
|
223
|
+
function parseElement(
|
|
224
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
225
|
+
originNode, scopeNS, rawHtml, startLine, startCol, startOffset,
|
|
226
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
227
|
+
parentNode,
|
|
228
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
229
|
+
prevNode,
|
|
230
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
231
|
+
nextNode, offset, options) {
|
|
232
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
233
|
+
if (!originNode.position) {
|
|
234
|
+
throw new TypeError("Node doesn't have position");
|
|
235
|
+
}
|
|
236
|
+
let startTagRaw;
|
|
227
237
|
let childrenStart;
|
|
228
238
|
let childrenEnd;
|
|
229
|
-
if (originNode.children
|
|
230
|
-
childrenStart = originNode.children[0].start + offset;
|
|
231
|
-
childrenEnd = originNode.children[originNode.children.length - 1].end + offset;
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
childrenEnd = originNode.content.end + offset;
|
|
236
|
-
}
|
|
237
|
-
else if (/\/>$/.test(raw)) {
|
|
238
|
-
childrenStart = originNode.end + offset;
|
|
239
|
-
childrenEnd = originNode.end + offset;
|
|
239
|
+
if (originNode.children[0]) {
|
|
240
|
+
childrenStart = ((_c = (_b = (_a = originNode.children[0].position) === null || _a === void 0 ? void 0 : _a.start) === null || _b === void 0 ? void 0 : _b.offset) !== null && _c !== void 0 ? _c : 0) + offset;
|
|
241
|
+
childrenEnd = ((_g = (_f = (_e = (_d = originNode.children[originNode.children.length - 1]) === null || _d === void 0 ? void 0 : _d.position) === null || _e === void 0 ? void 0 : _e.end) === null || _f === void 0 ? void 0 : _f.offset) !== null && _g !== void 0 ? _g : 0) + offset;
|
|
242
|
+
const startTagStartOffset = originNode.position.start.offset + offset;
|
|
243
|
+
const startTagEndOffset = childrenStart;
|
|
244
|
+
startTagRaw = rawHtml.slice(startTagStartOffset, startTagEndOffset);
|
|
240
245
|
}
|
|
241
246
|
else {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
247
|
+
childrenStart = offset + ((_k = (_j = (_h = originNode.position.end) === null || _h === void 0 ? void 0 : _h.offset) !== null && _j !== void 0 ? _j : nextNode === null || nextNode === void 0 ? void 0 : nextNode.endOffset) !== null && _k !== void 0 ? _k : rawHtml.length - offset);
|
|
248
|
+
childrenEnd = childrenStart;
|
|
249
|
+
const startTagStartOffset = originNode.position.start.offset + offset;
|
|
250
|
+
let startTagEndOffset = childrenStart;
|
|
251
|
+
startTagRaw = rawHtml.slice(startTagStartOffset, startTagEndOffset);
|
|
252
|
+
const expectedCloseTag = `</${originNode.name}>`;
|
|
253
|
+
if (startTagRaw.includes(expectedCloseTag)) {
|
|
254
|
+
childrenStart -= expectedCloseTag.length;
|
|
255
|
+
childrenEnd = childrenStart;
|
|
256
|
+
startTagRaw = startTagRaw.replace(expectedCloseTag, '');
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
let startTagRawMasked = startTagRaw;
|
|
260
|
+
for (const attr of originNode.attributes) {
|
|
261
|
+
startTagRawMasked = startTagRawMasked.replace(attr.value, ' '.repeat(attr.value.length));
|
|
262
|
+
}
|
|
263
|
+
const closeChars = '>';
|
|
264
|
+
const closeOffset = startTagRawMasked.indexOf(closeChars) + closeChars.length;
|
|
265
|
+
startTagEndOffset = startTagStartOffset + closeOffset;
|
|
266
|
+
startTagRaw = rawHtml.slice(startTagStartOffset, startTagEndOffset);
|
|
267
|
+
}
|
|
268
|
+
// console.log({
|
|
269
|
+
// originNode,
|
|
270
|
+
// attrs: originNode.attributes,
|
|
271
|
+
// startTagRaw,
|
|
272
|
+
// startTagStartOffset,
|
|
273
|
+
// startTagEndOffset,
|
|
274
|
+
// expectedCloseTag,
|
|
275
|
+
// childrenStart,
|
|
276
|
+
// childrenEnd,
|
|
277
|
+
// });
|
|
246
278
|
}
|
|
247
|
-
const startTagStartOffset = originNode.start + offset;
|
|
248
|
-
const startTagEndOffset = childrenStart;
|
|
249
|
-
const startTagRaw = rawHtml.slice(startTagStartOffset, startTagEndOffset);
|
|
250
279
|
const tagTokens = (0, html_parser_1.parseRawTag)(startTagRaw, startLine, startCol, startOffset);
|
|
251
280
|
const tagName = tagTokens.tagName;
|
|
252
281
|
let endTag = null;
|
|
253
|
-
if (childrenEnd < originNode.end + offset) {
|
|
254
|
-
const endTagLoc = (0, parser_utils_1.sliceFragment)(rawHtml, childrenEnd, originNode.end + offset);
|
|
282
|
+
if (childrenEnd < ((_m = (_l = originNode.position.end) === null || _l === void 0 ? void 0 : _l.offset) !== null && _m !== void 0 ? _m : 0) + offset) {
|
|
283
|
+
const endTagLoc = (0, parser_utils_1.sliceFragment)(rawHtml, childrenEnd, ((_p = (_o = originNode.position.end) === null || _o === void 0 ? void 0 : _o.offset) !== null && _p !== void 0 ? _p : 0) + offset);
|
|
255
284
|
const endTagTokens = (0, html_parser_1.parseRawTag)(endTagLoc.raw, endTagLoc.startLine, endTagLoc.startCol, endTagLoc.startOffset);
|
|
256
285
|
const endTagName = endTagTokens.tagName;
|
|
257
286
|
endTag = {
|
|
@@ -290,7 +319,12 @@ function parseElement(nodeName, originNode, scopeNS, rawHtml, startLine, startCo
|
|
|
290
319
|
type: 'starttag',
|
|
291
320
|
namespace: scopeNS,
|
|
292
321
|
elementType: (0, parser_utils_1.detectElementType)(tagName, options === null || options === void 0 ? void 0 : options.authoredElementName, /^[A-Z]|\./),
|
|
293
|
-
attributes: originNode.attributes.map((
|
|
322
|
+
attributes: originNode.attributes.map((
|
|
323
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
324
|
+
attr, i) => {
|
|
325
|
+
var _a;
|
|
326
|
+
return (0, attr_tokenizer_1.attrTokenizer)(attr, (_a = originNode.attributes[i + 1]) !== null && _a !== void 0 ? _a : null, rawHtml, startTagRaw, startOffset + startTagRaw.length);
|
|
327
|
+
}),
|
|
294
328
|
hasSpreadAttr: false,
|
|
295
329
|
parentNode,
|
|
296
330
|
prevNode,
|
|
@@ -306,15 +340,8 @@ function parseElement(nodeName, originNode, scopeNS, rawHtml, startLine, startCo
|
|
|
306
340
|
if (endTag) {
|
|
307
341
|
endTag.pearNode = startTag;
|
|
308
342
|
}
|
|
309
|
-
startTag.childNodes =
|
|
343
|
+
startTag.childNodes = ['style', 'script'].includes(tagName)
|
|
344
|
+
? undefined
|
|
345
|
+
: traverse(originNode, startTag, scopeNS, rawHtml, offset, options);
|
|
310
346
|
return startTag;
|
|
311
347
|
}
|
|
312
|
-
function parseStyle(nodes, scopeNS, rawHtml, offset, options) {
|
|
313
|
-
const result = [];
|
|
314
|
-
for (const node of nodes) {
|
|
315
|
-
const { startLine, startCol, startOffset } = (0, parser_utils_1.sliceFragment)(rawHtml, node.start, node.end);
|
|
316
|
-
const styleEl = parseElement('style', node, scopeNS, rawHtml, startLine, startCol, startOffset, null, null, null, offset, options);
|
|
317
|
-
result.push(styleEl);
|
|
318
|
-
}
|
|
319
|
-
return result;
|
|
320
|
-
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markuplint/astro-parser",
|
|
3
|
-
"version": "3.0.0-
|
|
3
|
+
"version": "3.0.0-dev.176+f6ad62e9",
|
|
4
4
|
"description": "astro parser for markuplint",
|
|
5
5
|
"repository": "git@github.com:markuplint/markuplint.git",
|
|
6
6
|
"author": "Yusuke Hirao <yusukehirao@me.com>",
|
|
@@ -16,11 +16,12 @@
|
|
|
16
16
|
"clean": "tsc --build --clean"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@astrojs/parser": "0.
|
|
20
|
-
"@markuplint/html-parser": "3.0.0-
|
|
21
|
-
"@markuplint/ml-ast": "3.0.0-
|
|
22
|
-
"@markuplint/parser-utils": "3.0.0-
|
|
23
|
-
"
|
|
19
|
+
"@astrojs/parser": "0.22.2",
|
|
20
|
+
"@markuplint/html-parser": "3.0.0-dev.176+f6ad62e9",
|
|
21
|
+
"@markuplint/ml-ast": "3.0.0-dev.176+f6ad62e9",
|
|
22
|
+
"@markuplint/parser-utils": "3.0.0-dev.176+f6ad62e9",
|
|
23
|
+
"astro-eslint-parser": "^0.13.2",
|
|
24
|
+
"tslib": "^2.4.1"
|
|
24
25
|
},
|
|
25
|
-
"gitHead": "
|
|
26
|
+
"gitHead": "f6ad62e992e1569be4067f1e90d2d6017a658f57"
|
|
26
27
|
}
|