@markuplint/html-parser 3.4.0 → 3.6.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-tokenizer.js +8 -8
- package/lib/create-tree.js +18 -12
- package/lib/index.d.ts +4 -5
- package/lib/index.js +9 -11
- package/lib/optimize-starts-head-or-body.js +5 -1
- package/lib/parse-raw-tag.js +2 -3
- package/lib/parse.js +1 -2
- package/package.json +7 -4
- package/lib/const.d.ts +0 -3
- package/lib/const.js +0 -7
- package/lib/flatten-nodes.d.ts +0 -2
- package/lib/flatten-nodes.js +0 -238
- package/lib/remove-deprecated-node.d.ts +0 -7
- package/lib/remove-deprecated-node.js +0 -41
- package/lib/tag-splitter.d.ts +0 -7
- package/lib/tag-splitter.js +0 -92
package/lib/attr-tokenizer.js
CHANGED
|
@@ -5,7 +5,7 @@ const reAttrsInStartTag =
|
|
|
5
5
|
// eslint-disable-next-line no-control-regex
|
|
6
6
|
/(\s*)([^\x00-\x1f\x7f-\x9f "'>/=]+)(?:(\s*)(=)(\s*)(?:(?:"([^"]*)")|(?:'([^']*)')|([^\s]*)))?/;
|
|
7
7
|
function attrTokenizer(raw, line, col, startOffset) {
|
|
8
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
8
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
9
9
|
const attrMatchedMap = raw.match(reAttrsInStartTag);
|
|
10
10
|
if (!attrMatchedMap) {
|
|
11
11
|
throw new SyntaxError('Illegal attribute token');
|
|
@@ -13,10 +13,10 @@ function attrTokenizer(raw, line, col, startOffset) {
|
|
|
13
13
|
const spacesBeforeAttrString = (_a = attrMatchedMap[1]) !== null && _a !== void 0 ? _a : '';
|
|
14
14
|
const nameChars = (_b = attrMatchedMap[2]) !== null && _b !== void 0 ? _b : '';
|
|
15
15
|
const spacesBeforeEqualChars = (_c = attrMatchedMap[3]) !== null && _c !== void 0 ? _c : '';
|
|
16
|
-
const equalChars = attrMatchedMap[4]
|
|
17
|
-
const spacesAfterEqualChars = (
|
|
16
|
+
const equalChars = (_d = attrMatchedMap[4]) !== null && _d !== void 0 ? _d : null;
|
|
17
|
+
const spacesAfterEqualChars = (_e = attrMatchedMap[5]) !== null && _e !== void 0 ? _e : '';
|
|
18
18
|
const quoteChars = attrMatchedMap[6] != null ? '"' : attrMatchedMap[7] != null ? "'" : null;
|
|
19
|
-
const valueChars = (
|
|
19
|
+
const valueChars = (_h = (_g = (_f = attrMatchedMap[6]) !== null && _f !== void 0 ? _f : attrMatchedMap[7]) !== null && _g !== void 0 ? _g : attrMatchedMap[8]) !== null && _h !== void 0 ? _h : (quoteChars ? '' : null);
|
|
20
20
|
let offset = startOffset;
|
|
21
21
|
const spacesBeforeName = (0, parser_utils_1.tokenizer)(spacesBeforeAttrString, line, col, offset);
|
|
22
22
|
line = spacesBeforeName.endLine;
|
|
@@ -49,11 +49,11 @@ function attrTokenizer(raw, line, col, startOffset) {
|
|
|
49
49
|
const endQuote = (0, parser_utils_1.tokenizer)(quoteChars, line, col, offset);
|
|
50
50
|
const attrToken = (0, parser_utils_1.tokenizer)(nameChars +
|
|
51
51
|
spacesBeforeEqualChars +
|
|
52
|
-
(equalChars
|
|
52
|
+
(equalChars !== null && equalChars !== void 0 ? equalChars : '') +
|
|
53
53
|
spacesAfterEqualChars +
|
|
54
|
-
(quoteChars
|
|
55
|
-
(valueChars
|
|
56
|
-
(quoteChars
|
|
54
|
+
(quoteChars !== null && quoteChars !== void 0 ? quoteChars : '') +
|
|
55
|
+
(valueChars !== null && valueChars !== void 0 ? valueChars : '') +
|
|
56
|
+
(quoteChars !== null && quoteChars !== void 0 ? quoteChars : ''), name.startLine, name.startCol, name.startOffset);
|
|
57
57
|
return {
|
|
58
58
|
type: 'html-attr',
|
|
59
59
|
uuid: (0, parser_utils_1.uuid)(),
|
package/lib/create-tree.js
CHANGED
|
@@ -10,13 +10,13 @@ const P5_OPTIONS = {
|
|
|
10
10
|
sourceCodeLocationInfo: true,
|
|
11
11
|
};
|
|
12
12
|
function createTree(rawCode, isFragment, offsetOffset, offsetLine, offsetColumn) {
|
|
13
|
-
const doc = isFragment
|
|
14
|
-
? (0, parse5_1.parseFragment)(rawCode, P5_OPTIONS)
|
|
15
|
-
: (0, parse5_1.parse)(rawCode, P5_OPTIONS);
|
|
13
|
+
const doc = isFragment ? (0, parse5_1.parseFragment)(rawCode, P5_OPTIONS) : (0, parse5_1.parse)(rawCode, P5_OPTIONS);
|
|
16
14
|
return createTreeRecursive(doc, null, rawCode, offsetOffset, offsetLine, offsetColumn);
|
|
17
15
|
}
|
|
18
16
|
exports.createTree = createTree;
|
|
19
|
-
function createTreeRecursive(rootNode,
|
|
17
|
+
function createTreeRecursive(rootNode,
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
19
|
+
parentNode, rawHtml, offsetOffset, offsetLine, offsetColumn) {
|
|
20
20
|
const nodeList = [];
|
|
21
21
|
const childNodes = getChildNodes(rootNode);
|
|
22
22
|
let prevNode = null;
|
|
@@ -36,11 +36,16 @@ function createTreeRecursive(rootNode, parentNode, rawHtml, offsetOffset, offset
|
|
|
36
36
|
}
|
|
37
37
|
return nodeList;
|
|
38
38
|
}
|
|
39
|
-
function nodeize(originNode,
|
|
39
|
+
function nodeize(originNode,
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
41
|
+
prevNode,
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
43
|
+
parentNode, rawHtml, offsetOffset, offsetLine, offsetColumn) {
|
|
44
|
+
var _a, _b, _c;
|
|
40
45
|
const nextNode = null;
|
|
41
46
|
const location = getLocation(originNode);
|
|
42
47
|
if (!location) {
|
|
43
|
-
const prevToken = prevNode
|
|
48
|
+
const prevToken = prevNode !== null && prevNode !== void 0 ? prevNode : parentNode;
|
|
44
49
|
const startOffset = prevToken ? prevToken.endOffset : 0;
|
|
45
50
|
const endOffset = prevToken ? prevToken.endOffset : 0;
|
|
46
51
|
const startLine = prevToken ? prevToken.endLine : 0;
|
|
@@ -75,18 +80,18 @@ function nodeize(originNode, prevNode, parentNode, rawHtml, offsetOffset, offset
|
|
|
75
80
|
return node;
|
|
76
81
|
}
|
|
77
82
|
const { startOffset, endOffset, startLine, endLine, startCol, endCol } = location;
|
|
78
|
-
const raw = rawHtml.slice(startOffset, endOffset
|
|
83
|
+
const raw = rawHtml.slice(startOffset, endOffset !== null && endOffset !== void 0 ? endOffset : startOffset);
|
|
79
84
|
switch (originNode.nodeName) {
|
|
80
85
|
case '#documentType': {
|
|
81
86
|
return {
|
|
82
87
|
uuid: (0, parser_utils_1.uuid)(),
|
|
83
88
|
raw,
|
|
84
89
|
// @ts-ignore
|
|
85
|
-
name: originNode.name
|
|
90
|
+
name: (_a = originNode.name) !== null && _a !== void 0 ? _a : '',
|
|
86
91
|
// @ts-ignore
|
|
87
|
-
publicId: originNode.publicId
|
|
92
|
+
publicId: (_b = originNode.publicId) !== null && _b !== void 0 ? _b : '',
|
|
88
93
|
// @ts-ignore
|
|
89
|
-
systemId: originNode.systemId
|
|
94
|
+
systemId: (_c = originNode.systemId) !== null && _c !== void 0 ? _c : '',
|
|
90
95
|
startOffset: startOffset + offsetOffset,
|
|
91
96
|
endOffset: endOffset + offsetOffset,
|
|
92
97
|
startLine: startLine + offsetLine,
|
|
@@ -146,7 +151,7 @@ function nodeize(originNode, prevNode, parentNode, rawHtml, offsetOffset, offset
|
|
|
146
151
|
const tagLoc = 'startTag' in location ? location.startTag : null;
|
|
147
152
|
const startTagRaw = tagLoc
|
|
148
153
|
? rawHtml.slice(tagLoc.startOffset, tagLoc.endOffset)
|
|
149
|
-
: rawHtml.slice(startOffset, endOffset
|
|
154
|
+
: rawHtml.slice(startOffset, endOffset !== null && endOffset !== void 0 ? endOffset : startOffset);
|
|
150
155
|
const tagTokens = (0, parse_raw_tag_1.default)(startTagRaw, startLine, startCol, startOffset, offsetOffset, offsetLine, offsetColumn);
|
|
151
156
|
const tagName = tagTokens.tagName;
|
|
152
157
|
let endTag = null;
|
|
@@ -236,7 +241,8 @@ function nodeize(originNode, prevNode, parentNode, rawHtml, offsetOffset, offset
|
|
|
236
241
|
* - If node has "content" property then parse as document fragment.
|
|
237
242
|
*/
|
|
238
243
|
function getChildNodes(rootNode) {
|
|
239
|
-
|
|
244
|
+
var _a;
|
|
245
|
+
return rootNode.content ? rootNode.content.childNodes : (_a = rootNode.childNodes) !== null && _a !== void 0 ? _a : [];
|
|
240
246
|
}
|
|
241
247
|
function hasLocation(node) {
|
|
242
248
|
return 'sourceCodeLocation' in node;
|
package/lib/index.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
+
export { default as attrTokenizer } from './attr-tokenizer';
|
|
1
2
|
export { default as isDocumentFragment } from './is-document-fragment';
|
|
2
|
-
export { parse } from './parse';
|
|
3
|
-
export { flattenNodes } from './flatten-nodes';
|
|
4
|
-
export { removeDeprecatedNode } from './remove-deprecated-node';
|
|
5
|
-
export { getNamespace } from './get-namespace';
|
|
6
3
|
export { default as parseRawTag } from './parse-raw-tag';
|
|
7
|
-
export {
|
|
4
|
+
export { getNamespace } from './get-namespace';
|
|
5
|
+
export { parse } from './parse';
|
|
6
|
+
export { createTree } from './create-tree';
|
package/lib/index.js
CHANGED
|
@@ -3,18 +3,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.createTree = exports.parse = exports.getNamespace = exports.parseRawTag = exports.isDocumentFragment = exports.attrTokenizer = void 0;
|
|
7
|
+
var attr_tokenizer_1 = require("./attr-tokenizer");
|
|
8
|
+
Object.defineProperty(exports, "attrTokenizer", { enumerable: true, get: function () { return __importDefault(attr_tokenizer_1).default; } });
|
|
7
9
|
var is_document_fragment_1 = require("./is-document-fragment");
|
|
8
10
|
Object.defineProperty(exports, "isDocumentFragment", { enumerable: true, get: function () { return __importDefault(is_document_fragment_1).default; } });
|
|
9
|
-
var parse_1 = require("./parse");
|
|
10
|
-
Object.defineProperty(exports, "parse", { enumerable: true, get: function () { return parse_1.parse; } });
|
|
11
|
-
var flatten_nodes_1 = require("./flatten-nodes");
|
|
12
|
-
Object.defineProperty(exports, "flattenNodes", { enumerable: true, get: function () { return flatten_nodes_1.flattenNodes; } });
|
|
13
|
-
var remove_deprecated_node_1 = require("./remove-deprecated-node");
|
|
14
|
-
Object.defineProperty(exports, "removeDeprecatedNode", { enumerable: true, get: function () { return remove_deprecated_node_1.removeDeprecatedNode; } });
|
|
15
|
-
var get_namespace_1 = require("./get-namespace");
|
|
16
|
-
Object.defineProperty(exports, "getNamespace", { enumerable: true, get: function () { return get_namespace_1.getNamespace; } });
|
|
17
11
|
var parse_raw_tag_1 = require("./parse-raw-tag");
|
|
18
12
|
Object.defineProperty(exports, "parseRawTag", { enumerable: true, get: function () { return __importDefault(parse_raw_tag_1).default; } });
|
|
19
|
-
var
|
|
20
|
-
Object.defineProperty(exports, "
|
|
13
|
+
var get_namespace_1 = require("./get-namespace");
|
|
14
|
+
Object.defineProperty(exports, "getNamespace", { enumerable: true, get: function () { return get_namespace_1.getNamespace; } });
|
|
15
|
+
var parse_1 = require("./parse");
|
|
16
|
+
Object.defineProperty(exports, "parse", { enumerable: true, get: function () { return parse_1.parse; } });
|
|
17
|
+
var create_tree_1 = require("./create-tree");
|
|
18
|
+
Object.defineProperty(exports, "createTree", { enumerable: true, get: function () { return create_tree_1.createTree; } });
|
|
@@ -34,7 +34,11 @@ function optimizeStartsHeadTagOrBodyTagSetup(rawCode) {
|
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
36
|
exports.optimizeStartsHeadTagOrBodyTagSetup = optimizeStartsHeadTagOrBodyTagSetup;
|
|
37
|
-
function optimizeStartsHeadTagOrBodyTagResume(
|
|
37
|
+
function optimizeStartsHeadTagOrBodyTagResume(
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
39
|
+
nodeList,
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
41
|
+
replacements) {
|
|
38
42
|
nodeList.forEach(node => {
|
|
39
43
|
if (!node.nodeName.startsWith(`x-${UNDUPLICATED_CHAR}`)) {
|
|
40
44
|
return;
|
package/lib/parse-raw-tag.js
CHANGED
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
const parser_utils_1 = require("@markuplint/parser-utils");
|
|
5
5
|
const attr_tokenizer_1 = tslib_1.__importDefault(require("./attr-tokenizer"));
|
|
6
|
-
const const_1 = require("./const");
|
|
7
6
|
// eslint-disable-next-line no-control-regex
|
|
8
7
|
const reAttrsInStartTag = /\s*[^\x00-\x1f\x7f-\x9f "'>/=]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^\s]*))?/;
|
|
9
8
|
const reEndTokens = /(\s*\/)?(\s*)>$/;
|
|
@@ -12,7 +11,7 @@ function parseRawTag(raw, startLine, startCol, startOffset, offsetOffset = 0, of
|
|
|
12
11
|
let offset = startOffset + offsetOffset;
|
|
13
12
|
let line = startLine + offsetLine;
|
|
14
13
|
let col = startCol + (startLine === 1 ? offsetColumn : 0);
|
|
15
|
-
const matches = raw.match(
|
|
14
|
+
const matches = raw.match(parser_utils_1.reTag);
|
|
16
15
|
const tagWithAttrs = matches === null || matches === void 0 ? void 0 : matches[1];
|
|
17
16
|
if (!tagWithAttrs) {
|
|
18
17
|
throw new SyntaxError(`Invalid tag syntax: "${raw}"`);
|
|
@@ -20,7 +19,7 @@ function parseRawTag(raw, startLine, startCol, startOffset, offsetOffset = 0, of
|
|
|
20
19
|
// eslint-disable-next-line no-control-regex
|
|
21
20
|
const tagNameSplitted = tagWithAttrs.split(/[\u0000\u0009\u000A\u000C\u0020/>]/);
|
|
22
21
|
const tagName = tagNameSplitted[0] || tagNameSplitted[1];
|
|
23
|
-
if (!tagName || (!
|
|
22
|
+
if (!tagName || (!parser_utils_1.reTagName.test(tagName) && !(0, parser_utils_1.isPotentialCustomElementName)(tagName))) {
|
|
24
23
|
throw new SyntaxError(`Invalid tag name: "${tagName}" in <${tagWithAttrs}>`);
|
|
25
24
|
}
|
|
26
25
|
const tagStartPos = tagWithAttrs.indexOf(tagName);
|
package/lib/parse.js
CHANGED
|
@@ -4,7 +4,6 @@ exports.parse = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const parser_utils_1 = require("@markuplint/parser-utils");
|
|
6
6
|
const create_tree_1 = require("./create-tree");
|
|
7
|
-
const flatten_nodes_1 = require("./flatten-nodes");
|
|
8
7
|
const is_document_fragment_1 = tslib_1.__importDefault(require("./is-document-fragment"));
|
|
9
8
|
const optimize_starts_head_or_body_1 = require("./optimize-starts-head-or-body");
|
|
10
9
|
const parse = (rawCode, options) => {
|
|
@@ -18,7 +17,7 @@ const parse = (rawCode, options) => {
|
|
|
18
17
|
rawCode = data.code;
|
|
19
18
|
}
|
|
20
19
|
const nodeTree = (0, create_tree_1.createTree)(rawCode, isFragment, (_a = options === null || options === void 0 ? void 0 : options.offsetOffset) !== null && _a !== void 0 ? _a : 0, (_b = options === null || options === void 0 ? void 0 : options.offsetLine) !== null && _b !== void 0 ? _b : 0, (_c = options === null || options === void 0 ? void 0 : options.offsetColumn) !== null && _c !== void 0 ? _c : 0);
|
|
21
|
-
const nodeList = (0,
|
|
20
|
+
const nodeList = (0, parser_utils_1.flattenNodes)(nodeTree, rawCode);
|
|
22
21
|
if (data) {
|
|
23
22
|
(0, optimize_starts_head_or_body_1.optimizeStartsHeadTagOrBodyTagResume)(nodeList, data);
|
|
24
23
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markuplint/html-parser",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.6.0",
|
|
4
4
|
"description": "HTML parser for markuplint",
|
|
5
5
|
"repository": "git@github.com:markuplint/markuplint.git",
|
|
6
6
|
"author": "Yusuke Hirao <yusukehirao@me.com>",
|
|
@@ -20,10 +20,13 @@
|
|
|
20
20
|
"clean": "tsc --build --clean"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@markuplint/ml-ast": "3.
|
|
24
|
-
"@markuplint/parser-utils": "3.
|
|
23
|
+
"@markuplint/ml-ast": "3.1.0",
|
|
24
|
+
"@markuplint/parser-utils": "3.6.0",
|
|
25
25
|
"parse5": "7.1.2",
|
|
26
26
|
"tslib": "^2.4.1"
|
|
27
27
|
},
|
|
28
|
-
"
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"type-fest": "^3.7.0"
|
|
30
|
+
},
|
|
31
|
+
"gitHead": "715dd53d3b1064a9bcf616c1533921cad9e3b187"
|
|
29
32
|
}
|
package/lib/const.d.ts
DELETED
package/lib/const.js
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.reSplitterTag = exports.reTagName = exports.reTag = void 0;
|
|
4
|
-
exports.reTag = /^<((?:.|\s|\n)+)>\s*$/;
|
|
5
|
-
// eslint-disable-next-line no-control-regex
|
|
6
|
-
exports.reTagName = /^(?:[a-z][^\u0000\u0009\u000A\u000C\u0020/>]*)/i;
|
|
7
|
-
exports.reSplitterTag = /<[^>]+>/g;
|
package/lib/flatten-nodes.d.ts
DELETED
package/lib/flatten-nodes.js
DELETED
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.flattenNodes = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const parser_utils_1 = require("@markuplint/parser-utils");
|
|
6
|
-
const remove_deprecated_node_1 = require("./remove-deprecated-node");
|
|
7
|
-
const tag_splitter_1 = tslib_1.__importDefault(require("./tag-splitter"));
|
|
8
|
-
function flattenNodes(nodeTree, rawHtml, createLastText = true) {
|
|
9
|
-
const nodeOrders = arrayize(nodeTree, rawHtml);
|
|
10
|
-
{
|
|
11
|
-
/**
|
|
12
|
-
* Correction prev/next/parent
|
|
13
|
-
*/
|
|
14
|
-
let prevToken = null;
|
|
15
|
-
for (const node of nodeOrders) {
|
|
16
|
-
if (!prevToken) {
|
|
17
|
-
prevToken = node;
|
|
18
|
-
continue;
|
|
19
|
-
}
|
|
20
|
-
if (node.type !== 'endtag') {
|
|
21
|
-
prevToken = node;
|
|
22
|
-
continue;
|
|
23
|
-
}
|
|
24
|
-
const endTag = node;
|
|
25
|
-
if (endTag.nodeName.toLowerCase() === 'body' && prevToken.type === 'text') {
|
|
26
|
-
const prevWreckagesText = prevToken;
|
|
27
|
-
if (prevWreckagesText) {
|
|
28
|
-
const wreckages = (0, tag_splitter_1.default)(prevWreckagesText.raw, prevWreckagesText.startLine, prevWreckagesText.startCol);
|
|
29
|
-
if (wreckages.length && wreckages[0]) {
|
|
30
|
-
// console.log('wreckages\n', wreckages);
|
|
31
|
-
const lastText = wreckages[0];
|
|
32
|
-
const raw = lastText.raw;
|
|
33
|
-
const startLine = lastText.line;
|
|
34
|
-
const startCol = lastText.col;
|
|
35
|
-
prevWreckagesText.raw = raw;
|
|
36
|
-
prevWreckagesText.endOffset = prevWreckagesText.startOffset + raw.length;
|
|
37
|
-
prevWreckagesText.startLine = startLine;
|
|
38
|
-
prevWreckagesText.endLine = (0, parser_utils_1.getEndLine)(raw, startLine);
|
|
39
|
-
prevWreckagesText.startCol = startCol;
|
|
40
|
-
prevWreckagesText.endCol = (0, parser_utils_1.getEndCol)(raw, startCol);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
(0, remove_deprecated_node_1.removeDeprecatedNode)(nodeOrders);
|
|
47
|
-
{
|
|
48
|
-
/**
|
|
49
|
-
* getting last node
|
|
50
|
-
*/
|
|
51
|
-
let lastNode = null;
|
|
52
|
-
for (const node of nodeOrders) {
|
|
53
|
-
if (node.isGhost) {
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
lastNode = node;
|
|
57
|
-
}
|
|
58
|
-
if (lastNode) {
|
|
59
|
-
if (lastNode.type === 'text') {
|
|
60
|
-
// Correction for Parse5 AST
|
|
61
|
-
// prev node: ? -> html
|
|
62
|
-
lastNode.prevNode = lastNode.parentNode && lastNode.parentNode.parentNode;
|
|
63
|
-
if (lastNode.prevNode) {
|
|
64
|
-
lastNode.prevNode.nextNode = lastNode;
|
|
65
|
-
}
|
|
66
|
-
// parent node: body -> null
|
|
67
|
-
lastNode.parentNode = null;
|
|
68
|
-
// next node: ? -> null
|
|
69
|
-
lastNode.nextNode = null;
|
|
70
|
-
}
|
|
71
|
-
else if (createLastText) {
|
|
72
|
-
/**
|
|
73
|
-
* create Last spaces
|
|
74
|
-
*/
|
|
75
|
-
let lastOffset = 0;
|
|
76
|
-
nodeOrders.forEach((node, i) => {
|
|
77
|
-
lastOffset = Math.max(node.endOffset, lastOffset);
|
|
78
|
-
});
|
|
79
|
-
// console.log(lastOffset);
|
|
80
|
-
const lastTextContent = rawHtml.slice(lastOffset);
|
|
81
|
-
// console.log(`"${lastTextContent}"`);
|
|
82
|
-
if (lastTextContent) {
|
|
83
|
-
const line = lastNode ? lastNode.endLine : 0;
|
|
84
|
-
const col = lastNode ? lastNode.endCol : 0;
|
|
85
|
-
const lastTextNode = {
|
|
86
|
-
uuid: (0, parser_utils_1.uuid)(),
|
|
87
|
-
raw: lastTextContent,
|
|
88
|
-
startOffset: lastOffset,
|
|
89
|
-
endOffset: lastOffset + lastTextContent.length,
|
|
90
|
-
startLine: line,
|
|
91
|
-
endLine: (0, parser_utils_1.getEndLine)(lastTextContent, line),
|
|
92
|
-
startCol: col,
|
|
93
|
-
endCol: (0, parser_utils_1.getEndCol)(lastTextContent, col),
|
|
94
|
-
nodeName: '#text',
|
|
95
|
-
type: 'text',
|
|
96
|
-
parentNode: null,
|
|
97
|
-
prevNode: lastNode,
|
|
98
|
-
nextNode: null,
|
|
99
|
-
isFragment: false,
|
|
100
|
-
isGhost: false,
|
|
101
|
-
};
|
|
102
|
-
if (lastNode) {
|
|
103
|
-
lastNode.nextNode = lastTextNode;
|
|
104
|
-
if ((lastNode.type === 'starttag' || lastNode.type === 'endtag') && lastNode.pearNode) {
|
|
105
|
-
lastNode.pearNode.nextNode = lastTextNode;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
nodeOrders.push(lastTextNode);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* concat text nodes
|
|
115
|
-
*/
|
|
116
|
-
const result = [];
|
|
117
|
-
nodeOrders.forEach(node => {
|
|
118
|
-
const prevNode = result[result.length - 1] || null;
|
|
119
|
-
if (node.type === 'text' && prevNode && prevNode.type === 'text') {
|
|
120
|
-
prevNode.raw = prevNode.raw + node.raw;
|
|
121
|
-
prevNode.endOffset = node.endOffset;
|
|
122
|
-
prevNode.endLine = node.endLine;
|
|
123
|
-
prevNode.endCol = node.endCol;
|
|
124
|
-
prevNode.nextNode = node.nextNode;
|
|
125
|
-
if (prevNode.parentNode && prevNode.parentNode.childNodes) {
|
|
126
|
-
prevNode.parentNode.childNodes = prevNode.parentNode.childNodes.filter(n => n.uuid !== node.uuid);
|
|
127
|
-
}
|
|
128
|
-
if (node.nextNode) {
|
|
129
|
-
node.nextNode.prevNode = prevNode;
|
|
130
|
-
}
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
result.push(node);
|
|
134
|
-
});
|
|
135
|
-
{
|
|
136
|
-
/**
|
|
137
|
-
* Correction prev/next/parent
|
|
138
|
-
*/
|
|
139
|
-
let prevToken = null;
|
|
140
|
-
for (const node of result) {
|
|
141
|
-
if (!prevToken) {
|
|
142
|
-
prevToken = node;
|
|
143
|
-
continue;
|
|
144
|
-
}
|
|
145
|
-
if (((prevToken.type === 'endtag' && prevToken.nodeName.toLowerCase() === 'body') ||
|
|
146
|
-
prevToken.type === 'doctype') &&
|
|
147
|
-
node.type === 'text') {
|
|
148
|
-
const nextNode = prevToken.nextNode;
|
|
149
|
-
prevToken.nextNode = node;
|
|
150
|
-
if (prevToken.type === 'endtag' && prevToken.pearNode) {
|
|
151
|
-
prevToken.pearNode.nextNode = node;
|
|
152
|
-
}
|
|
153
|
-
node.prevNode = prevToken;
|
|
154
|
-
node.nextNode = nextNode;
|
|
155
|
-
node.parentNode = prevToken.parentNode;
|
|
156
|
-
}
|
|
157
|
-
// EndTag
|
|
158
|
-
if (node.type === 'starttag' && node.pearNode) {
|
|
159
|
-
const endTag = node.pearNode;
|
|
160
|
-
endTag.pearNode = node;
|
|
161
|
-
endTag.prevNode = node.prevNode;
|
|
162
|
-
endTag.nextNode = node.nextNode;
|
|
163
|
-
}
|
|
164
|
-
// Children
|
|
165
|
-
if (node.type === 'text') {
|
|
166
|
-
const parent = node.parentNode;
|
|
167
|
-
if (parent && parent.type === 'starttag' && parent.nodeName.toLowerCase() === 'html') {
|
|
168
|
-
if (parent.childNodes && !parent.childNodes.some(n => n.uuid === node.uuid)) {
|
|
169
|
-
parent.childNodes.push(node);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
prevToken = node;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
// console.log(nodeOrders.map((n, i) => `${i}: ${n.raw.trim()}`));
|
|
177
|
-
return result;
|
|
178
|
-
}
|
|
179
|
-
exports.flattenNodes = flattenNodes;
|
|
180
|
-
function arrayize(nodeTree, rawHtml) {
|
|
181
|
-
const nodeOrders = [];
|
|
182
|
-
let prevLine = 1;
|
|
183
|
-
let prevCol = 1;
|
|
184
|
-
let currentStartOffset = 0;
|
|
185
|
-
let currentEndOffset = 0;
|
|
186
|
-
/**
|
|
187
|
-
* pushing list
|
|
188
|
-
*/
|
|
189
|
-
(0, parser_utils_1.walk)(nodeTree, node => {
|
|
190
|
-
currentStartOffset = node.startOffset;
|
|
191
|
-
const diff = currentStartOffset - currentEndOffset;
|
|
192
|
-
if (diff > 0) {
|
|
193
|
-
const html = rawHtml.slice(currentEndOffset, currentStartOffset);
|
|
194
|
-
/**
|
|
195
|
-
* first white spaces
|
|
196
|
-
*/
|
|
197
|
-
if (/^\s+$/.test(html)) {
|
|
198
|
-
const spaces = html;
|
|
199
|
-
const textNode = {
|
|
200
|
-
uuid: (0, parser_utils_1.uuid)(),
|
|
201
|
-
raw: spaces,
|
|
202
|
-
startOffset: currentEndOffset,
|
|
203
|
-
endOffset: currentEndOffset + spaces.length,
|
|
204
|
-
startLine: prevLine,
|
|
205
|
-
endLine: (0, parser_utils_1.getEndLine)(spaces, prevLine),
|
|
206
|
-
startCol: prevCol,
|
|
207
|
-
endCol: (0, parser_utils_1.getEndCol)(spaces, prevCol),
|
|
208
|
-
nodeName: '#text',
|
|
209
|
-
type: 'text',
|
|
210
|
-
parentNode: node.parentNode,
|
|
211
|
-
prevNode: node.prevNode,
|
|
212
|
-
nextNode: node,
|
|
213
|
-
isFragment: false,
|
|
214
|
-
isGhost: false,
|
|
215
|
-
};
|
|
216
|
-
node.prevNode = textNode;
|
|
217
|
-
if (node.parentNode && node.parentNode.childNodes) {
|
|
218
|
-
node.parentNode.childNodes.unshift(textNode);
|
|
219
|
-
}
|
|
220
|
-
nodeOrders.push(textNode);
|
|
221
|
-
}
|
|
222
|
-
else if (/^<\/[a-z0-9][a-z0-9:-]*>$/i.test(html)) {
|
|
223
|
-
// close tag
|
|
224
|
-
}
|
|
225
|
-
else {
|
|
226
|
-
// never
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
currentEndOffset = currentStartOffset + node.raw.length;
|
|
230
|
-
prevLine = node.endLine;
|
|
231
|
-
prevCol = node.endCol;
|
|
232
|
-
// for ghost nodes
|
|
233
|
-
node.startOffset = node.startOffset || currentStartOffset;
|
|
234
|
-
node.endOffset = node.endOffset || currentEndOffset;
|
|
235
|
-
nodeOrders.push(node);
|
|
236
|
-
});
|
|
237
|
-
return nodeOrders;
|
|
238
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.removeDeprecatedNode = void 0;
|
|
4
|
-
/**
|
|
5
|
-
*
|
|
6
|
-
* @disruptive
|
|
7
|
-
* @param nodeOrders [Disruptive change]
|
|
8
|
-
*/
|
|
9
|
-
function removeDeprecatedNode(nodeOrders) {
|
|
10
|
-
/**
|
|
11
|
-
* sorting
|
|
12
|
-
*/
|
|
13
|
-
nodeOrders.sort((a, b) => {
|
|
14
|
-
if (a.isGhost || b.isGhost) {
|
|
15
|
-
return 0;
|
|
16
|
-
}
|
|
17
|
-
return a.startOffset - b.startOffset;
|
|
18
|
-
});
|
|
19
|
-
/**
|
|
20
|
-
* remove duplicated node
|
|
21
|
-
*/
|
|
22
|
-
const stack = {};
|
|
23
|
-
const removeIndexes = [];
|
|
24
|
-
nodeOrders.forEach((node, i) => {
|
|
25
|
-
if (node.isGhost) {
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
const id = `${node.startLine}:${node.startCol}:${node.endLine}:${node.endCol}`;
|
|
29
|
-
if (stack[id] != null) {
|
|
30
|
-
removeIndexes.push(i);
|
|
31
|
-
}
|
|
32
|
-
stack[id] = i;
|
|
33
|
-
});
|
|
34
|
-
let r = nodeOrders.length;
|
|
35
|
-
while (r--) {
|
|
36
|
-
if (removeIndexes.includes(r)) {
|
|
37
|
-
nodeOrders.splice(r, 1);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
exports.removeDeprecatedNode = removeDeprecatedNode;
|
package/lib/tag-splitter.d.ts
DELETED
package/lib/tag-splitter.js
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const parser_utils_1 = require("@markuplint/parser-utils");
|
|
4
|
-
const const_1 = require("./const");
|
|
5
|
-
function tagSplitter(raw, line, col) {
|
|
6
|
-
return withLocation(tagSplitterAsString(raw), line, col);
|
|
7
|
-
}
|
|
8
|
-
exports.default = tagSplitter;
|
|
9
|
-
function tagSplitterAsString(raw) {
|
|
10
|
-
const tagMatches = raw.match(const_1.reSplitterTag);
|
|
11
|
-
if (!tagMatches) {
|
|
12
|
-
return [raw];
|
|
13
|
-
}
|
|
14
|
-
const tokens = Array.from(tagMatches);
|
|
15
|
-
tokens.unshift(); // remove all match
|
|
16
|
-
const nodes = [];
|
|
17
|
-
let rest = raw;
|
|
18
|
-
for (const token of tokens) {
|
|
19
|
-
const index = rest.indexOf(token);
|
|
20
|
-
let length = token.length;
|
|
21
|
-
if (index > 0) {
|
|
22
|
-
const text = rest.slice(0, index);
|
|
23
|
-
nodes.push(text);
|
|
24
|
-
length += text.length;
|
|
25
|
-
}
|
|
26
|
-
nodes.push(token);
|
|
27
|
-
rest = rest.slice(length);
|
|
28
|
-
}
|
|
29
|
-
if (rest) {
|
|
30
|
-
nodes.push(rest);
|
|
31
|
-
}
|
|
32
|
-
return nodes;
|
|
33
|
-
}
|
|
34
|
-
function withLocation(nodes, line, col) {
|
|
35
|
-
const result = [];
|
|
36
|
-
for (const node of nodes) {
|
|
37
|
-
if (node[0] !== '<') {
|
|
38
|
-
result.push({
|
|
39
|
-
type: 'text',
|
|
40
|
-
raw: node,
|
|
41
|
-
line,
|
|
42
|
-
col,
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
const label = node.slice(1).slice(0, -1);
|
|
47
|
-
if (const_1.reTagName.test(label)) {
|
|
48
|
-
result.push({
|
|
49
|
-
type: 'starttag',
|
|
50
|
-
raw: node,
|
|
51
|
-
line,
|
|
52
|
-
col,
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
else if (label[0] === '/') {
|
|
56
|
-
result.push({
|
|
57
|
-
type: 'endtag',
|
|
58
|
-
raw: node,
|
|
59
|
-
line,
|
|
60
|
-
col,
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
else if (label[0] === '!') {
|
|
64
|
-
result.push({
|
|
65
|
-
type: 'comment',
|
|
66
|
-
raw: node,
|
|
67
|
-
line,
|
|
68
|
-
col,
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
else if (label[0] === '?') {
|
|
72
|
-
result.push({
|
|
73
|
-
type: 'boguscomment',
|
|
74
|
-
raw: node,
|
|
75
|
-
line,
|
|
76
|
-
col,
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
result.push({
|
|
81
|
-
type: 'text',
|
|
82
|
-
raw: node,
|
|
83
|
-
line,
|
|
84
|
-
col,
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
line = (0, parser_utils_1.getEndLine)(node, line);
|
|
89
|
-
col = (0, parser_utils_1.getEndCol)(node, col);
|
|
90
|
-
}
|
|
91
|
-
return result;
|
|
92
|
-
}
|