wikilint 2.44.0 → 2.45.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/config/default.json +1 -2
- package/config/enwiki.json +1 -1
- package/config/jawiki.json +1 -1
- package/config/minimum.json +1 -1
- package/config/zhwiki.json +1 -1
- package/data/ext/templatedata.json +13 -5
- package/data/signatures.json +38 -32
- package/dist/base.d.mts +1 -1
- package/dist/base.d.ts +1 -1
- package/dist/bin/config.js +1 -1
- package/dist/index.js +1 -1
- package/dist/internal.d.ts +6 -1
- package/dist/lib/element.js +5 -5
- package/dist/lib/lintConfig.js +7 -0
- package/dist/lib/lsp.d.ts +1 -2
- package/dist/lib/lsp.js +18 -42
- package/dist/lib/node.js +2 -2
- package/dist/lib/text.js +2 -2
- package/dist/map.d.ts +4 -1
- package/dist/mixin/elementLike.js +29 -31
- package/dist/mixin/hidden.js +0 -1
- package/dist/mixin/paramLineParent.d.ts +26 -0
- package/dist/mixin/paramLineParent.js +51 -0
- package/dist/src/arg.js +17 -35
- package/dist/src/atom.d.ts +1 -1
- package/dist/src/atom.js +2 -0
- package/dist/src/attribute.js +10 -5
- package/dist/src/attributes.js +15 -13
- package/dist/src/commented.d.ts +1 -0
- package/dist/src/commented.js +1 -3
- package/dist/src/converterFlags.js +9 -5
- package/dist/src/converterRule.js +2 -2
- package/dist/src/funcTag.d.ts +23 -0
- package/dist/src/funcTag.js +85 -0
- package/dist/src/heading.js +8 -3
- package/dist/src/hidden.d.ts +3 -2
- package/dist/src/hidden.js +29 -5
- package/dist/src/imageParameter.js +16 -4
- package/dist/src/index.js +2 -2
- package/dist/src/link/base.js +14 -2
- package/dist/src/link/categorytree.d.ts +2 -0
- package/dist/src/link/categorytree.js +8 -5
- package/dist/src/link/file.js +18 -12
- package/dist/src/multiLine/charinsert.d.ts +16 -0
- package/dist/src/multiLine/charinsert.js +84 -0
- package/dist/src/multiLine/gallery.js +4 -4
- package/dist/src/multiLine/imagemap.d.ts +1 -1
- package/dist/src/multiLine/imagemap.js +7 -7
- package/dist/src/multiLine/index.d.ts +3 -0
- package/dist/src/multiLine/index.js +79 -18
- package/dist/src/multiLine/inputbox.d.ts +1 -0
- package/dist/src/multiLine/paramTag.d.ts +3 -0
- package/dist/src/multiLine/paramTag.js +60 -13
- package/dist/src/nested.js +7 -7
- package/dist/src/nowiki/quote.js +6 -5
- package/dist/src/paramLine.d.ts +17 -3
- package/dist/src/paramLine.js +123 -31
- package/dist/src/parameter.d.ts +6 -0
- package/dist/src/parameter.js +15 -1
- package/dist/src/singleLine/charinsertLine.d.ts +21 -0
- package/dist/src/singleLine/charinsertLine.js +69 -0
- package/dist/src/{imagemapLink.d.ts → singleLine/imagemapLink.d.ts} +8 -7
- package/dist/src/singleLine/imagemapLink.js +95 -0
- package/dist/src/singleLine/index.d.ts +10 -0
- package/dist/src/singleLine/index.js +16 -0
- package/dist/src/tag/html.js +26 -8
- package/dist/src/tag/index.js +18 -17
- package/dist/src/tagPair/ext.js +23 -2
- package/dist/src/tagPair/index.js +1 -10
- package/dist/src/transclude.js +13 -13
- package/dist/util/sharable.js +22 -0
- package/dist/util/sharable.mjs +22 -0
- package/dist/util/string.js +27 -2
- package/i18n/en.json +4 -0
- package/i18n/zh-hans.json +4 -0
- package/i18n/zh-hant.json +4 -0
- package/package.json +10 -18
- package/dist/src/imagemapLink.js +0 -34
- /package/dist/{util → vendor}/search.js +0 -0
package/dist/lib/lsp.js
CHANGED
|
@@ -21,7 +21,7 @@ const util_1 = __importDefault(require("util"));
|
|
|
21
21
|
const child_process_1 = require("child_process");
|
|
22
22
|
const crypto_1 = require("crypto");
|
|
23
23
|
const stylelint_util_1 = require("@bhsd/stylelint-util");
|
|
24
|
-
const search_1 = __importDefault(require("../
|
|
24
|
+
const search_1 = __importDefault(require("../vendor/search"));
|
|
25
25
|
const constants_2 = require("../util/constants");
|
|
26
26
|
const document_1 = require("./document");
|
|
27
27
|
exports.tasks = new WeakMap();
|
|
@@ -105,7 +105,7 @@ const createNodeRange = (token) => {
|
|
|
105
105
|
* @param extra extra text
|
|
106
106
|
* @param getDoc documentation method
|
|
107
107
|
*/
|
|
108
|
-
const getCompletion = (words, kind, mt, { line, character }, extra, getDoc) => [...new Set(words)].map((w) => {
|
|
108
|
+
const getCompletion = (words, kind, mt, { line, character }, extra = '', getDoc) => [...new Set(words)].map((w) => {
|
|
109
109
|
const doc = getDoc?.(w)?.description;
|
|
110
110
|
return {
|
|
111
111
|
label: w,
|
|
@@ -115,7 +115,7 @@ const getCompletion = (words, kind, mt, { line, character }, extra, getDoc) => [
|
|
|
115
115
|
start: { line, character: character - mt.length },
|
|
116
116
|
end: { line, character },
|
|
117
117
|
},
|
|
118
|
-
newText: w +
|
|
118
|
+
newText: w + extra,
|
|
119
119
|
},
|
|
120
120
|
...doc && {
|
|
121
121
|
documentation: {
|
|
@@ -272,8 +272,7 @@ const partialParse = async (wikitext, watch, include, config = index_1.default.g
|
|
|
272
272
|
};
|
|
273
273
|
/* NOT FOR BROWSER ONLY */
|
|
274
274
|
/** @see https://www.npmjs.com/package/stylelint-config-recommended */
|
|
275
|
-
const cssRules = { 'block-no-empty': null }, sources = { 'invalid-css': 'css', 'invalid-math': 'texvc' }, jsonSelector = constants_2.jsonTags.map(s => `ext#${s}`).join(), scores = new Map();
|
|
276
|
-
let colors;
|
|
275
|
+
const cssRules = { 'block-no-empty': null }, colors = Object.keys(common_1.colorsNamed), sources = { 'invalid-css': 'css', 'invalid-math': 'texvc' }, jsonSelector = constants_2.jsonTags.map(s => `ext#${s}`).join(), scores = new Map();
|
|
277
276
|
/**
|
|
278
277
|
* Correct the position of an error.
|
|
279
278
|
* @param height
|
|
@@ -479,22 +478,9 @@ class LanguageService {
|
|
|
479
478
|
* 提供颜色指示
|
|
480
479
|
* @param rgba color parser / 颜色解析函数
|
|
481
480
|
* @param text source Wikitext / 源代码
|
|
482
|
-
* @param hsl whether HSL colors are treated / 是否允许HSL颜色
|
|
483
481
|
*/
|
|
484
|
-
async provideDocumentColors(rgba, text
|
|
482
|
+
async provideDocumentColors(rgba, text) {
|
|
485
483
|
const root = await this.#queue(text);
|
|
486
|
-
/* NOT FOR BROWSER ONLY */
|
|
487
|
-
if (colors === undefined) {
|
|
488
|
-
try {
|
|
489
|
-
const { default: colorName } = require('color-name');
|
|
490
|
-
colors = new RegExp(String.raw `\b${Object.keys(colorName).join('|')}\b`, 'giu');
|
|
491
|
-
}
|
|
492
|
-
catch {
|
|
493
|
-
/* c8 ignore next */
|
|
494
|
-
colors = false;
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
/* NOT FOR BROWSER ONLY END */
|
|
498
484
|
return root.querySelectorAll('attr-value,parameter-value,arg-default').reverse().flatMap(token => {
|
|
499
485
|
const { type, childNodes,
|
|
500
486
|
/* NOT FOR BROWSER ONLY */
|
|
@@ -509,15 +495,10 @@ class LanguageService {
|
|
|
509
495
|
/* NOT FOR BROWSER ONLY END */
|
|
510
496
|
}
|
|
511
497
|
/* NOT FOR BROWSER ONLY */
|
|
512
|
-
const isStyle =
|
|
498
|
+
const isStyle = type === 'attr-value' && parentNode.name === 'style';
|
|
513
499
|
/* NOT FOR BROWSER ONLY END */
|
|
514
500
|
return childNodes.filter((child) => child.type === 'text').reverse().flatMap(child => {
|
|
515
|
-
const { data } = child, parts = (0, common_1.splitColors)(data,
|
|
516
|
-
/* NOT FOR BROWSER ONLY */
|
|
517
|
-
if (isStyle) {
|
|
518
|
-
parts.push(...[...data.matchAll(colors)].map(({ index, 0: s }) => [s, index, index + s.length, true]));
|
|
519
|
-
}
|
|
520
|
-
/* NOT FOR BROWSER ONLY END */
|
|
501
|
+
const { data } = child, parts = (0, common_1.splitColors)(data, isStyle && colors).filter(([, , , isColor]) => isColor);
|
|
521
502
|
if (parts.length === 0) {
|
|
522
503
|
return [];
|
|
523
504
|
}
|
|
@@ -688,13 +669,8 @@ class LanguageService {
|
|
|
688
669
|
if (mt?.[7] !== undefined || type === 'image-parameter') { // image parameter
|
|
689
670
|
const index = root.indexFromPos(line, character), match = mt?.[7]?.trimStart()
|
|
690
671
|
?? this.#text.slice(cur.getAbsoluteIndex(), index).trimStart(), equal = this.#text[index] === '=';
|
|
691
|
-
return
|
|
692
|
-
|
|
693
|
-
.filter(({ label }) => !equal || !/[= ]$/u.test(label)),
|
|
694
|
-
...getCompletion(root.querySelectorAll('image-parameter#width')
|
|
695
|
-
.filter(token => token !== cur)
|
|
696
|
-
.map(width => width.text()), 'Unit', match, position),
|
|
697
|
-
];
|
|
672
|
+
return getCompletion(params, 'Property', match, position)
|
|
673
|
+
.filter(({ label }) => !equal || !/[= ]$/u.test(label));
|
|
698
674
|
}
|
|
699
675
|
else if (mt?.[8] !== undefined || type === 'attr-key') { // attribute key
|
|
700
676
|
const tag = mt?.[8]?.toLowerCase() ?? parentNode.tag, key = mt?.[10]
|
|
@@ -739,11 +715,11 @@ class LanguageService {
|
|
|
739
715
|
}).map(({ name }) => name), 'Variable', key, position, type === 'parameter-value' ? '=' : '')
|
|
740
716
|
: undefined;
|
|
741
717
|
}
|
|
742
|
-
else if (type === 'param-line') {
|
|
743
|
-
// parameter line of `<dynamicpagelist>` or `<
|
|
718
|
+
else if (type === 'param-line-key') {
|
|
719
|
+
// parameter line of `<dynamicpagelist>`, `<inputbox>` or `<seo>`
|
|
744
720
|
const key = this.#text.slice(cur.getAbsoluteIndex(), root.indexFromPos(line, character)).trimStart();
|
|
745
721
|
return /^[a-z]+$/iu.test(key)
|
|
746
|
-
? getCompletion(sharable_1.extParams[
|
|
722
|
+
? getCompletion(sharable_1.extParams[parentNode.name], 'Property', key, position)
|
|
747
723
|
: undefined;
|
|
748
724
|
/* NOT FOR BROWSER ONLY */
|
|
749
725
|
}
|
|
@@ -989,8 +965,8 @@ class LanguageService {
|
|
|
989
965
|
*/
|
|
990
966
|
async provideFoldingRanges(text) {
|
|
991
967
|
const root = await this.#queue(text), { length } = root.getLines(), ranges = [], levels = Array.from({ length: 6 }), tokens = root.querySelectorAll('heading-title,table,template,magic-word');
|
|
992
|
-
for (
|
|
993
|
-
|
|
968
|
+
for (let i = tokens.length - 1; i >= 0; i--) { // 提高 getBoundingClientRect 的性能
|
|
969
|
+
tokens[i].getRelativeIndex();
|
|
994
970
|
}
|
|
995
971
|
for (const token of tokens) {
|
|
996
972
|
const { offsetHeight } = token;
|
|
@@ -1225,7 +1201,7 @@ class LanguageService {
|
|
|
1225
1201
|
return undefined;
|
|
1226
1202
|
}
|
|
1227
1203
|
const { type } = node, refName = getRefName(node), refNameGroup = refName && node.parentNode.parentNode.getAttr('group'), refGroup = getRefGroup(node), name = getName(node), refs = root.querySelectorAll(type).filter(token => {
|
|
1228
|
-
const
|
|
1204
|
+
const t = token.parentNode.type;
|
|
1229
1205
|
if (type === 'link-target' && t !== 'link' && t !== 'redirect-target') {
|
|
1230
1206
|
return false;
|
|
1231
1207
|
}
|
|
@@ -1415,10 +1391,10 @@ class LanguageService {
|
|
|
1415
1391
|
* @since v1.16.3
|
|
1416
1392
|
*/
|
|
1417
1393
|
async provideInlayHints(text) {
|
|
1418
|
-
const root = await this.#queue(text);
|
|
1394
|
+
const root = await this.#queue(text), templates = root.querySelectorAll('template,magic-word#invoke');
|
|
1419
1395
|
let hints = [];
|
|
1420
|
-
for (
|
|
1421
|
-
const { type, childNodes } =
|
|
1396
|
+
for (let i = templates.length - 1; i >= 0; i--) {
|
|
1397
|
+
const { type, childNodes } = templates[i];
|
|
1422
1398
|
hints = [
|
|
1423
1399
|
...hints,
|
|
1424
1400
|
...childNodes.slice(type === 'template' ? 1 : 3).filter(({ anon }) => anon)
|
package/dist/lib/node.js
CHANGED
|
@@ -40,7 +40,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
40
40
|
exports.AstNode = void 0;
|
|
41
41
|
/* eslint-disable @typescript-eslint/no-base-to-string */
|
|
42
42
|
const common_1 = require("@bhsd/common");
|
|
43
|
-
const search_1 = __importDefault(require("../
|
|
43
|
+
const search_1 = __importDefault(require("../vendor/search"));
|
|
44
44
|
const lint_1 = require("../util/lint");
|
|
45
45
|
const debug_1 = require("../util/debug");
|
|
46
46
|
const cached_1 = require("../mixin/cached");
|
|
@@ -145,7 +145,7 @@ let AstNode = (() => {
|
|
|
145
145
|
* @param left column number / 列号
|
|
146
146
|
*/
|
|
147
147
|
indexFromPos(top, left) {
|
|
148
|
-
|
|
148
|
+
LSP: {
|
|
149
149
|
if (top < 0 || left < 0) {
|
|
150
150
|
return undefined;
|
|
151
151
|
}
|
package/dist/lib/text.js
CHANGED
|
@@ -16,7 +16,7 @@ const errorSyntaxUrl = /* #__PURE__ */ new RegExp(source, 'giu'), noLinkTypes =
|
|
|
16
16
|
'{': /[{}]/u,
|
|
17
17
|
']': /[[\]](?=[^[\]]*$)/u,
|
|
18
18
|
'}': /[{}](?=[^{}]*$)/u,
|
|
19
|
-
}, disallowedTags = new Set([
|
|
19
|
+
}, magic = new Set(['rfc', 'pmid', 'isbn']), disallowedTags = new Set([
|
|
20
20
|
'html',
|
|
21
21
|
'head',
|
|
22
22
|
'style',
|
|
@@ -136,7 +136,7 @@ class AstText extends node_1.AstNode {
|
|
|
136
136
|
error = error.slice(1);
|
|
137
137
|
}
|
|
138
138
|
error = error.toLowerCase();
|
|
139
|
-
const [char] = error, magicLink = error
|
|
139
|
+
const [char] = error, magicLink = magic.has(error), lbrace = char === '{', rbrace = char === '}', lbrack = char === '[', rbrack = char === ']';
|
|
140
140
|
let { length } = error;
|
|
141
141
|
if (rbrack && (index || length > 1)) {
|
|
142
142
|
errorRegex.lastIndex--;
|
package/dist/map.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RedirectToken, RedirectTargetToken, OnlyincludeToken, IncludeToken, CommentToken, ExtToken, AttributesToken, AttributeToken, AtomToken, ArgToken, TranscludeToken, SyntaxToken, ParameterToken, HeadingToken, HtmlToken, TableToken, TrToken, TdToken, DoubleUnderscoreToken, HrToken, LinkToken, CategoryToken, FileToken, ImageParameterToken, QuoteToken, ExtLinkToken, MagicLinkToken, ListToken, DdToken, ConverterToken, ConverterFlagsToken, ConverterRuleToken, TranslateToken, TvarToken, HiddenToken, GalleryImageToken, ParamLineToken, ImagemapLinkToken } from './internal';
|
|
1
|
+
import type { RedirectToken, RedirectTargetToken, OnlyincludeToken, IncludeToken, CommentToken, ExtToken, AttributesToken, AttributeToken, AtomToken, ArgToken, TranscludeToken, SyntaxToken, ParameterToken, HeadingToken, HtmlToken, TableToken, TrToken, TdToken, DoubleUnderscoreToken, HrToken, LinkToken, CategoryToken, FileToken, ImageParameterToken, QuoteToken, ExtLinkToken, MagicLinkToken, ListToken, DdToken, ConverterToken, ConverterFlagsToken, ConverterRuleToken, TranslateToken, TvarToken, HiddenToken, GalleryImageToken, ParamLineToken, ImagemapLinkToken, CharinsertLineToken } from './internal';
|
|
2
2
|
export interface TokenTypeMap {
|
|
3
3
|
redirect: RedirectToken;
|
|
4
4
|
'redirect-syntax': SyntaxToken;
|
|
@@ -60,6 +60,9 @@ export interface TokenTypeMap {
|
|
|
60
60
|
'converter-rule': ConverterRuleToken;
|
|
61
61
|
'converter-rule-variant': AtomToken;
|
|
62
62
|
'param-line': ParamLineToken;
|
|
63
|
+
'param-line-key': AtomToken;
|
|
64
|
+
'param-line-value': AtomToken;
|
|
63
65
|
'imagemap-link': ImagemapLinkToken;
|
|
66
|
+
'charinsert-line': CharinsertLineToken;
|
|
64
67
|
}
|
|
65
68
|
export type SelectedTokenTypes = keyof TokenTypeMap;
|
|
@@ -5,23 +5,23 @@ const debug_1 = require("../util/debug");
|
|
|
5
5
|
const selector_1 = require("../util/selector");
|
|
6
6
|
/** @ignore */
|
|
7
7
|
const elementLike = (constructor) => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
8
|
+
LINT: {
|
|
9
|
+
class ElementLike extends constructor {
|
|
10
|
+
#getCondition(selector) {
|
|
11
|
+
return (0, selector_1.getCondition)(selector, this);
|
|
12
|
+
}
|
|
13
|
+
closest(selector) {
|
|
14
|
+
const condition = this.#getCondition(selector);
|
|
15
|
+
let { parentNode } = this;
|
|
16
|
+
while (parentNode) {
|
|
17
|
+
if (condition(parentNode)) {
|
|
18
|
+
return parentNode;
|
|
19
|
+
}
|
|
20
|
+
({ parentNode } = parentNode);
|
|
18
21
|
}
|
|
19
|
-
|
|
22
|
+
return undefined;
|
|
20
23
|
}
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
getElementBy(condition) {
|
|
24
|
-
LINT: {
|
|
24
|
+
getElementBy(condition) {
|
|
25
25
|
const stack = [...this.childNodes].reverse();
|
|
26
26
|
while (stack.length > 0) {
|
|
27
27
|
const child = stack.pop(), { type, childNodes } = child;
|
|
@@ -37,12 +37,10 @@ const elementLike = (constructor) => {
|
|
|
37
37
|
}
|
|
38
38
|
return undefined;
|
|
39
39
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
getElementsBy(condition) {
|
|
45
|
-
LINT: {
|
|
40
|
+
querySelector(selector) {
|
|
41
|
+
return this.getElementBy(this.#getCondition(selector));
|
|
42
|
+
}
|
|
43
|
+
getElementsBy(condition) {
|
|
46
44
|
const stack = [...this.childNodes].reverse(), descendants = [];
|
|
47
45
|
while (stack.length > 0) {
|
|
48
46
|
const child = stack.pop(), { type, childNodes } = child;
|
|
@@ -58,19 +56,19 @@ const elementLike = (constructor) => {
|
|
|
58
56
|
}
|
|
59
57
|
return descendants;
|
|
60
58
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
59
|
+
querySelectorAll(selector) {
|
|
60
|
+
return this.getElementsBy(this.#getCondition(selector));
|
|
61
|
+
}
|
|
62
|
+
escape() {
|
|
63
|
+
LSP: {
|
|
64
|
+
for (const child of this.childNodes) {
|
|
65
|
+
child.escape();
|
|
66
|
+
}
|
|
69
67
|
}
|
|
70
68
|
}
|
|
71
69
|
}
|
|
70
|
+
(0, debug_1.mixin)(ElementLike, constructor);
|
|
71
|
+
return ElementLike;
|
|
72
72
|
}
|
|
73
|
-
(0, debug_1.mixin)(ElementLike, constructor);
|
|
74
|
-
return ElementLike;
|
|
75
73
|
};
|
|
76
74
|
exports.elementLike = elementLike;
|
package/dist/mixin/hidden.js
CHANGED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ParamLineToken } from '../src/paramLine';
|
|
2
|
+
export interface ParamLineParentBase {
|
|
3
|
+
/**
|
|
4
|
+
* Get all parameter keys
|
|
5
|
+
*
|
|
6
|
+
* 获取所有参数键
|
|
7
|
+
*/
|
|
8
|
+
getKeys(): Set<string>;
|
|
9
|
+
/**
|
|
10
|
+
* Get parameters with the specified key
|
|
11
|
+
*
|
|
12
|
+
* 获取指定参数
|
|
13
|
+
* @param key parameter key / 参数键
|
|
14
|
+
*/
|
|
15
|
+
getParams(key: string): ParamLineToken[];
|
|
16
|
+
/**
|
|
17
|
+
* Get duplicated parameters
|
|
18
|
+
*
|
|
19
|
+
* 获取重复参数
|
|
20
|
+
*/
|
|
21
|
+
getDuplicatedParams(): [string, ParamLineToken[]][];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 子节点为ParamLineToken的类
|
|
25
|
+
* @ignore
|
|
26
|
+
*/
|
|
@@ -0,0 +1,51 @@
|
|
|
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.paramLineParent = void 0;
|
|
7
|
+
const debug_1 = require("../util/debug");
|
|
8
|
+
const lint_1 = require("../util/lint");
|
|
9
|
+
const rect_1 = require("../lib/rect");
|
|
10
|
+
const index_1 = __importDefault(require("../index"));
|
|
11
|
+
/**
|
|
12
|
+
* 子节点为ParamLineToken的类
|
|
13
|
+
* @ignore
|
|
14
|
+
*/
|
|
15
|
+
const paramLineParent = (constructor) => {
|
|
16
|
+
LINT: {
|
|
17
|
+
class ParamLineParent extends constructor {
|
|
18
|
+
getKeys() {
|
|
19
|
+
return new Set(this.childNodes.map(({ key }) => key).filter((key) => key !== undefined));
|
|
20
|
+
}
|
|
21
|
+
getParams(key) {
|
|
22
|
+
return this.childNodes.filter(({ key: k }) => k === key);
|
|
23
|
+
}
|
|
24
|
+
getDuplicatedParams() {
|
|
25
|
+
return [...this.getKeys()].map((key) => [key, this.getParams(key)])
|
|
26
|
+
.filter(([, { length }]) => length > 1);
|
|
27
|
+
}
|
|
28
|
+
lint(start = this.getAbsoluteIndex()) {
|
|
29
|
+
const errors = super.lint(start), { name, firstChild } = this, rule = 'no-duplicate', { lintConfig } = index_1.default, s = lintConfig.getSeverity(rule, name);
|
|
30
|
+
if (s) {
|
|
31
|
+
const msg = index_1.default.msg('duplicate-ext-parameter', name), rect = new rect_1.BoundingRect(this, start), { computeEditInfo } = lintConfig;
|
|
32
|
+
for (const [, params] of this.getDuplicatedParams()) {
|
|
33
|
+
const duplication = Array.from({ length: params.length });
|
|
34
|
+
for (let i = params.length - 1; i >= 0; i--) {
|
|
35
|
+
const param = params[i], e = (0, lint_1.generateForChild)(param, rect, rule, msg, s);
|
|
36
|
+
if (computeEditInfo) {
|
|
37
|
+
e.suggestions = [(0, lint_1.fixByRemove)(e, param === firstChild ? 0 : -1)];
|
|
38
|
+
}
|
|
39
|
+
duplication[i] = e;
|
|
40
|
+
}
|
|
41
|
+
Array.prototype.push.apply(errors, duplication);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return errors;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
(0, debug_1.mixin)(ParamLineParent, constructor);
|
|
48
|
+
return ParamLineParent;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
exports.paramLineParent = paramLineParent;
|
package/dist/src/arg.js
CHANGED
|
@@ -38,7 +38,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
38
38
|
};
|
|
39
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
40
|
exports.ArgToken = void 0;
|
|
41
|
-
const string_1 = require("../util/string");
|
|
42
41
|
const lint_1 = require("../util/lint");
|
|
43
42
|
const rect_1 = require("../lib/rect");
|
|
44
43
|
const padded_1 = require("../mixin/padded");
|
|
@@ -99,11 +98,17 @@ let ArgToken = (() => {
|
|
|
99
98
|
}
|
|
100
99
|
/** @private */
|
|
101
100
|
text() {
|
|
102
|
-
|
|
101
|
+
// eslint-disable-next-line @typescript-eslint/no-useless-default-assignment
|
|
102
|
+
const { length, childNodes, name = this.#getName() } = this;
|
|
103
|
+
return length === 1 ? `{{{${name}}}}` : `{{{${name}|${childNodes[1].text()}}}}`;
|
|
104
|
+
}
|
|
105
|
+
/** 获取name */
|
|
106
|
+
#getName() {
|
|
107
|
+
return this.firstChild.text().trim();
|
|
103
108
|
}
|
|
104
109
|
/** 更新name */
|
|
105
110
|
#setName() {
|
|
106
|
-
LSP: this.setAttribute('name', this
|
|
111
|
+
LSP: this.setAttribute('name', this.#getName());
|
|
107
112
|
}
|
|
108
113
|
/** @private */
|
|
109
114
|
afterBuild() {
|
|
@@ -113,44 +118,21 @@ let ArgToken = (() => {
|
|
|
113
118
|
/** @private */
|
|
114
119
|
lint(start = this.getAbsoluteIndex(), re) {
|
|
115
120
|
LINT: {
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
argDefault.setAttribute('aIndex', index);
|
|
122
|
-
const childErrors = argDefault.lint(index, re);
|
|
123
|
-
if (childErrors.length > 0) {
|
|
124
|
-
Array.prototype.push.apply(errors, childErrors);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
const rules = ['no-ignored', 'no-arg'], { lintConfig } = index_1.default, { computeEditInfo } = lintConfig, rect = new rect_1.BoundingRect(this, start), s = rules.map(rule => lintConfig.getSeverity(rule, 'arg'));
|
|
128
|
-
if (s[0] && rest.length > 0) {
|
|
129
|
-
Array.prototype.push.apply(errors, rest.map(child => {
|
|
130
|
-
const e = (0, lint_1.generateForChild)(child, rect, rules[0], 'invisible-triple-braces', s[0]);
|
|
131
|
-
e.startIndex--;
|
|
132
|
-
e.startCol--;
|
|
133
|
-
if (computeEditInfo) {
|
|
134
|
-
e.suggestions = [
|
|
135
|
-
(0, lint_1.fixByRemove)(e),
|
|
136
|
-
(0, lint_1.fixByEscape)(e.startIndex, '{{!}}'),
|
|
137
|
-
];
|
|
138
|
-
}
|
|
139
|
-
return e;
|
|
140
|
-
}));
|
|
141
|
-
}
|
|
142
|
-
if (s[1] && !this.getAttribute('include')) {
|
|
143
|
-
const e = (0, lint_1.generateForSelf)(this, rect, rules[1], 'unexpected-argument', s[1]);
|
|
144
|
-
if (computeEditInfo && argDefault) {
|
|
121
|
+
const errors = super.lint(start, re), { lintConfig } = index_1.default, rect = new rect_1.BoundingRect(this, start);
|
|
122
|
+
let rule = 'no-arg', s = lintConfig.getSeverity(rule);
|
|
123
|
+
if (s && !this.getAttribute('include')) {
|
|
124
|
+
const e = (0, lint_1.generateForSelf)(this, rect, rule, 'unexpected-argument', s), [, argDefault] = this.childNodes;
|
|
125
|
+
if (lintConfig.computeEditInfo && argDefault) {
|
|
145
126
|
e.suggestions = [(0, lint_1.fixBy)(e, 'expand', argDefault.text())];
|
|
146
127
|
}
|
|
147
128
|
errors.push(e);
|
|
148
129
|
}
|
|
149
130
|
const ext = this.closest('ext');
|
|
150
131
|
if (ext) {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
132
|
+
rule = 'arg-in-ext';
|
|
133
|
+
s = lintConfig.getSeverity(rule, ext.name);
|
|
134
|
+
if (s) {
|
|
135
|
+
errors.push((0, lint_1.generateForSelf)(this, rect, rule, 'argument-in-ext', s));
|
|
154
136
|
}
|
|
155
137
|
}
|
|
156
138
|
return errors;
|
package/dist/src/atom.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Token } from './index';
|
|
2
2
|
import type { Config } from '../base';
|
|
3
|
-
declare const atomTypes: readonly ["arg-name", "attr-key", "attr-value", "ext-attr-dirty", "html-attr-dirty", "table-attr-dirty", "converter-flag", "converter-rule-variant", "invoke-function", "invoke-module", "template-name", "link-target"];
|
|
3
|
+
declare const atomTypes: readonly ["arg-name", "attr-key", "attr-value", "ext-attr-dirty", "html-attr-dirty", "table-attr-dirty", "converter-flag", "converter-rule-variant", "invoke-function", "invoke-module", "template-name", "link-target", "param-line-key", "param-line-value"];
|
|
4
4
|
declare type AtomTypes = typeof atomTypes[number];
|
|
5
5
|
/**
|
|
6
6
|
* plain Token that will not be parsed further
|
package/dist/src/atom.js
CHANGED
package/dist/src/attribute.js
CHANGED
|
@@ -14,7 +14,7 @@ const index_2 = require("./index");
|
|
|
14
14
|
const atom_1 = require("./atom");
|
|
15
15
|
/* NOT FOR BROWSER ONLY */
|
|
16
16
|
const document_1 = require("../lib/document");
|
|
17
|
-
const insecureStyle = /expression|(?:accelerator|-o-link(?:-source)?|-o-replace)\s*:|(?:url|src|image(?:-set)?)\s*\(|attr\s*\([^)]+[\s,]url/u, evil = /(?:^|\s|\*\/)(?:java|vb)script(?:\W|$)/iu, complexTypes = new Set(['ext', 'arg', 'magic-word', 'template']), urlAttrs = new Set([
|
|
17
|
+
const insecureStyle = /expression|(?:accelerator|-o-link(?:-source)?|-o-replace)\s*:|(?:url|src|image(?:-set)?)\s*\(|attr\s*\([^)]+[\s,]url/u, evil = /(?:^|\s|\*\/)(?:java|vb)script(?:\W|$)/iu, complexTypes = new Set(['ext', 'arg', 'magic-word', 'template']), itemAttrs = new Set(['itemtype', 'itemid', 'itemref']), urlAttrs = new Set([
|
|
18
18
|
'about',
|
|
19
19
|
'property',
|
|
20
20
|
'resource',
|
|
@@ -88,9 +88,13 @@ class AttributeToken extends index_2.Token {
|
|
|
88
88
|
this.#tag = tag;
|
|
89
89
|
this.setAttribute('name', (0, string_1.trimLc)((0, string_1.removeComment)(key)));
|
|
90
90
|
}
|
|
91
|
+
/** 获取name */
|
|
92
|
+
#getName() {
|
|
93
|
+
return (0, string_1.trimLc)(this.firstChild.text());
|
|
94
|
+
}
|
|
91
95
|
/** 更新name */
|
|
92
96
|
#setName() {
|
|
93
|
-
this.setAttribute('name',
|
|
97
|
+
this.setAttribute('name', this.#getName());
|
|
94
98
|
}
|
|
95
99
|
/** @private */
|
|
96
100
|
afterBuild() {
|
|
@@ -110,7 +114,9 @@ class AttributeToken extends index_2.Token {
|
|
|
110
114
|
}
|
|
111
115
|
/** @private */
|
|
112
116
|
text() {
|
|
113
|
-
|
|
117
|
+
// eslint-disable-next-line @typescript-eslint/no-useless-default-assignment
|
|
118
|
+
const { lastChild, name = this.#getName() } = this;
|
|
119
|
+
return this.#equal ? `${name}${this.#equal.trim()}"${lastChild.text()}"` : name;
|
|
114
120
|
}
|
|
115
121
|
/** @private */
|
|
116
122
|
getGaps() {
|
|
@@ -138,8 +144,7 @@ class AttributeToken extends index_2.Token {
|
|
|
138
144
|
// 或非通用HTML属性
|
|
139
145
|
|| !/^(?:xmlns:[\w:.-]+|data-(?!ooui|mw|parsoid)[^:_]*)$/u.test(name)
|
|
140
146
|
&& (tag === 'meta' || tag === 'link' || !sharable_1.commonHtmlAttrs.has(name)))
|
|
141
|
-
|| (name
|
|
142
|
-
&& !parentNode?.hasAttr('itemscope')) {
|
|
147
|
+
|| itemAttrs.has(name) && !parentNode?.hasAttr('itemscope')) {
|
|
143
148
|
LINT: {
|
|
144
149
|
const s = lintConfig.getSeverity(rule, 'unknown');
|
|
145
150
|
if (s) {
|
package/dist/src/attributes.js
CHANGED
|
@@ -124,10 +124,8 @@ class AttributesToken extends index_2.Token {
|
|
|
124
124
|
* @param key attribute name / 属性名
|
|
125
125
|
*/
|
|
126
126
|
getAttrToken(key) {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
return tokens[tokens.length - 1];
|
|
130
|
-
}
|
|
127
|
+
const tokens = this.getAttrTokens(key);
|
|
128
|
+
return tokens[tokens.length - 1];
|
|
131
129
|
}
|
|
132
130
|
/**
|
|
133
131
|
* Get the attribute
|
|
@@ -136,7 +134,7 @@ class AttributesToken extends index_2.Token {
|
|
|
136
134
|
* @param key attribute name / 属性键
|
|
137
135
|
*/
|
|
138
136
|
getAttr(key) {
|
|
139
|
-
|
|
137
|
+
return this.getAttrToken(key)?.getValue();
|
|
140
138
|
}
|
|
141
139
|
/** 是否位于闭合标签内 */
|
|
142
140
|
#lint() {
|
|
@@ -219,20 +217,24 @@ class AttributesToken extends index_2.Token {
|
|
|
219
217
|
const severity = lintConfig.getSeverity(rules[3], 'attribute');
|
|
220
218
|
if (severity && duplicated.size > 0) {
|
|
221
219
|
for (const key of duplicated) {
|
|
222
|
-
const pairs = attrs.get(key).map(attr => [attr, attr.getValue()]);
|
|
223
|
-
|
|
224
|
-
const e = (0, lint_1.generateForChild)(attr, rect, rules[3], index_1.default.msg('duplicate-attribute', key), severity);
|
|
220
|
+
const pairs = attrs.get(key).map(attr => [attr, attr.getValue()]), duplication = Array.from({ length: pairs.length }), values = new Set();
|
|
221
|
+
for (let i = pairs.length - 1; i >= 0; i--) {
|
|
222
|
+
const [attr, value] = pairs[i], e = (0, lint_1.generateForChild)(attr, rect, rules[3], index_1.default.msg('duplicate-attribute', key), severity);
|
|
225
223
|
if (computeEditInfo || fix) {
|
|
226
224
|
const remove = (0, lint_1.fixByRemove)(e);
|
|
227
|
-
if (!value ||
|
|
225
|
+
if (!value || values.has(value)) {
|
|
228
226
|
e.fix = remove;
|
|
229
227
|
}
|
|
230
|
-
else
|
|
231
|
-
|
|
228
|
+
else {
|
|
229
|
+
values.add(value);
|
|
230
|
+
if (computeEditInfo) {
|
|
231
|
+
e.suggestions = [remove];
|
|
232
|
+
}
|
|
232
233
|
}
|
|
233
234
|
}
|
|
234
|
-
|
|
235
|
-
}
|
|
235
|
+
duplication[i] = e;
|
|
236
|
+
}
|
|
237
|
+
Array.prototype.push.apply(errors, duplication);
|
|
236
238
|
}
|
|
237
239
|
}
|
|
238
240
|
return errors;
|
package/dist/src/commented.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import type { AstText, AttributesToken, ExtToken } from '../internal';
|
|
|
7
7
|
* @classdesc `{childNodes: (AstText|CommentToken)[]}`
|
|
8
8
|
*/
|
|
9
9
|
export declare abstract class CommentedToken extends Token {
|
|
10
|
+
readonly name: 'hiero';
|
|
10
11
|
readonly childNodes: readonly (CommentToken | AstText)[];
|
|
11
12
|
abstract get firstChild(): CommentToken | AstText | undefined;
|
|
12
13
|
abstract get lastChild(): CommentToken | AstText | undefined;
|
package/dist/src/commented.js
CHANGED
|
@@ -13,9 +13,7 @@ class CommentedToken extends index_1.Token {
|
|
|
13
13
|
}
|
|
14
14
|
/** @class */
|
|
15
15
|
constructor(wikitext, config, accum = []) {
|
|
16
|
-
super(undefined, config, accum, {
|
|
17
|
-
AstText: ':', CommentToken: ':',
|
|
18
|
-
});
|
|
16
|
+
super(undefined, config, accum, {});
|
|
19
17
|
if (wikitext) {
|
|
20
18
|
let i = wikitext.indexOf('<!--'), j = i !== -1 && wikitext.indexOf('-->', i + 4), lastIndex = 0;
|
|
21
19
|
while (j !== false && j !== -1) {
|
|
@@ -77,9 +77,13 @@ let ConverterFlagsToken = (() => {
|
|
|
77
77
|
super(undefined, config, accum, {});
|
|
78
78
|
this.safeAppend(flags.map(flag => new atom_1.AtomToken(flag, 'converter-flag', config, accum)));
|
|
79
79
|
}
|
|
80
|
+
/** 获取全部转换类型标记 */
|
|
81
|
+
#getFlags() {
|
|
82
|
+
return this.childNodes.map(child => child.text().trim());
|
|
83
|
+
}
|
|
80
84
|
/** @private */
|
|
81
85
|
afterBuild() {
|
|
82
|
-
this.#flags = this
|
|
86
|
+
this.#flags = this.#getFlags();
|
|
83
87
|
super.afterBuild();
|
|
84
88
|
}
|
|
85
89
|
/** @private */
|
|
@@ -88,7 +92,7 @@ let ConverterFlagsToken = (() => {
|
|
|
88
92
|
}
|
|
89
93
|
/** @private */
|
|
90
94
|
text() {
|
|
91
|
-
return
|
|
95
|
+
return (this.#flags ?? this.#getFlags()).join(';');
|
|
92
96
|
}
|
|
93
97
|
/**
|
|
94
98
|
* Get unknown language conversion flags
|
|
@@ -129,9 +133,9 @@ let ConverterFlagsToken = (() => {
|
|
|
129
133
|
}
|
|
130
134
|
const rule = 'no-ignored', s = lintConfig.getSeverity(rule, 'conversionFlag');
|
|
131
135
|
if (s) {
|
|
132
|
-
const rect = new rect_1.BoundingRect(this, start);
|
|
133
|
-
for (let i = 0; i <
|
|
134
|
-
const child =
|
|
136
|
+
const rect = new rect_1.BoundingRect(this, start), { childNodes, length } = this;
|
|
137
|
+
for (let i = 0; i < length; i++) {
|
|
138
|
+
const child = childNodes[i], flag = child.text().trim();
|
|
135
139
|
if (this.isInvalidFlag(flag, variantFlags, unknownFlags)) {
|
|
136
140
|
const e = (0, lint_1.generateForChild)(child, rect, rule, 'invalid-conversion-flag', s);
|
|
137
141
|
if (computeEditInfo || fix) {
|
|
@@ -109,8 +109,8 @@ let ConverterRuleToken = (() => {
|
|
|
109
109
|
text() {
|
|
110
110
|
const { childNodes, firstChild, lastChild } = this;
|
|
111
111
|
return childNodes.length === 3
|
|
112
|
-
? `${firstChild.text()}=>${childNodes[1].text()}:${lastChild.text()}`
|
|
113
|
-
:
|
|
112
|
+
? `${firstChild.text().trim()}=>${childNodes[1].text().trim()}:${lastChild.text().trim()}`
|
|
113
|
+
: childNodes.map(child => child.text().trim()).join(':');
|
|
114
114
|
}
|
|
115
115
|
/** @private */
|
|
116
116
|
getGaps(i) {
|