wikilint 2.44.0 → 2.46.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.
Files changed (80) hide show
  1. package/config/default.json +1 -2
  2. package/config/enwiki.json +1 -1
  3. package/config/jawiki.json +1 -1
  4. package/config/minimum.json +1 -1
  5. package/config/zhwiki.json +1 -1
  6. package/data/ext/templatedata.json +13 -5
  7. package/data/signatures.json +38 -32
  8. package/dist/base.d.mts +10 -2
  9. package/dist/base.d.ts +10 -2
  10. package/dist/bin/config.js +1 -1
  11. package/dist/index.js +1 -1
  12. package/dist/internal.d.ts +6 -1
  13. package/dist/lib/element.js +5 -5
  14. package/dist/lib/lintConfig.js +7 -0
  15. package/dist/lib/lsp.d.ts +11 -3
  16. package/dist/lib/lsp.js +91 -59
  17. package/dist/lib/node.js +2 -2
  18. package/dist/lib/text.js +2 -2
  19. package/dist/map.d.ts +4 -1
  20. package/dist/mixin/elementLike.js +29 -31
  21. package/dist/mixin/hidden.js +0 -1
  22. package/dist/mixin/paramLineParent.d.ts +29 -0
  23. package/dist/mixin/paramLineParent.js +51 -0
  24. package/dist/src/arg.js +17 -35
  25. package/dist/src/atom.d.ts +1 -1
  26. package/dist/src/atom.js +2 -0
  27. package/dist/src/attribute.js +10 -5
  28. package/dist/src/attributes.js +18 -15
  29. package/dist/src/commented.d.ts +1 -0
  30. package/dist/src/commented.js +1 -3
  31. package/dist/src/converterFlags.js +18 -21
  32. package/dist/src/converterRule.js +2 -2
  33. package/dist/src/funcTag.d.ts +23 -0
  34. package/dist/src/funcTag.js +85 -0
  35. package/dist/src/heading.js +8 -3
  36. package/dist/src/hidden.d.ts +3 -2
  37. package/dist/src/hidden.js +29 -5
  38. package/dist/src/imageParameter.js +16 -4
  39. package/dist/src/index.js +2 -2
  40. package/dist/src/link/base.js +14 -2
  41. package/dist/src/link/categorytree.d.ts +2 -0
  42. package/dist/src/link/categorytree.js +8 -5
  43. package/dist/src/link/file.js +21 -14
  44. package/dist/src/multiLine/charinsert.d.ts +16 -0
  45. package/dist/src/multiLine/charinsert.js +84 -0
  46. package/dist/src/multiLine/gallery.js +4 -4
  47. package/dist/src/multiLine/imagemap.d.ts +1 -1
  48. package/dist/src/multiLine/imagemap.js +13 -12
  49. package/dist/src/multiLine/index.d.ts +3 -0
  50. package/dist/src/multiLine/index.js +79 -18
  51. package/dist/src/multiLine/inputbox.d.ts +1 -0
  52. package/dist/src/multiLine/paramTag.d.ts +3 -0
  53. package/dist/src/multiLine/paramTag.js +60 -13
  54. package/dist/src/nested.js +23 -25
  55. package/dist/src/nowiki/quote.js +6 -5
  56. package/dist/src/paramLine.d.ts +23 -3
  57. package/dist/src/paramLine.js +129 -31
  58. package/dist/src/parameter.d.ts +6 -0
  59. package/dist/src/parameter.js +15 -1
  60. package/dist/src/singleLine/charinsertLine.d.ts +21 -0
  61. package/dist/src/singleLine/charinsertLine.js +69 -0
  62. package/dist/src/{imagemapLink.d.ts → singleLine/imagemapLink.d.ts} +8 -7
  63. package/dist/src/singleLine/imagemapLink.js +95 -0
  64. package/dist/src/singleLine/index.d.ts +10 -0
  65. package/dist/src/singleLine/index.js +16 -0
  66. package/dist/src/table/td.js +5 -4
  67. package/dist/src/tag/html.js +26 -8
  68. package/dist/src/tag/index.js +30 -17
  69. package/dist/src/tagPair/ext.js +23 -2
  70. package/dist/src/tagPair/index.js +1 -10
  71. package/dist/src/transclude.js +15 -15
  72. package/dist/util/sharable.js +22 -0
  73. package/dist/util/sharable.mjs +22 -0
  74. package/dist/util/string.js +27 -2
  75. package/i18n/en.json +4 -0
  76. package/i18n/zh-hans.json +4 -0
  77. package/i18n/zh-hant.json +4 -0
  78. package/package.json +17 -25
  79. package/dist/src/imagemapLink.js +0 -34
  80. /package/dist/{util → vendor}/search.js +0 -0
@@ -1,4 +1,38 @@
1
1
  "use strict";
2
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
3
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
4
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
5
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
6
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
7
+ var _, done = false;
8
+ for (var i = decorators.length - 1; i >= 0; i--) {
9
+ var context = {};
10
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
11
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
12
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
13
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
14
+ if (kind === "accessor") {
15
+ if (result === void 0) continue;
16
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
17
+ if (_ = accept(result.get)) descriptor.get = _;
18
+ if (_ = accept(result.set)) descriptor.set = _;
19
+ if (_ = accept(result.init)) initializers.unshift(_);
20
+ }
21
+ else if (_ = accept(result)) {
22
+ if (kind === "field") initializers.unshift(_);
23
+ else descriptor[key] = _;
24
+ }
25
+ }
26
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
27
+ done = true;
28
+ };
29
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
30
+ var useValue = arguments.length > 2;
31
+ for (var i = 0; i < initializers.length; i++) {
32
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
33
+ }
34
+ return useValue ? value : void 0;
35
+ };
2
36
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
37
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
38
  };
@@ -6,51 +40,115 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
40
  exports.ParamLineToken = void 0;
7
41
  const lint_1 = require("../util/lint");
8
42
  const sharable_1 = require("../util/sharable");
43
+ const gapped_1 = require("../mixin/gapped");
9
44
  const index_1 = __importDefault(require("../index"));
10
45
  const index_2 = require("./index");
46
+ const atom_1 = require("./atom");
47
+ const skipTypes = new Set(['comment', 'include', 'noinclude']);
11
48
  /**
12
49
  * parameter of certain extension tags
13
50
  *
14
51
  * 某些扩展标签的参数
52
+ * @classdesc `{childNodes: [AtomToken] | [AtomToken, AtomToken]}`
15
53
  */
16
- class ParamLineToken extends index_2.Token {
17
- get type() {
18
- return 'param-line';
19
- }
20
- /** @param name 扩展标签名 */
21
- constructor(name, wikitext, config, accum, acceptable) {
22
- super(wikitext, config, accum, acceptable);
23
- this.setAttribute('name', name);
24
- }
25
- /** @private */
26
- lint(start = this.getAbsoluteIndex()) {
27
- LINT: {
28
- const rule = 'no-ignored', { lintConfig } = index_1.default, { name, childNodes } = this, s = lintConfig.getSeverity(rule, name);
29
- if (!s) {
30
- return [];
54
+ let ParamLineToken = (() => {
55
+ let _classDecorators = [(0, gapped_1.gapped)()];
56
+ let _classDescriptor;
57
+ let _classExtraInitializers = [];
58
+ let _classThis;
59
+ let _classSuper = index_2.Token;
60
+ var ParamLineToken = class extends _classSuper {
61
+ static { _classThis = this; }
62
+ static {
63
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
64
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
65
+ ParamLineToken = _classThis = _classDescriptor.value;
66
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
67
+ __runInitializers(_classThis, _classExtraInitializers);
68
+ }
69
+ get type() {
70
+ return 'param-line';
71
+ }
72
+ /**
73
+ * A reasonable parameter name
74
+ *
75
+ * 合理的参数名
76
+ * @since v1.45.0
77
+ */
78
+ get key() {
79
+ LINT: return this.getKey();
80
+ }
81
+ /** @param name 扩展标签名 */
82
+ constructor(name, wikitext, config, accum, acceptable = {}) {
83
+ super(undefined, config, accum, {});
84
+ this.setAttribute('name', name);
85
+ const equal = wikitext.indexOf('=');
86
+ if (equal === -1) {
87
+ this.insertAt(new atom_1.AtomToken(wikitext, 'param-line-key', config, accum, acceptable));
31
88
  }
32
- const msg = index_1.default.msg('invalid-parameter', name);
33
- if (childNodes.some(({ type }) => type === 'ext')) {
34
- return [(0, lint_1.generateForSelf)(this, { start }, rule, msg, s)];
89
+ else {
90
+ this.append(new atom_1.AtomToken(wikitext.slice(0, equal), 'param-line-key', config, accum, acceptable), new atom_1.AtomToken(wikitext.slice(equal + 1), 'param-line-value', config, accum, acceptable));
35
91
  }
36
- const children = childNodes
37
- .filter(({ type }) => type !== 'comment' && type !== 'include' && type !== 'noinclude'), isInputbox = name === 'inputbox', i = isInputbox ? children.findIndex(({ type }) => type !== 'text') : -1;
38
- let str = children.slice(0, i === -1 ? undefined : i).map(String).join('').trim();
39
- if (str) {
40
- if (isInputbox) {
41
- str = str.toLowerCase();
92
+ }
93
+ /** @private */
94
+ toString(skip) {
95
+ return super.toString(skip, '=');
96
+ }
97
+ /** @private */
98
+ text() {
99
+ return this.childNodes.map(child => child.text().trim()).join('=');
100
+ }
101
+ /** @private */
102
+ lint(start = this.getAbsoluteIndex()) {
103
+ LINT: {
104
+ const rule = 'no-ignored', { lintConfig } = index_1.default, { name, length, firstChild: { childNodes }, previousSibling } = this, s = lintConfig.getSeverity(rule, name);
105
+ if (!s) {
106
+ return [];
107
+ }
108
+ const children = childNodes.filter(({ type }) => !skipTypes.has(type)), i = children.findIndex(({ type }) => type !== 'text');
109
+ let key = children.slice(0, i === -1 ? undefined : i).map(String).join('').trim(), wrong = false;
110
+ if (childNodes.some(({ type }) => type === 'ext') || length === 1 && i === -1 && key) {
111
+ wrong = true;
112
+ }
113
+ else if (key || length === 2) {
114
+ if (name === 'inputbox') {
115
+ key = key.toLowerCase();
116
+ }
117
+ const params = sharable_1.extParams[name];
118
+ if (i === -1
119
+ ? !params.some(p => p === key
120
+ || p.endsWith('$1') && key.startsWith(p.slice(0, -2)))
121
+ : !params.some(p => p.startsWith(key))) {
122
+ wrong = true;
123
+ }
42
124
  }
43
- const j = str.indexOf('='), key = str.slice(0, j === -1 ? undefined : j).trim(), params = sharable_1.extParams[name];
44
- if (j === -1 ? i === -1 || !params.some(p => p.startsWith(key)) : !params.includes(key)) {
45
- const e = (0, lint_1.generateForSelf)(this, { start }, rule, msg, s);
125
+ if (wrong) {
126
+ const e = (0, lint_1.generateForSelf)(this, { start }, rule, index_1.default.msg('invalid-parameter', name), s);
46
127
  if (lintConfig.computeEditInfo) {
47
- e.suggestions = [(0, lint_1.fixByRemove)(e)];
128
+ e.suggestions = [(0, lint_1.fixByRemove)(e, previousSibling ? -1 : 0)];
48
129
  }
49
130
  return [e];
50
131
  }
132
+ return super.lint(start, false);
51
133
  }
52
- return super.lint(start, false);
53
134
  }
54
- }
55
- }
135
+ /**
136
+ * Get a reasonable parameter name
137
+ *
138
+ * 获取合理的参数名
139
+ * @since v1.45.0
140
+ */
141
+ getKey() {
142
+ LINT: {
143
+ const { length, firstChild: { childNodes }, name } = this, isInputbox = name === 'inputbox';
144
+ return length === 1 || childNodes.some(({ type }) => type === 'ext')
145
+ ? undefined
146
+ : childNodes.map(child => isInputbox && child.type === 'text' ? child.data.toLowerCase() : child.text())
147
+ .join('')
148
+ .trim();
149
+ }
150
+ }
151
+ };
152
+ return ParamLineToken = _classThis;
153
+ })();
56
154
  exports.ParamLineToken = ParamLineToken;
@@ -23,4 +23,10 @@ export declare abstract class ParameterToken extends Token {
23
23
  * @param value 参数值
24
24
  */
25
25
  constructor(key?: string | number, value?: string, config?: Config, accum?: Token[]);
26
+ /**
27
+ * Get the parameter value
28
+ *
29
+ * 获取参数值
30
+ */
31
+ getValue(): string;
26
32
  }
@@ -61,7 +61,9 @@ class ParameterToken extends index_2.Token {
61
61
  }
62
62
  /** @private */
63
63
  text() {
64
- return this.anon ? this.lastChild.text() : super.text('=');
64
+ return this.anon
65
+ ? this.getValue()
66
+ : this.childNodes.map(child => child.text().trim()).join('=');
65
67
  }
66
68
  /** @private */
67
69
  getGaps() {
@@ -92,5 +94,17 @@ class ParameterToken extends index_2.Token {
92
94
  return errors;
93
95
  }
94
96
  }
97
+ /**
98
+ * Get the parameter value
99
+ *
100
+ * 获取参数值
101
+ */
102
+ getValue() {
103
+ const { parentNode, lastChild, anon, name } = this, value = (0, string_1.removeCommentLine)(lastChild.text());
104
+ return anon && (parentNode?.isTemplate() !== false
105
+ || name === '2' && parentNode.type === 'magic-word' && parentNode.name === 'tag')
106
+ ? value
107
+ : value.trim();
108
+ }
95
109
  }
96
110
  exports.ParameterToken = ParameterToken;
@@ -0,0 +1,21 @@
1
+ import { SingleLineToken } from './index';
2
+ import { ExtToken } from '../tagPair/ext';
3
+ import type { Config, LintError } from '../../base';
4
+ import type { Token, CharinsertToken, AstText } from '../../internal';
5
+ /**
6
+ * lines in `<charinsert>`
7
+ *
8
+ * `<charinsert>` 的行
9
+ * @classdesc `{childNodes: (AstText | ExtToken)[]}`
10
+ */
11
+ export declare abstract class CharinsertLineToken extends SingleLineToken {
12
+ readonly childNodes: readonly (AstText | ExtToken)[];
13
+ abstract get firstChild(): AstText | ExtToken | undefined;
14
+ abstract get lastChild(): AstText | ExtToken | undefined;
15
+ abstract get parentNode(): CharinsertToken | undefined;
16
+ abstract get previousSibling(): CharinsertLineToken | undefined;
17
+ abstract get nextSibling(): CharinsertLineToken | undefined;
18
+ get type(): 'charinsert-line';
19
+ /** @class */
20
+ constructor(wikitext: string | undefined, config: Config, accum: Token[]);
21
+ }
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CharinsertLineToken = void 0;
7
+ const lint_1 = require("../../util/lint");
8
+ const rect_1 = require("../../lib/rect");
9
+ const index_1 = __importDefault(require("../../index"));
10
+ const index_2 = require("./index");
11
+ const ext_1 = require("../tagPair/ext");
12
+ /**
13
+ * lines in `<charinsert>`
14
+ *
15
+ * `<charinsert>` 的行
16
+ * @classdesc `{childNodes: (AstText | ExtToken)[]}`
17
+ */
18
+ class CharinsertLineToken extends index_2.SingleLineToken {
19
+ get type() {
20
+ return 'charinsert-line';
21
+ }
22
+ /** @class */
23
+ constructor(wikitext, config, accum) {
24
+ super(wikitext?.replace(/<(nowiki)>(.*?)<\/(nowiki)>/giu, (_, opening, content, closing) => {
25
+ // @ts-expect-error abstract class
26
+ new ext_1.ExtToken(opening, undefined, content, closing, config, false, accum);
27
+ return `\0${accum.length - 2}e\x7F`;
28
+ }), config, accum);
29
+ }
30
+ /** @private */
31
+ lint(start = this.getAbsoluteIndex()) {
32
+ LINT: {
33
+ const rule = 'no-ignored', s = index_1.default.lintConfig.getSeverity(rule, 'charinsert');
34
+ if (!s) {
35
+ return [];
36
+ }
37
+ const errors = [], str = this.childNodes.map(child => child.type === 'text'
38
+ ? child.data
39
+ : `<nowiki>${child.innerText.replace(/[^+]/gu, '_')}</nowiki>`).join(''), re = /(?:^|\s)\S+/gu, rect = new rect_1.BoundingRect(this, start), msg = index_1.default.msg('invalid-content', 'charinsert');
40
+ let mt = re.exec(str);
41
+ while (mt) {
42
+ const [item] = mt;
43
+ let i = item.indexOf('+');
44
+ if (i !== -1 && item.slice(0, i).trim()) {
45
+ i = item.indexOf('+', i + 1);
46
+ }
47
+ if (i !== -1) {
48
+ const e = (0, lint_1.generateForSelf)(this, rect, rule, msg, s), startOffset = mt.index + i, endOffset = mt.index + item.length;
49
+ e.endIndex = start + endOffset;
50
+ e.endCol = e.startCol + endOffset;
51
+ e.startIndex += startOffset;
52
+ e.startCol += startOffset;
53
+ errors.push(e);
54
+ }
55
+ mt = re.exec(str);
56
+ }
57
+ return errors;
58
+ }
59
+ }
60
+ /* NOT FOR BROWSER ONLY */
61
+ /** @private */
62
+ text() {
63
+ const entities = { '\t': '&#9;', '\r': '&#12;', ' ': '&#32;' };
64
+ return this.childNodes.map(child => child.type === 'text'
65
+ ? child.data
66
+ : child.innerText.replace(/[\t\r ]/gu, c => entities[c])).join('').trim().replace(/\n+/gu, ' ');
67
+ }
68
+ }
69
+ exports.CharinsertLineToken = CharinsertLineToken;
@@ -1,16 +1,17 @@
1
- import { Token } from './index';
2
- import { NoincludeToken } from './nowiki/noinclude';
3
- import { LinkToken } from './link/index';
4
- import { ExtLinkToken } from './extLink';
5
- import type { Config } from '../base';
6
- import type { AstText, ImagemapToken, GalleryImageToken } from '../internal';
1
+ import { SingleLineToken } from './index';
2
+ import { NoincludeToken } from '../nowiki/noinclude';
3
+ import { LinkToken } from '../link/index';
4
+ import { ExtLinkToken } from '../extLink';
5
+ import type { Config, LintError } from '../../base';
6
+ import type { AstText, ImagemapToken, GalleryImageToken, Token } from '../../internal';
7
7
  /**
8
8
  * link inside the `<imagemap>`
9
9
  *
10
10
  * `<imagemap>`内的链接
11
11
  * @classdesc `{childNodes: [AstText, LinkToken|ExtLinkToken, NoincludeToken]}`
12
12
  */
13
- export declare abstract class ImagemapLinkToken extends Token {
13
+ export declare abstract class ImagemapLinkToken extends SingleLineToken {
14
+ #private;
14
15
  readonly childNodes: readonly [AstText, LinkToken | ExtLinkToken, NoincludeToken];
15
16
  abstract get firstChild(): AstText;
16
17
  abstract get lastChild(): NoincludeToken;
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ImagemapLinkToken = void 0;
7
+ const lint_1 = require("../../util/lint");
8
+ const index_1 = __importDefault(require("../../index"));
9
+ const index_2 = require("./index");
10
+ const noinclude_1 = require("../nowiki/noinclude");
11
+ const index_3 = require("../link/index");
12
+ const extLink_1 = require("../extLink");
13
+ const shapes = new Set(['default', 'rect', 'circle', 'poly']);
14
+ /** @ignore */
15
+ const notNumeric = (s, allowNegative) => {
16
+ const n = Number(s);
17
+ return Number.isNaN(n) || n > 1e9 || !allowNegative && n < 0;
18
+ };
19
+ /**
20
+ * link inside the `<imagemap>`
21
+ *
22
+ * `<imagemap>`内的链接
23
+ * @classdesc `{childNodes: [AstText, LinkToken|ExtLinkToken, NoincludeToken]}`
24
+ */
25
+ class ImagemapLinkToken extends index_2.SingleLineToken {
26
+ get type() {
27
+ return 'imagemap-link';
28
+ }
29
+ /**
30
+ * @param pre 链接前的文本
31
+ * @param linkStuff 内外链接
32
+ * @param post 链接后的文本
33
+ */
34
+ constructor(pre, linkStuff, post, config, accum = []) {
35
+ super(undefined, config, accum);
36
+ this.append(pre, linkStuff.length === 2
37
+ // @ts-expect-error abstract class
38
+ ? new index_3.LinkToken(...linkStuff, config, accum)
39
+ // @ts-expect-error abstract class
40
+ : new extLink_1.ExtLinkToken(...linkStuff, config, accum),
41
+ // @ts-expect-error abstract class
42
+ new noinclude_1.NoincludeToken(post, config, accum));
43
+ }
44
+ /**
45
+ * 检查链接区域是否合法
46
+ * @param errors 错误列表
47
+ * @param coords 坐标字符串
48
+ * @param start 节点起始位置
49
+ * @param minCount 最少需要的坐标数量
50
+ * @param isPoly 是否为多边形
51
+ */
52
+ #lintCoords(errors, coords, start, minCount, isPoly) {
53
+ LINT: {
54
+ const parts = coords.split(/[ \t]+/u).map(s => s.trim()).filter(Boolean), { length } = parts, rule = 'invalid-imagemap', s = index_1.default.lintConfig.getSeverity(rule, 'coord');
55
+ if (s && (length < minCount || isPoly && length % 2 || parts.some(part => notNumeric(part, isPoly)))) {
56
+ errors.push((0, lint_1.generateForChild)(this.firstChild, { start }, rule, 'invalid-coord', s));
57
+ }
58
+ }
59
+ }
60
+ /** 获取链接区域图形和坐标 */
61
+ #getShape() {
62
+ const area = this.firstChild.data.trim(), i = area.search(/[ \t]/u), shape = i === -1 ? area : area.slice(0, i);
63
+ return shapes.has(shape) && [shape, area.slice(i).trim()];
64
+ }
65
+ /** @private */
66
+ lint(start = this.getAbsoluteIndex(), re) {
67
+ LINT: {
68
+ const errors = super.lint(start, re), { firstChild } = this, shapeAndCoords = this.#getShape();
69
+ if (shapeAndCoords) {
70
+ const [shape, coords] = shapeAndCoords;
71
+ switch (shape) {
72
+ case 'default':
73
+ break;
74
+ case 'rect':
75
+ this.#lintCoords(errors, coords, start, 4);
76
+ break;
77
+ case 'circle':
78
+ this.#lintCoords(errors, coords, start, 3);
79
+ break;
80
+ case 'poly':
81
+ this.#lintCoords(errors, coords, start, 1, true);
82
+ // no default
83
+ }
84
+ }
85
+ else {
86
+ const rule = 'invalid-imagemap', s = index_1.default.lintConfig.getSeverity(rule, 'shape');
87
+ if (s) {
88
+ errors.push((0, lint_1.generateForChild)(firstChild, { start }, rule, 'unrecognized-shape', s));
89
+ }
90
+ }
91
+ return errors;
92
+ }
93
+ }
94
+ }
95
+ exports.ImagemapLinkToken = ImagemapLinkToken;
@@ -0,0 +1,10 @@
1
+ import { Token } from '../index';
2
+ import type { MultiLineToken } from '../multiLine/index';
3
+ /**
4
+ * single-line token inside specific extension tags, such as `<charinsert>` and `<imagemap>`
5
+ *
6
+ * 特定扩展标签内的单行节点,如 `<charinsert>` 和 `<imagemap>`
7
+ */
8
+ export declare abstract class SingleLineToken extends Token {
9
+ abstract get parentNode(): MultiLineToken | undefined;
10
+ }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SingleLineToken = void 0;
4
+ const index_1 = require("../index");
5
+ /**
6
+ * single-line token inside specific extension tags, such as `<charinsert>` and `<imagemap>`
7
+ *
8
+ * 特定扩展标签内的单行节点,如 `<charinsert>` 和 `<imagemap>`
9
+ */
10
+ class SingleLineToken extends index_1.Token {
11
+ /** @private */
12
+ isPlain() {
13
+ return this.type === 'plain';
14
+ }
15
+ }
16
+ exports.SingleLineToken = SingleLineToken;
@@ -148,8 +148,9 @@ let TdToken = (() => {
148
148
  /** @private */
149
149
  lint(start = this.getAbsoluteIndex(), re) {
150
150
  LINT: {
151
- const errors = super.lint(start, re), rect = new rect_1.BoundingRect(this, start + this.getRelativeIndex(this.length - 1)), rule = 'pipe-like', { lintConfig } = index_1.default, { computeEditInfo, fix } = lintConfig, severities = ['td', 'double'].map(key => lintConfig.getSeverity(rule, key));
152
- for (const child of this.lastChild.childNodes) {
151
+ const errors = super.lint(start, re), rect = new rect_1.BoundingRect(this, start + this.getRelativeIndex(this.length - 1)), rule = 'pipe-like', { lintConfig } = index_1.default, { computeEditInfo, fix } = lintConfig, severities = ['td', 'double'].map(key => lintConfig.getSeverity(rule, key)), { childNodes, length } = this.lastChild, pipes = [];
152
+ for (let i = length - 1; i >= 0; i--) {
153
+ const child = childNodes[i];
153
154
  if (child.type === 'text') {
154
155
  const { data } = child;
155
156
  if (data.includes('|')) {
@@ -165,12 +166,12 @@ let TdToken = (() => {
165
166
  e.suggestions = [(0, lint_1.fixByPipe)(e.startIndex, data)];
166
167
  }
167
168
  }
168
- errors.push(e);
169
+ pipes.push(e);
169
170
  }
170
171
  }
171
172
  }
172
173
  }
173
- return errors;
174
+ return [...errors, ...pipes.reverse()];
174
175
  }
175
176
  }
176
177
  /**
@@ -112,16 +112,34 @@ let HtmlToken = (() => {
112
112
  }
113
113
  /** @private */
114
114
  text() {
115
- const { closing, selfClosing, name } = this, [, , voidTags] = this.getAttribute('config').html;
115
+ const { closing, selfClosing, name } = this, [normalTags, , voidTags] = this.getAttribute('config').html;
116
+ let slash;
116
117
  if (voidTags.includes(name)) {
117
- return closing && name !== 'br' ? '' : super.text('/');
118
+ if (closing && name !== 'br') {
119
+ return '';
120
+ }
121
+ slash = '/';
122
+ }
123
+ else {
124
+ slash = selfClosing && !closing && !normalTags.includes(name) ? '/' : '';
125
+ }
126
+ return `<${closing && !slash ? '/' : ''}${name}${closing ? '' : super.text()}${slash}>`;
127
+ }
128
+ /** 是否是无效自封闭标签 */
129
+ #lint() {
130
+ const { name, closing, selfClosing } = this, [, flexibleTags, voidTags] = this.getAttribute('config').html, isVoid = voidTags.includes(name), isFlexible = flexibleTags.includes(name), isNormal = !isVoid && !isFlexible;
131
+ if (!(closing && (selfClosing || isVoid) || selfClosing && isNormal)) {
132
+ return false;
133
+ }
134
+ else if (isVoid) {
135
+ return 2;
118
136
  }
119
- return super.text(selfClosing && !closing ? '/' : '');
137
+ return isFlexible ? 1 : 0;
120
138
  }
121
139
  /** @private */
122
140
  lint(start = this.getAbsoluteIndex(), re) {
123
141
  LINT: {
124
- const errors = super.lint(start, re), { name, parentNode, closing, selfClosing } = this, rect = new rect_1.BoundingRect(this, start), { lintConfig } = index_1.default, { computeEditInfo, fix } = lintConfig, severity = this.inTableAttrs();
142
+ const errors = super.lint(start, re), { name, parentNode, closing } = this, rect = new rect_1.BoundingRect(this, start), { lintConfig } = index_1.default, { computeEditInfo, fix } = lintConfig, severity = this.inTableAttrs();
125
143
  let rule = 'h1', s = lintConfig.getSeverity(rule, 'html');
126
144
  if (s && name === 'h1' && !closing) {
127
145
  const e = (0, lint_1.generateForSelf)(this, rect, rule, '<h1>', s);
@@ -153,9 +171,9 @@ let HtmlToken = (() => {
153
171
  }
154
172
  errors.push(e);
155
173
  }
156
- const [, flexibleTags, voidTags] = this.getAttribute('config').html, isVoid = voidTags.includes(name), isFlexible = flexibleTags.includes(name), isNormal = !isVoid && !isFlexible;
174
+ const tagType = this.#lint();
157
175
  rule = 'unmatched-tag';
158
- if (closing && (selfClosing || isVoid) || selfClosing && isNormal) {
176
+ if (tagType !== false) {
159
177
  s = lintConfig.getSeverity(rule, closing ? 'both' : 'selfClosing');
160
178
  if (s) {
161
179
  const e = (0, lint_1.generateForSelf)(this, rect, rule, closing ? 'closing-and-self-closing' : 'invalid-self-closing', s);
@@ -165,13 +183,13 @@ let HtmlToken = (() => {
165
183
  range: [e.endIndex - 2, e.endIndex - 1],
166
184
  text: '',
167
185
  };
168
- if (isFlexible) {
186
+ if (tagType === 1) {
169
187
  if (computeEditInfo) {
170
188
  e.suggestions = [open, noSelfClosing];
171
189
  }
172
190
  }
173
191
  else if (closing) {
174
- e.fix = isVoid ? open : noSelfClosing;
192
+ e.fix = tagType === 2 ? open : noSelfClosing;
175
193
  }
176
194
  else if (computeEditInfo) {
177
195
  e.suggestions = [
@@ -34,11 +34,6 @@ class TagToken extends index_1.Token {
34
34
  return `<${this.#closing ? '/' : ''}${this.#tag}${super.toString(skip)}${this.selfClosing ? '/' : ''}>`;
35
35
  }
36
36
  /** @private */
37
- text(separator = '') {
38
- const { closing } = this;
39
- return `<${closing && !separator ? '/' : ''}${this.#tag}${closing ? '' : super.text()}${separator}>`;
40
- }
41
- /** @private */
42
37
  getAttribute(key) {
43
38
  return key === 'padding'
44
39
  ? this.#tag.length + (this.#closing ? 2 : 1)
@@ -51,8 +46,9 @@ class TagToken extends index_1.Token {
51
46
  */
52
47
  findMatchingTag() {
53
48
  LINT: return (0, lint_1.cache)(this.#match, () => {
54
- const { type, name, parentNode, closing, selfClosing, } = this;
55
- let isVoid = false, isFlexible = false;
49
+ const { type, name, closing, selfClosing, } = this;
50
+ // eslint-disable-next-line prefer-const
51
+ let { parentNode } = this, isVoid = false, isFlexible = false;
56
52
  if (type === 'html') {
57
53
  const [, flexibleTags, voidTags] = this.getAttribute('config').html;
58
54
  isVoid = voidTags.includes(name);
@@ -65,27 +61,44 @@ class TagToken extends index_1.Token {
65
61
  if (!parentNode) {
66
62
  return undefined;
67
63
  }
68
- const { childNodes } = parentNode, i = childNodes.indexOf(this), siblings = closing ? childNodes.slice(0, i).reverse() : childNodes.slice(i + 1), stack = [this], { rev } = debug_1.Shadow;
69
- for (const token of siblings) {
70
- if (!token.is(type)
71
- || type === 'html' && (token.name !== name || isFlexible && token.selfClosing)) {
72
- continue;
64
+ const { childNodes } = parentNode, i = childNodes.indexOf(this), siblings = closing ? childNodes.slice(0, i) : childNodes.slice(i + 1).reverse(), stack = [this], { rev } = debug_1.Shadow;
65
+ let cur = siblings.pop(), until;
66
+ while (cur) {
67
+ // eslint-disable-next-line no-empty, @typescript-eslint/no-unnecessary-condition
68
+ if (!cur) {
69
+ }
70
+ else if (until) {
71
+ if (cur === until) {
72
+ until = undefined;
73
+ }
74
+ }
75
+ else if (!cur.is(type)
76
+ || type === 'html' && (cur.name !== name || isFlexible && cur.selfClosing)) {
77
+ //
73
78
  }
74
- else if (token.#closing === closing) {
79
+ else if (cur.#closing === closing) {
75
80
  /* c8 ignore next 3 */
76
81
  if (type === 'tvar') {
77
82
  return undefined;
78
83
  }
79
- stack.push(token);
84
+ else if (cur.#match?.[0] === rev) {
85
+ const [, matched] = cur.#match;
86
+ if (!matched) {
87
+ return undefined;
88
+ }
89
+ until = matched;
90
+ }
91
+ stack.push(cur);
80
92
  }
81
93
  else {
82
94
  const top = stack.pop();
83
95
  if (top === this) {
84
- return token;
96
+ return cur;
85
97
  }
86
- top.#match = [rev, token];
87
- token.#match = [rev, top];
98
+ top.#match = [rev, cur];
99
+ cur.#match = [rev, top];
88
100
  }
101
+ cur = siblings.pop();
89
102
  }
90
103
  for (const token of stack) {
91
104
  token.#match = [rev, undefined];