@markuplint/parser-utils 3.13.0 → 4.0.0-alpha.10
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/LICENSE +1 -1
- package/lib/attr-tokenizer.d.ts +18 -0
- package/lib/attr-tokenizer.js +169 -0
- package/lib/const.d.ts +9 -2
- package/lib/const.js +12 -9
- package/lib/debugger.d.ts +3 -2
- package/lib/debugger.js +38 -39
- package/lib/decision.js +6 -11
- package/lib/detect-element-type.d.ts +1 -5
- package/lib/detect-element-type.js +4 -8
- package/lib/enums.d.ts +16 -0
- package/lib/enums.js +18 -0
- package/lib/get-location.d.ts +4 -17
- package/lib/get-location.js +11 -31
- package/lib/idl-attributes.d.ts +2 -2
- package/lib/idl-attributes.js +5 -10
- package/lib/ignore-block.d.ts +4 -3
- package/lib/ignore-block.js +75 -131
- package/lib/ignore-front-matter.d.ts +4 -1
- package/lib/ignore-front-matter.js +15 -10
- package/lib/index.d.ts +7 -16
- package/lib/index.js +7 -19
- package/lib/parser-error.d.ts +19 -24
- package/lib/parser-error.js +8 -15
- package/lib/parser.d.ts +108 -0
- package/lib/parser.js +1076 -0
- package/lib/script-parser.d.ts +6 -0
- package/lib/script-parser.js +22 -0
- package/lib/sort-nodes.d.ts +2 -0
- package/lib/sort-nodes.js +18 -0
- package/lib/types.d.ts +50 -12
- package/lib/types.js +1 -2
- package/package.json +17 -8
- package/lib/create-token.d.ts +0 -9
- package/lib/create-token.js +0 -35
- package/lib/flatten-nodes.d.ts +0 -2
- package/lib/flatten-nodes.js +0 -251
- package/lib/get-space-before.d.ts +0 -1
- package/lib/get-space-before.js +0 -13
- package/lib/idl-attributes.test.d.ts +0 -1
- package/lib/idl-attributes.test.js +0 -45
- package/lib/parse-attr.d.ts +0 -27
- package/lib/parse-attr.js +0 -150
- package/lib/remove-deprecated-node.d.ts +0 -7
- package/lib/remove-deprecated-node.js +0 -43
- package/lib/siblings-correction.d.ts +0 -9
- package/lib/siblings-correction.js +0 -26
- package/lib/tag-splitter.d.ts +0 -7
- package/lib/tag-splitter.js +0 -92
- package/lib/walker.d.ts +0 -2
- package/lib/walker.js +0 -22
- package/test/create-token.spec.js +0 -17
- package/test/flatten-nodes.spec.js +0 -31
- package/test/get-location.spec.js +0 -38
- package/test/ignore-block.spec.js +0 -274
- package/test/ignore-front-matter.spec.js +0 -20
- package/test/parse-attr.spec.js +0 -68
package/LICENSE
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { QuoteSet } from './types.js';
|
|
2
|
+
import { AttrState } from './enums.js';
|
|
3
|
+
/**
|
|
4
|
+
* @see https://html.spec.whatwg.org/multipage/parsing.html#tag-name-state
|
|
5
|
+
* @see https://html.spec.whatwg.org/multipage/parsing.html#before-attribute-name-state
|
|
6
|
+
* @see https://html.spec.whatwg.org/multipage/parsing.html#attribute-name-state
|
|
7
|
+
*/
|
|
8
|
+
export declare function attrTokenizer(raw: string, quoteSet?: readonly QuoteSet[], startState?: AttrState, quoteInValueChars?: ReadonlyArray<QuoteSet>, endOfUnquotedValueChars?: ReadonlyArray<string>): {
|
|
9
|
+
spacesBeforeAttrName: string;
|
|
10
|
+
attrName: string;
|
|
11
|
+
spacesBeforeEqual: string;
|
|
12
|
+
equal: string;
|
|
13
|
+
spacesAfterEqual: string;
|
|
14
|
+
quoteStart: string;
|
|
15
|
+
attrValue: string;
|
|
16
|
+
quoteEnd: string;
|
|
17
|
+
leftover: string;
|
|
18
|
+
};
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { defaultSpaces } from './const.js';
|
|
2
|
+
import { AttrState } from './enums.js';
|
|
3
|
+
const defaultQuoteSet = [
|
|
4
|
+
{ start: '"', end: '"' },
|
|
5
|
+
{ start: "'", end: "'" },
|
|
6
|
+
];
|
|
7
|
+
const defaultQuoteInValueChars = [];
|
|
8
|
+
const spaces = defaultSpaces;
|
|
9
|
+
const EQUAL = '=';
|
|
10
|
+
/**
|
|
11
|
+
* @see https://html.spec.whatwg.org/multipage/parsing.html#tag-name-state
|
|
12
|
+
* @see https://html.spec.whatwg.org/multipage/parsing.html#before-attribute-name-state
|
|
13
|
+
* @see https://html.spec.whatwg.org/multipage/parsing.html#attribute-name-state
|
|
14
|
+
*/
|
|
15
|
+
export function attrTokenizer(raw, quoteSet = defaultQuoteSet, startState = AttrState.BeforeName, quoteInValueChars = defaultQuoteInValueChars, endOfUnquotedValueChars = [...defaultSpaces, '/', '>']) {
|
|
16
|
+
let state = startState;
|
|
17
|
+
let spacesBeforeAttrName = '';
|
|
18
|
+
let attrName = '';
|
|
19
|
+
let spacesBeforeEqual = '';
|
|
20
|
+
let equal = '';
|
|
21
|
+
let spacesAfterEqual = '';
|
|
22
|
+
let quoteTypeIndex = -1;
|
|
23
|
+
let quoteStart = '';
|
|
24
|
+
let attrValue = '';
|
|
25
|
+
let quoteEnd = '';
|
|
26
|
+
const isBeforeValueStarted = startState === AttrState.BeforeValue;
|
|
27
|
+
const quoteModeStack = [];
|
|
28
|
+
const chars = [...raw];
|
|
29
|
+
while (chars.length > 0) {
|
|
30
|
+
if (state === AttrState.AfterValue) {
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
const char = chars.shift();
|
|
34
|
+
switch (state) {
|
|
35
|
+
case AttrState.BeforeName: {
|
|
36
|
+
if (char === '>') {
|
|
37
|
+
chars.unshift(char);
|
|
38
|
+
state = AttrState.AfterValue;
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
if (char === '/') {
|
|
42
|
+
chars.unshift(char);
|
|
43
|
+
state = AttrState.AfterValue;
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
if (spaces.includes(char)) {
|
|
47
|
+
spacesBeforeAttrName += char;
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
attrName += char;
|
|
51
|
+
state = AttrState.Name;
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
case AttrState.Name: {
|
|
55
|
+
if (char === '>') {
|
|
56
|
+
chars.unshift(char);
|
|
57
|
+
state = AttrState.AfterValue;
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
if (char === '/') {
|
|
61
|
+
chars.unshift(char);
|
|
62
|
+
state = AttrState.AfterValue;
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
if (spaces.includes(char)) {
|
|
66
|
+
spacesBeforeEqual += char;
|
|
67
|
+
state = AttrState.Equal;
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
if (char === EQUAL) {
|
|
71
|
+
equal += char;
|
|
72
|
+
state = AttrState.BeforeValue;
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
attrName += char;
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
case AttrState.Equal: {
|
|
79
|
+
if (spaces.includes(char)) {
|
|
80
|
+
spacesBeforeEqual += char;
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
if (char === EQUAL) {
|
|
84
|
+
equal += char;
|
|
85
|
+
state = AttrState.BeforeValue;
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
// End of attribute
|
|
89
|
+
chars.unshift(spacesBeforeEqual, char);
|
|
90
|
+
spacesBeforeEqual = '';
|
|
91
|
+
state = AttrState.AfterValue;
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
case AttrState.BeforeValue: {
|
|
95
|
+
if (endOfUnquotedValueChars.includes(char) && spaces.includes(char)) {
|
|
96
|
+
if (isBeforeValueStarted) {
|
|
97
|
+
spacesBeforeAttrName += char;
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
spacesAfterEqual += char;
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
quoteTypeIndex = quoteSet.findIndex(quote => quote.start === char);
|
|
104
|
+
const quote = quoteSet[quoteTypeIndex];
|
|
105
|
+
if (quote) {
|
|
106
|
+
quoteStart = quote.start;
|
|
107
|
+
state = AttrState.Value;
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
const raw = char + chars.join('');
|
|
111
|
+
const inQuote = quoteInValueChars.find(quote => raw.startsWith(quote.start));
|
|
112
|
+
if (inQuote) {
|
|
113
|
+
quoteModeStack.push(inQuote);
|
|
114
|
+
attrValue += inQuote.start;
|
|
115
|
+
chars.splice(0, inQuote.start.length - 1);
|
|
116
|
+
state = AttrState.Value;
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
chars.unshift(char);
|
|
120
|
+
state = AttrState.Value;
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
case AttrState.Value: {
|
|
124
|
+
if (!quoteSet[quoteTypeIndex] && endOfUnquotedValueChars.includes(char)) {
|
|
125
|
+
chars.unshift(char);
|
|
126
|
+
state = AttrState.AfterValue;
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
if (quoteModeStack.length === 0 && char === quoteSet[quoteTypeIndex]?.end) {
|
|
130
|
+
quoteEnd = char;
|
|
131
|
+
state = AttrState.AfterValue;
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
const raw = char + chars.join('');
|
|
135
|
+
const inQuoteEnd = quoteModeStack.at(-1);
|
|
136
|
+
if (inQuoteEnd && raw.startsWith(inQuoteEnd.end)) {
|
|
137
|
+
quoteModeStack.pop();
|
|
138
|
+
attrValue += inQuoteEnd.end;
|
|
139
|
+
chars.splice(0, inQuoteEnd.end.length - 1);
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
const inQuoteStart = quoteInValueChars.find(quote => raw.startsWith(quote.start));
|
|
143
|
+
if (inQuoteStart) {
|
|
144
|
+
quoteModeStack.push(inQuoteStart);
|
|
145
|
+
attrValue += inQuoteStart.start;
|
|
146
|
+
chars.splice(0, inQuoteStart.start.length - 1);
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
attrValue += char;
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (state === AttrState.Value && quoteTypeIndex !== -1) {
|
|
155
|
+
throw new SyntaxError(`Unclosed attribute value: ${raw}`);
|
|
156
|
+
}
|
|
157
|
+
const leftover = chars.join('');
|
|
158
|
+
return {
|
|
159
|
+
spacesBeforeAttrName,
|
|
160
|
+
attrName,
|
|
161
|
+
spacesBeforeEqual,
|
|
162
|
+
equal,
|
|
163
|
+
spacesAfterEqual,
|
|
164
|
+
quoteStart,
|
|
165
|
+
attrValue,
|
|
166
|
+
quoteEnd,
|
|
167
|
+
leftover,
|
|
168
|
+
};
|
|
169
|
+
}
|
package/lib/const.d.ts
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
|
-
export declare const MASK_CHAR =
|
|
1
|
+
export declare const MASK_CHAR = "\uE000";
|
|
2
2
|
/**
|
|
3
3
|
* SVG Element list
|
|
4
4
|
*
|
|
5
5
|
* @see https://developer.mozilla.org/en-US/docs/Web/SVG/Element
|
|
6
6
|
*/
|
|
7
7
|
export declare const svgElementList: string[];
|
|
8
|
-
export declare const reTag: RegExp;
|
|
9
8
|
export declare const reTagName: RegExp;
|
|
10
9
|
export declare const reSplitterTag: RegExp;
|
|
10
|
+
/**
|
|
11
|
+
* - U+0009 CHARACTER TABULATION (tab) => `\t`
|
|
12
|
+
* - U+000A LINE FEED (LF) => `\n`
|
|
13
|
+
* - U+000C FORM FEED (FF) => `\f`
|
|
14
|
+
* - U+000D CARRIAGE RETURN (CR) => `\r`
|
|
15
|
+
* - U+0020 SPACE => ` `
|
|
16
|
+
*/
|
|
17
|
+
export declare const defaultSpaces: readonly ["\t", "\n", "\f", "\r", " "];
|
package/lib/const.js
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.reSplitterTag = exports.reTagName = exports.reTag = exports.svgElementList = exports.MASK_CHAR = void 0;
|
|
4
|
-
exports.MASK_CHAR = '\uE000';
|
|
1
|
+
export const MASK_CHAR = '\uE000';
|
|
5
2
|
/**
|
|
6
3
|
* SVG Element list
|
|
7
4
|
*
|
|
8
5
|
* @see https://developer.mozilla.org/en-US/docs/Web/SVG/Element
|
|
9
6
|
*/
|
|
10
|
-
|
|
7
|
+
export const svgElementList = [
|
|
11
8
|
'a',
|
|
12
9
|
'animate',
|
|
13
10
|
'animateMotion',
|
|
@@ -97,7 +94,13 @@ exports.svgElementList = [
|
|
|
97
94
|
'tref',
|
|
98
95
|
'vkern',
|
|
99
96
|
];
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
97
|
+
export const reTagName = /^[a-z][^\0\t\n\f />]*/i;
|
|
98
|
+
export const reSplitterTag = /<[^>]+>/g;
|
|
99
|
+
/**
|
|
100
|
+
* - U+0009 CHARACTER TABULATION (tab) => `\t`
|
|
101
|
+
* - U+000A LINE FEED (LF) => `\n`
|
|
102
|
+
* - U+000C FORM FEED (FF) => `\f`
|
|
103
|
+
* - U+000D CARRIAGE RETURN (CR) => `\r`
|
|
104
|
+
* - U+0020 SPACE => ` `
|
|
105
|
+
*/
|
|
106
|
+
export const defaultSpaces = ['\t', '\n', '\f', '\r', ' '];
|
package/lib/debugger.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import type { MLASTAttr, MLASTNode } from '@markuplint/ml-ast';
|
|
2
|
-
export declare function nodeListToDebugMaps(nodeList: MLASTNode[], withAttr?: boolean): string[];
|
|
3
|
-
export declare function attributesToDebugMaps(attributes: MLASTAttr[]): string[][];
|
|
2
|
+
export declare function nodeListToDebugMaps(nodeList: readonly (MLASTNode | null)[], withAttr?: boolean): string[];
|
|
3
|
+
export declare function attributesToDebugMaps(attributes: readonly MLASTAttr[]): string[][];
|
|
4
|
+
export declare function nodeTreeDebugView(nodeTree: readonly MLASTNode[]): (string | undefined)[];
|
package/lib/debugger.js
CHANGED
|
@@ -1,64 +1,63 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.attributesToDebugMaps = exports.nodeListToDebugMaps = void 0;
|
|
4
|
-
function nodeListToDebugMaps(
|
|
5
|
-
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
6
|
-
nodeList, withAttr = false) {
|
|
7
|
-
return nodeList
|
|
8
|
-
.map(n => {
|
|
1
|
+
export function nodeListToDebugMaps(nodeList, withAttr = false) {
|
|
2
|
+
return nodeList.flatMap(n => {
|
|
9
3
|
const r = [];
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
r.push(...attributesToDebugMaps(n.attributes).flat());
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
else {
|
|
17
|
-
r.push(`[N/A]>[N/A](N/A)${n.nodeName}: ${visibleWhiteSpace(n.raw)}`);
|
|
4
|
+
r.push(tokenDebug(n));
|
|
5
|
+
if (withAttr && n && n.type === 'starttag') {
|
|
6
|
+
r.push(...attributesToDebugMaps(n.attributes).flat());
|
|
18
7
|
}
|
|
19
8
|
return r;
|
|
20
|
-
})
|
|
21
|
-
.flat();
|
|
9
|
+
});
|
|
22
10
|
}
|
|
23
|
-
|
|
24
|
-
function attributesToDebugMaps(
|
|
25
|
-
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
26
|
-
attributes) {
|
|
11
|
+
export function attributesToDebugMaps(attributes) {
|
|
27
12
|
return attributes.map(n => {
|
|
28
13
|
const r = [
|
|
29
14
|
tokenDebug({
|
|
30
15
|
...n,
|
|
31
|
-
name: n.type === '
|
|
16
|
+
name: n.type === 'attr' ? n.name.raw : n.raw,
|
|
32
17
|
}),
|
|
33
18
|
];
|
|
34
|
-
if (n.type === '
|
|
35
|
-
r.push(` ${
|
|
36
|
-
r
|
|
37
|
-
r.push(` ${tokenDebug(n.spacesBeforeEqual, 'bE')}`);
|
|
38
|
-
r.push(` ${tokenDebug(n.equal, 'equal')}`);
|
|
39
|
-
r.push(` ${tokenDebug(n.spacesAfterEqual, 'aE')}`);
|
|
40
|
-
r.push(` ${tokenDebug(n.startQuote, 'sQ')}`);
|
|
41
|
-
r.push(` ${tokenDebug(n.value, 'value')}`);
|
|
42
|
-
r.push(` ${tokenDebug(n.endQuote, 'eQ')}`);
|
|
43
|
-
r.push(` isDirective: ${!!n.isDirective}`);
|
|
44
|
-
r.push(` isDynamicValue: ${!!n.isDynamicValue}`);
|
|
19
|
+
if (n.type === 'spread') {
|
|
20
|
+
r.push(` #spread: ${visibleWhiteSpace(n.raw)}`);
|
|
21
|
+
return r;
|
|
45
22
|
}
|
|
23
|
+
r.push(` ${tokenDebug(n.spacesBeforeName, 'bN')}`, ` ${tokenDebug(n.name, 'name')}`, ` ${tokenDebug(n.spacesBeforeEqual, 'bE')}`, ` ${tokenDebug(n.equal, 'equal')}`, ` ${tokenDebug(n.spacesAfterEqual, 'aE')}`, ` ${tokenDebug(n.startQuote, 'sQ')}`, ` ${tokenDebug(n.value, 'value')}`, ` ${tokenDebug(n.endQuote, 'eQ')}`, ` isDirective: ${!!n.isDirective}`, ` isDynamicValue: ${!!n.isDynamicValue}`);
|
|
46
24
|
if (n.potentialName != null) {
|
|
47
25
|
r.push(` potentialName: ${visibleWhiteSpace(n.potentialName)}`);
|
|
48
26
|
}
|
|
49
|
-
if (n.
|
|
27
|
+
if (n.candidate) {
|
|
50
28
|
r.push(` candidate: ${visibleWhiteSpace(n.candidate)}`);
|
|
51
29
|
}
|
|
52
30
|
return r;
|
|
53
31
|
});
|
|
54
32
|
}
|
|
55
|
-
|
|
33
|
+
export function nodeTreeDebugView(nodeTree) {
|
|
34
|
+
return nodeTree
|
|
35
|
+
.map((n, i) => {
|
|
36
|
+
const lines = [];
|
|
37
|
+
if (n.type === 'attr' || n.type === 'spread') {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
lines.push(`${i.toString().padStart(3, '0')}: [${n.uuid.slice(0, 8)}] ${' '.repeat(Math.max(n.depth, 0))}${n.type === 'endtag' ? '/' : ''}${n.nodeName}(${n.uuid.slice(0, 8)})${n.type === 'starttag' && n.isGhost ? '[👻]' : ''}${n.type === 'starttag'
|
|
41
|
+
? ` => ${n.pairNode ? `/${n.pairNode.nodeName}(${n.pairNode.uuid.slice(0, 8)})` : '💀'}`
|
|
42
|
+
: ''}`);
|
|
43
|
+
if (n.type === 'starttag' || n.type === 'psblock') {
|
|
44
|
+
for (const c of n.childNodes ?? []) {
|
|
45
|
+
lines.push(`${' '.repeat(15)} ${' '.repeat(Math.max(n.depth, 0))}┗━ ${c.type === 'endtag' ? '/' : ''}${c.nodeName}(${c.uuid.slice(0, 8)})`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return lines;
|
|
49
|
+
})
|
|
50
|
+
.filter(Boolean)
|
|
51
|
+
.flat();
|
|
52
|
+
}
|
|
56
53
|
function tokenDebug(n, type = '') {
|
|
57
|
-
|
|
54
|
+
if (!n) {
|
|
55
|
+
return 'NULL';
|
|
56
|
+
}
|
|
58
57
|
return `[${n.startLine}:${n.startCol}]>[${n.endLine}:${n.endCol}](${n.startOffset},${n.endOffset})${
|
|
59
58
|
// @ts-ignore
|
|
60
|
-
|
|
59
|
+
n.potentialName ?? n.nodeName ?? n.name ?? n.type ?? type}${'isGhost' in n && n.isGhost ? '(👻)' : ''}${'isBogus' in n && n.isBogus ? '(👿)' : ''}: ${visibleWhiteSpace(n.raw)}`;
|
|
61
60
|
}
|
|
62
61
|
function visibleWhiteSpace(chars) {
|
|
63
|
-
return chars.
|
|
62
|
+
return chars.replaceAll('\n', '⏎').replaceAll('\t', '→').replaceAll(/\s/g, '␣');
|
|
64
63
|
}
|
package/lib/decision.js
CHANGED
|
@@ -1,20 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.isPotentialCustomElementName = exports.isSVGElement = void 0;
|
|
4
|
-
const types_1 = require("@markuplint/types");
|
|
5
|
-
const const_1 = require("./const");
|
|
1
|
+
import { isCustomElementName } from '@markuplint/types';
|
|
2
|
+
import { svgElementList } from './const.js';
|
|
6
3
|
/**
|
|
7
4
|
*
|
|
8
5
|
*
|
|
9
6
|
* @param nodeName
|
|
10
7
|
* @returns
|
|
11
8
|
*/
|
|
12
|
-
function isSVGElement(nodeName) {
|
|
13
|
-
return
|
|
9
|
+
export function isSVGElement(nodeName) {
|
|
10
|
+
return svgElementList.includes(nodeName);
|
|
14
11
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
function isPotentialCustomElementName(tagName) {
|
|
12
|
+
const isCEN = isCustomElementName();
|
|
13
|
+
export function isPotentialCustomElementName(tagName) {
|
|
18
14
|
return isCEN(tagName);
|
|
19
15
|
}
|
|
20
|
-
exports.isPotentialCustomElementName = isPotentialCustomElementName;
|
|
@@ -1,6 +1,2 @@
|
|
|
1
1
|
import type { ElementType, ParserAuthoredElementNameDistinguishing } from '@markuplint/ml-ast';
|
|
2
|
-
export declare function detectElementType(
|
|
3
|
-
name: string,
|
|
4
|
-
option?: ParserAuthoredElementNameDistinguishing,
|
|
5
|
-
defaultPattern?: ParserAuthoredElementNameDistinguishing,
|
|
6
|
-
): ElementType;
|
|
2
|
+
export declare function detectElementType(name: string, option?: ParserAuthoredElementNameDistinguishing, defaultPattern?: ParserAuthoredElementNameDistinguishing): ElementType;
|
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.detectElementType = void 0;
|
|
4
|
-
const decision_1 = require("./decision");
|
|
5
|
-
function detectElementType(name, option, defaultPattern) {
|
|
1
|
+
import { isPotentialCustomElementName } from './decision.js';
|
|
2
|
+
export function detectElementType(name, option, defaultPattern) {
|
|
6
3
|
if (distinguishAuthoredName(name, option, defaultPattern)) {
|
|
7
4
|
return 'authored';
|
|
8
5
|
}
|
|
9
|
-
return
|
|
6
|
+
return isPotentialCustomElementName(name) ? 'web-component' : 'html';
|
|
10
7
|
}
|
|
11
|
-
exports.detectElementType = detectElementType;
|
|
12
8
|
function distinguishAuthoredName(name, pattern, defaultPattern) {
|
|
13
9
|
if (pattern != null) {
|
|
14
10
|
return _distinguishAuthoredName(name, pattern);
|
|
@@ -29,7 +25,7 @@ function _distinguishAuthoredName(name, patterns) {
|
|
|
29
25
|
});
|
|
30
26
|
}
|
|
31
27
|
function toRegexp(pattern) {
|
|
32
|
-
const matched = pattern.match(/^\/(.+)\/([
|
|
28
|
+
const matched = pattern.match(/^\/(.+)\/([gi]*)$/i);
|
|
33
29
|
if (matched && matched[1]) {
|
|
34
30
|
return new RegExp(matched[1], matched[2]);
|
|
35
31
|
}
|
package/lib/enums.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare enum TagState {
|
|
2
|
+
BeforeOpenTag = 0,
|
|
3
|
+
FirstCharOfTagName = 1,
|
|
4
|
+
TagName = 2,
|
|
5
|
+
Attrs = 3,
|
|
6
|
+
AfterAttrs = 4,
|
|
7
|
+
AfterOpenTag = 5
|
|
8
|
+
}
|
|
9
|
+
export declare enum AttrState {
|
|
10
|
+
BeforeName = 0,
|
|
11
|
+
Name = 1,
|
|
12
|
+
Equal = 2,
|
|
13
|
+
BeforeValue = 3,
|
|
14
|
+
Value = 4,
|
|
15
|
+
AfterValue = 5
|
|
16
|
+
}
|
package/lib/enums.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export var TagState;
|
|
2
|
+
(function (TagState) {
|
|
3
|
+
TagState[TagState["BeforeOpenTag"] = 0] = "BeforeOpenTag";
|
|
4
|
+
TagState[TagState["FirstCharOfTagName"] = 1] = "FirstCharOfTagName";
|
|
5
|
+
TagState[TagState["TagName"] = 2] = "TagName";
|
|
6
|
+
TagState[TagState["Attrs"] = 3] = "Attrs";
|
|
7
|
+
TagState[TagState["AfterAttrs"] = 4] = "AfterAttrs";
|
|
8
|
+
TagState[TagState["AfterOpenTag"] = 5] = "AfterOpenTag";
|
|
9
|
+
})(TagState || (TagState = {}));
|
|
10
|
+
export var AttrState;
|
|
11
|
+
(function (AttrState) {
|
|
12
|
+
AttrState[AttrState["BeforeName"] = 0] = "BeforeName";
|
|
13
|
+
AttrState[AttrState["Name"] = 1] = "Name";
|
|
14
|
+
AttrState[AttrState["Equal"] = 2] = "Equal";
|
|
15
|
+
AttrState[AttrState["BeforeValue"] = 3] = "BeforeValue";
|
|
16
|
+
AttrState[AttrState["Value"] = 4] = "Value";
|
|
17
|
+
AttrState[AttrState["AfterValue"] = 5] = "AfterValue";
|
|
18
|
+
})(AttrState || (AttrState = {}));
|
package/lib/get-location.d.ts
CHANGED
|
@@ -1,17 +1,4 @@
|
|
|
1
|
-
export declare function getLine(
|
|
2
|
-
export declare function getCol(
|
|
3
|
-
export declare function getEndLine(
|
|
4
|
-
export declare function getEndCol(
|
|
5
|
-
export declare function sliceFragment(
|
|
6
|
-
rawHtml: string,
|
|
7
|
-
start: number,
|
|
8
|
-
end: number,
|
|
9
|
-
): {
|
|
10
|
-
startOffset: number;
|
|
11
|
-
endOffset: number;
|
|
12
|
-
startLine: number;
|
|
13
|
-
endLine: number;
|
|
14
|
-
startCol: number;
|
|
15
|
-
endCol: number;
|
|
16
|
-
raw: string;
|
|
17
|
-
};
|
|
1
|
+
export declare function getLine(rawCodeFragment: string, startOffset: number): number;
|
|
2
|
+
export declare function getCol(rawCodeFragment: string, startOffset: number): number;
|
|
3
|
+
export declare function getEndLine(rawCodeFragment: string, startLine: number): number;
|
|
4
|
+
export declare function getEndCol(rawCodeFragment: string, startCol: number): number;
|
package/lib/get-location.js
CHANGED
|
@@ -1,37 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
function getLine(html, startOffset) {
|
|
5
|
-
return html.slice(0, startOffset).split(/\n/g).length;
|
|
1
|
+
const LINE_BREAK = '\n';
|
|
2
|
+
export function getLine(rawCodeFragment, startOffset) {
|
|
3
|
+
return rawCodeFragment.slice(0, startOffset).split(LINE_BREAK).length;
|
|
6
4
|
}
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const lines = html.slice(0, startOffset).split(/\n/g);
|
|
11
|
-
return ((_a = lines[lines.length - 1]) !== null && _a !== void 0 ? _a : '').length + 1;
|
|
5
|
+
export function getCol(rawCodeFragment, startOffset) {
|
|
6
|
+
const lines = rawCodeFragment.slice(0, startOffset).split(LINE_BREAK);
|
|
7
|
+
return (lines.at(-1) ?? '').length + 1;
|
|
12
8
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
return html.split(/\r?\n/).length - 1 + line;
|
|
9
|
+
export function getEndLine(rawCodeFragment, startLine) {
|
|
10
|
+
return rawCodeFragment.split(LINE_BREAK).length - 1 + startLine;
|
|
16
11
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const lines = html.split(/\r?\n/);
|
|
12
|
+
export function getEndCol(rawCodeFragment, startCol) {
|
|
13
|
+
const lines = rawCodeFragment.split(LINE_BREAK);
|
|
20
14
|
const lineCount = lines.length;
|
|
21
15
|
const lastLine = lines.pop();
|
|
22
|
-
return lineCount > 1 ? lastLine.length + 1 :
|
|
16
|
+
return lineCount > 1 ? lastLine.length + 1 : startCol + rawCodeFragment.length;
|
|
23
17
|
}
|
|
24
|
-
exports.getEndCol = getEndCol;
|
|
25
|
-
function sliceFragment(rawHtml, start, end) {
|
|
26
|
-
const raw = rawHtml.slice(start, end);
|
|
27
|
-
return {
|
|
28
|
-
startOffset: start,
|
|
29
|
-
endOffset: end,
|
|
30
|
-
startLine: getLine(rawHtml, start),
|
|
31
|
-
endLine: getLine(rawHtml, end),
|
|
32
|
-
startCol: getCol(rawHtml, start),
|
|
33
|
-
endCol: getCol(rawHtml, end),
|
|
34
|
-
raw,
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
exports.sliceFragment = sliceFragment;
|
package/lib/idl-attributes.d.ts
CHANGED
package/lib/idl-attributes.js
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.searchIDLAttribute = void 0;
|
|
4
1
|
/**
|
|
5
2
|
* IDL attributes VS Content attributes
|
|
6
3
|
*
|
|
@@ -418,23 +415,21 @@ const idlContentMap = {
|
|
|
418
415
|
credentialless: 'credentialless',
|
|
419
416
|
};
|
|
420
417
|
const list = Object.entries(idlContentMap);
|
|
421
|
-
function searchIDLAttribute(name) {
|
|
422
|
-
var _a;
|
|
418
|
+
export function searchIDLAttribute(name) {
|
|
423
419
|
const camelizedName = camelize(name);
|
|
424
420
|
const [idlPropName, contentAttrName] = /^on[a-z]/.test(name)
|
|
425
421
|
? [name.toLowerCase(), name.toLowerCase()]
|
|
426
|
-
:
|
|
422
|
+
: list.find(([idlPropName, contentAttrName]) => idlPropName.toLowerCase() === camelizedName.toLowerCase() ||
|
|
427
423
|
contentAttrName.toLowerCase() === name.toLowerCase() ||
|
|
428
|
-
hyphenize(idlPropName) === name.toLowerCase())
|
|
424
|
+
hyphenize(idlPropName) === name.toLowerCase()) ?? [];
|
|
429
425
|
return {
|
|
430
426
|
idlPropName,
|
|
431
427
|
contentAttrName,
|
|
432
428
|
};
|
|
433
429
|
}
|
|
434
|
-
exports.searchIDLAttribute = searchIDLAttribute;
|
|
435
430
|
function camelize(str) {
|
|
436
|
-
return str.
|
|
431
|
+
return str.replaceAll(/[:-][a-z]/g, $0 => $0[1]?.toUpperCase() ?? '');
|
|
437
432
|
}
|
|
438
433
|
function hyphenize(str) {
|
|
439
|
-
return str.
|
|
434
|
+
return str.replaceAll(/[A-Z]/g, $0 => `-${$0.toLowerCase()}`);
|
|
440
435
|
}
|
package/lib/ignore-block.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { Parser } from './parser.js';
|
|
2
|
+
import type { IgnoreBlock, IgnoreTag } from './types.js';
|
|
3
|
+
import type { MLASTNodeTreeItem } from '@markuplint/ml-ast';
|
|
3
4
|
export declare function ignoreBlock(source: string, tags: readonly IgnoreTag[], maskChar?: string): IgnoreBlock;
|
|
4
|
-
export declare function restoreNode(nodeList:
|
|
5
|
+
export declare function restoreNode(parser: Parser<any, any>, nodeList: readonly MLASTNodeTreeItem[], ignoreBlock: IgnoreBlock, throwErrorWhenTagHasUnresolved?: boolean): MLASTNodeTreeItem[];
|