wikilint 2.5.0 → 2.5.1
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 -1
- package/config/enwiki.json +1 -1
- package/config/llwiki.json +1 -1
- package/config/minimum.json +3 -6
- package/config/zhwiki.json +1 -1
- package/dist/base.d.ts +3 -1
- package/dist/base.js +38 -0
- package/dist/index.js +2 -0
- package/dist/parser/list.js +24 -12
- package/dist/src/attribute.js +3 -2
- package/dist/src/html.d.ts +2 -0
- package/dist/src/html.js +8 -4
- package/dist/src/tagPair/include.js +7 -4
- package/dist/util/string.js +3 -2
- package/package.json +2 -2
package/config/default.json
CHANGED
|
@@ -767,7 +767,7 @@
|
|
|
767
767
|
"EXPECTED_UNCONNECTED_PAGE"
|
|
768
768
|
]
|
|
769
769
|
],
|
|
770
|
-
"protocol": "bitcoin:|ftp://|ftps://|geo:|git://|gopher://|http://|https://|irc://|ircs://|magnet:|mailto:|mms://|news:|nntp://|redis://|sftp://|sip:|sips:|sms:|ssh://|svn://|tel:|telnet://|urn:|worldwind://|xmpp:",
|
|
770
|
+
"protocol": "bitcoin:|ftp://|ftps://|geo:|git://|gopher://|http://|https://|irc://|ircs://|magnet:|mailto:|matrix:|mms://|news:|nntp://|redis://|sftp://|sip:|sips:|sms:|ssh://|svn://|tel:|telnet://|urn:|worldwind://|xmpp:",
|
|
771
771
|
"interwiki": [],
|
|
772
772
|
"img": {
|
|
773
773
|
"thumbnail": "thumbnail",
|
package/config/enwiki.json
CHANGED
|
@@ -369,7 +369,7 @@
|
|
|
369
369
|
"EXPECTED_UNCONNECTED_PAGE"
|
|
370
370
|
]
|
|
371
371
|
],
|
|
372
|
-
"protocol": "bitcoin:|ftp://|ftps://|geo:|git://|gopher://|http://|https://|irc://|ircs://|magnet:|mailto:|mms://|news:|nntp://|redis://|sftp://|sip:|sips:|sms:|ssh://|svn://|tel:|telnet://|urn:|worldwind://|xmpp:",
|
|
372
|
+
"protocol": "bitcoin:|ftp://|ftps://|geo:|git://|gopher://|http://|https://|irc://|ircs://|magnet:|mailto:|matrix:|mms://|news:|nntp://|redis://|sftp://|sip:|sips:|sms:|ssh://|svn://|tel:|telnet://|urn:|worldwind://|xmpp:",
|
|
373
373
|
"interwiki": [],
|
|
374
374
|
"img": {
|
|
375
375
|
"thumbnail": "thumbnail",
|
package/config/llwiki.json
CHANGED
|
@@ -518,7 +518,7 @@
|
|
|
518
518
|
"静态重定向"
|
|
519
519
|
]
|
|
520
520
|
],
|
|
521
|
-
"protocol": "bitcoin:|ftp://|ftps://|geo:|git://|gopher://|http://|https://|irc://|ircs://|magnet:|mailto:|mms://|news:|nntp://|redis://|sftp://|sip:|sips:|sms:|ssh://|svn://|tel:|telnet://|urn:|worldwind://|xmpp:",
|
|
521
|
+
"protocol": "bitcoin:|ftp://|ftps://|geo:|git://|gopher://|http://|https://|irc://|ircs://|magnet:|mailto:|matrix:|mms://|news:|nntp://|redis://|sftp://|sip:|sips:|sms:|ssh://|svn://|tel:|telnet://|urn:|worldwind://|xmpp:",
|
|
522
522
|
"interwiki": [],
|
|
523
523
|
"img": {
|
|
524
524
|
"thumbnail": "thumbnail",
|
package/config/minimum.json
CHANGED
|
@@ -66,8 +66,7 @@
|
|
|
66
66
|
"wbr",
|
|
67
67
|
"hr",
|
|
68
68
|
"meta",
|
|
69
|
-
"link"
|
|
70
|
-
"img"
|
|
69
|
+
"link"
|
|
71
70
|
]
|
|
72
71
|
],
|
|
73
72
|
"namespaces": {},
|
|
@@ -82,6 +81,7 @@
|
|
|
82
81
|
"#speciale": "speciale",
|
|
83
82
|
"#tag": "tag",
|
|
84
83
|
"#formatdate": "formatdate",
|
|
84
|
+
"#dateformat": "formatdate",
|
|
85
85
|
"#invoke": "invoke",
|
|
86
86
|
"#while": "while",
|
|
87
87
|
"#dowhile": "dowhile",
|
|
@@ -118,13 +118,10 @@
|
|
|
118
118
|
],
|
|
119
119
|
[
|
|
120
120
|
"msg",
|
|
121
|
-
"原始",
|
|
122
121
|
"raw"
|
|
123
122
|
],
|
|
124
123
|
[
|
|
125
|
-
"替代",
|
|
126
124
|
"subst",
|
|
127
|
-
"安全替代",
|
|
128
125
|
"safesubst"
|
|
129
126
|
]
|
|
130
127
|
],
|
|
@@ -132,7 +129,7 @@
|
|
|
132
129
|
[],
|
|
133
130
|
[]
|
|
134
131
|
],
|
|
135
|
-
"protocol": "bitcoin:|ftp://|ftps://|geo:|git://|gopher://|http://|https://|irc://|ircs://|magnet:|mailto:|mms://|news:|nntp://|redis://|sftp://|sip:|sips:|sms:|ssh://|svn://|tel:|telnet://|urn:|worldwind://|xmpp:",
|
|
132
|
+
"protocol": "bitcoin:|ftp://|ftps://|geo:|git://|gopher://|http://|https://|irc://|ircs://|magnet:|mailto:|matrix:|mms://|news:|nntp://|redis://|sftp://|sip:|sips:|sms:|ssh://|svn://|tel:|telnet://|urn:|worldwind://|xmpp:",
|
|
136
133
|
"interwiki": [],
|
|
137
134
|
"img": {},
|
|
138
135
|
"variants": []
|
package/config/zhwiki.json
CHANGED
|
@@ -707,7 +707,7 @@
|
|
|
707
707
|
"EXPECTED_UNCONNECTED_PAGE"
|
|
708
708
|
]
|
|
709
709
|
],
|
|
710
|
-
"protocol": "bitcoin:|ftp://|ftps://|geo:|git://|gopher://|http://|https://|irc://|ircs://|magnet:|mailto:|mms://|news:|nntp://|redis://|sftp://|sip:|sips:|sms:|ssh://|svn://|tel:|telnet://|urn:|worldwind://|xmpp:",
|
|
710
|
+
"protocol": "bitcoin:|ftp://|ftps://|geo:|git://|gopher://|http://|https://|irc://|ircs://|magnet:|mailto:|matrix:|mms://|news:|nntp://|redis://|sftp://|sip:|sips:|sms:|ssh://|svn://|tel:|telnet://|urn:|worldwind://|xmpp:",
|
|
711
711
|
"interwiki": [],
|
|
712
712
|
"img": {
|
|
713
713
|
"thumbnail": "thumbnail",
|
package/dist/base.d.ts
CHANGED
|
@@ -10,9 +10,10 @@ export interface Config {
|
|
|
10
10
|
readonly variants: string[];
|
|
11
11
|
readonly excludes?: string[];
|
|
12
12
|
}
|
|
13
|
+
export declare const rules: readonly ["bold-header", "format-leakage", "fostered-content", "h1", "illegal-attr", "insecure-style", "invalid-gallery", "invalid-imagemap", "invalid-invoke", "lonely-apos", "lonely-bracket", "lonely-http", "nested-link", "no-arg", "no-duplicate", "no-ignored", "obsolete-attr", "obsolete-tag", "parsing-order", "pipe-like", "table-layout", "tag-like", "unbalanced-header", "unclosed-comment", "unclosed-quote", "unclosed-table", "unescaped", "unknown-page", "unmatched-tag", "unterminated-url", "url-encoding", "var-anchor", "void-ext"];
|
|
13
14
|
export declare namespace LintError {
|
|
14
15
|
type Severity = 'error' | 'warning';
|
|
15
|
-
type Rule =
|
|
16
|
+
type Rule = typeof rules[number];
|
|
16
17
|
interface Fix {
|
|
17
18
|
readonly range: [number, number];
|
|
18
19
|
text: string;
|
|
@@ -46,6 +47,7 @@ interface AstElement extends AstNode {
|
|
|
46
47
|
export interface Parser {
|
|
47
48
|
config: string | Config;
|
|
48
49
|
i18n: string | Record<string, string> | undefined;
|
|
50
|
+
rules: readonly LintError.Rule[];
|
|
49
51
|
/** 获取解析设置 */
|
|
50
52
|
getConfig(): Config;
|
|
51
53
|
/**
|
package/dist/base.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rules = void 0;
|
|
4
|
+
exports.rules = [
|
|
5
|
+
'bold-header',
|
|
6
|
+
'format-leakage',
|
|
7
|
+
'fostered-content',
|
|
8
|
+
'h1',
|
|
9
|
+
'illegal-attr',
|
|
10
|
+
'insecure-style',
|
|
11
|
+
'invalid-gallery',
|
|
12
|
+
'invalid-imagemap',
|
|
13
|
+
'invalid-invoke',
|
|
14
|
+
'lonely-apos',
|
|
15
|
+
'lonely-bracket',
|
|
16
|
+
'lonely-http',
|
|
17
|
+
'nested-link',
|
|
18
|
+
'no-arg',
|
|
19
|
+
'no-duplicate',
|
|
20
|
+
'no-ignored',
|
|
21
|
+
'obsolete-attr',
|
|
22
|
+
'obsolete-tag',
|
|
23
|
+
'parsing-order',
|
|
24
|
+
'pipe-like',
|
|
25
|
+
'table-layout',
|
|
26
|
+
'tag-like',
|
|
27
|
+
'unbalanced-header',
|
|
28
|
+
'unclosed-comment',
|
|
29
|
+
'unclosed-quote',
|
|
30
|
+
'unclosed-table',
|
|
31
|
+
'unescaped',
|
|
32
|
+
'unknown-page',
|
|
33
|
+
'unmatched-tag',
|
|
34
|
+
'unterminated-url',
|
|
35
|
+
'url-encoding',
|
|
36
|
+
'var-anchor',
|
|
37
|
+
'void-ext',
|
|
38
|
+
];
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
/* eslint n/exports-style: 0 */
|
|
3
3
|
const fs = require("fs");
|
|
4
4
|
const path = require("path");
|
|
5
|
+
const base_1 = require("./base");
|
|
5
6
|
const debug_1 = require("./util/debug");
|
|
6
7
|
const constants_1 = require("./util/constants");
|
|
7
8
|
const string_1 = require("./util/string");
|
|
@@ -15,6 +16,7 @@ const rootRequire = (file, dir) => require(file.startsWith('/') ? file : `../${f
|
|
|
15
16
|
const Parser = {
|
|
16
17
|
config: 'default',
|
|
17
18
|
i18n: undefined,
|
|
19
|
+
rules: base_1.rules,
|
|
18
20
|
/** @implements */
|
|
19
21
|
getConfig() {
|
|
20
22
|
if (typeof this.config === 'string') {
|
package/dist/parser/list.js
CHANGED
|
@@ -22,7 +22,8 @@ const parseList = (wikitext, config = index_1.default.getConfig(), accum = []) =
|
|
|
22
22
|
if (!dt) {
|
|
23
23
|
return text;
|
|
24
24
|
}
|
|
25
|
-
|
|
25
|
+
const { html: [normalTags] } = config, fullRegex = /:+|-\{|\0\d+x\x7F/gu;
|
|
26
|
+
let regex = fullRegex, ex = regex.exec(text), lt = 0, lc = 0;
|
|
26
27
|
/**
|
|
27
28
|
* 创建`DdToken`
|
|
28
29
|
* @param syntax `:`
|
|
@@ -35,15 +36,7 @@ const parseList = (wikitext, config = index_1.default.getConfig(), accum = []) =
|
|
|
35
36
|
};
|
|
36
37
|
while (ex && dt) {
|
|
37
38
|
const { 0: syntax, index } = ex;
|
|
38
|
-
if (syntax
|
|
39
|
-
if (syntax.length >= dt) {
|
|
40
|
-
return dd(syntax.slice(0, dt), index);
|
|
41
|
-
}
|
|
42
|
-
dt -= syntax.length;
|
|
43
|
-
regex.lastIndex = index + 4 + String(accum.length).length;
|
|
44
|
-
text = dd(syntax, index);
|
|
45
|
-
}
|
|
46
|
-
else if (syntax === '-{') {
|
|
39
|
+
if (syntax === '-{') {
|
|
47
40
|
if (!lc) {
|
|
48
41
|
const { lastIndex } = regex;
|
|
49
42
|
regex = /-\{|\}-/gu;
|
|
@@ -51,14 +44,33 @@ const parseList = (wikitext, config = index_1.default.getConfig(), accum = []) =
|
|
|
51
44
|
}
|
|
52
45
|
lc++;
|
|
53
46
|
}
|
|
54
|
-
else {
|
|
47
|
+
else if (syntax === '}-') {
|
|
55
48
|
lc--;
|
|
56
49
|
if (!lc) {
|
|
57
50
|
const { lastIndex } = regex;
|
|
58
|
-
regex =
|
|
51
|
+
regex = fullRegex;
|
|
59
52
|
regex.lastIndex = lastIndex;
|
|
60
53
|
}
|
|
61
54
|
}
|
|
55
|
+
else if (syntax.startsWith('\0')) {
|
|
56
|
+
const { name, closing, selfClosing } = accum[Number(syntax.slice(1, -2))];
|
|
57
|
+
if (!selfClosing || normalTags.includes(name)) {
|
|
58
|
+
if (!closing) {
|
|
59
|
+
lt++;
|
|
60
|
+
}
|
|
61
|
+
else if (lt) {
|
|
62
|
+
lt--;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else if (lt === 0) { // syntax === ':'
|
|
67
|
+
if (syntax.length >= dt) {
|
|
68
|
+
return dd(syntax.slice(0, dt), index);
|
|
69
|
+
}
|
|
70
|
+
dt -= syntax.length;
|
|
71
|
+
regex.lastIndex = index + 4 + String(accum.length).length;
|
|
72
|
+
text = dd(syntax, index);
|
|
73
|
+
}
|
|
62
74
|
ex = regex.exec(text);
|
|
63
75
|
}
|
|
64
76
|
return text;
|
package/dist/src/attribute.js
CHANGED
|
@@ -20,6 +20,7 @@ const commonHtmlAttrs = new Set([
|
|
|
20
20
|
'aria-hidden',
|
|
21
21
|
'aria-label',
|
|
22
22
|
'aria-labelledby',
|
|
23
|
+
'aria-level',
|
|
23
24
|
'aria-owns',
|
|
24
25
|
'role',
|
|
25
26
|
'about',
|
|
@@ -145,7 +146,7 @@ const commonHtmlAttrs = new Set([
|
|
|
145
146
|
combobox: new Set(['placeholder', 'value', 'id', 'class', 'text', 'dropdown', 'style']),
|
|
146
147
|
}, insecureStyle = new RegExp('expression'
|
|
147
148
|
+ '|'
|
|
148
|
-
+ '(?:
|
|
149
|
+
+ '(?:accelerator|-o-link(?:-source)?|-o-replace)\\s*:'
|
|
149
150
|
+ '|'
|
|
150
151
|
+ '(?:url|image(?:-set)?)\\s*\\('
|
|
151
152
|
+ '|'
|
|
@@ -270,7 +271,7 @@ class AttributeToken extends index_2.Token {
|
|
|
270
271
|
if (lastChild.childNodes.some(child => child.type === 'text' && /\s/u.test(child.text()))) {
|
|
271
272
|
e.suggestions = [
|
|
272
273
|
{
|
|
273
|
-
desc: '
|
|
274
|
+
desc: 'close',
|
|
274
275
|
...fix,
|
|
275
276
|
},
|
|
276
277
|
];
|
package/dist/src/html.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ export declare abstract class HtmlToken extends Token {
|
|
|
13
13
|
readonly childNodes: readonly [AttributesToken];
|
|
14
14
|
abstract get firstChild(): AttributesToken;
|
|
15
15
|
abstract get lastChild(): AttributesToken;
|
|
16
|
+
/** 是否自封闭 */
|
|
17
|
+
get selfClosing(): boolean;
|
|
16
18
|
/** 是否是闭合标签 */
|
|
17
19
|
get closing(): boolean;
|
|
18
20
|
/**
|
package/dist/src/html.js
CHANGED
|
@@ -41,6 +41,10 @@ class HtmlToken extends index_2.Token {
|
|
|
41
41
|
#closing;
|
|
42
42
|
#selfClosing;
|
|
43
43
|
#tag;
|
|
44
|
+
/** 是否自封闭 */
|
|
45
|
+
get selfClosing() {
|
|
46
|
+
return this.#selfClosing;
|
|
47
|
+
}
|
|
44
48
|
/** 是否是闭合标签 */
|
|
45
49
|
get closing() {
|
|
46
50
|
return this.#closing;
|
|
@@ -163,14 +167,14 @@ class HtmlToken extends index_2.Token {
|
|
|
163
167
|
* @throws `SyntaxError` 未匹配的标签
|
|
164
168
|
*/
|
|
165
169
|
findMatchingTag() {
|
|
166
|
-
const { html } = this.getAttribute('config'), { name: tagName, parentNode, closing } = this, string = (0, string_1.noWrap)(String(this));
|
|
167
|
-
if (closing && (this.#selfClosing ||
|
|
170
|
+
const { html: [normalTags, flexibleTags, voidTags] } = this.getAttribute('config'), { name: tagName, parentNode, closing } = this, string = (0, string_1.noWrap)(String(this));
|
|
171
|
+
if (closing && (this.#selfClosing || voidTags.includes(tagName))) {
|
|
168
172
|
throw new SyntaxError(`tag that is both closing and self-closing: ${string}`);
|
|
169
173
|
}
|
|
170
|
-
else if (
|
|
174
|
+
else if (voidTags.includes(tagName) || this.#selfClosing && flexibleTags.includes(tagName)) { // 自封闭标签
|
|
171
175
|
return this;
|
|
172
176
|
}
|
|
173
|
-
else if (this.#selfClosing &&
|
|
177
|
+
else if (this.#selfClosing && normalTags.includes(tagName)) {
|
|
174
178
|
throw new SyntaxError(`invalid self-closing tag: ${string}`);
|
|
175
179
|
}
|
|
176
180
|
else if (!parentNode) {
|
|
@@ -26,10 +26,13 @@ class IncludeToken extends (0, hidden_1.hiddenToken)(index_2.TagPairToken) {
|
|
|
26
26
|
return [];
|
|
27
27
|
}
|
|
28
28
|
const e = (0, lint_1.generateForSelf)(this, { start }, 'unclosed-comment', index_1.default.msg('unclosed $1', `<${this.name}>`));
|
|
29
|
-
e.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
e.suggestions = [
|
|
30
|
+
{
|
|
31
|
+
desc: 'close',
|
|
32
|
+
range: [e.endIndex, e.endIndex],
|
|
33
|
+
text: `</${this.name}>`,
|
|
34
|
+
},
|
|
35
|
+
];
|
|
33
36
|
return [e];
|
|
34
37
|
}
|
|
35
38
|
}
|
package/dist/util/string.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.noWrap = exports.decodeHtml = exports.text = exports.escapeRegExp = exports.removeComment = exports.tidy = exports.extUrlChar = exports.extUrlCharFirst = void 0;
|
|
4
|
-
|
|
5
|
-
exports.
|
|
4
|
+
const commonExtUrlChar = '[^[\\]<>"\0-\x1F\x7F\\p{Zs}\uFFFD]';
|
|
5
|
+
exports.extUrlCharFirst = `(?:\\[[\\da-f:.]+\\]|${commonExtUrlChar})`;
|
|
6
|
+
exports.extUrlChar = `(?:${commonExtUrlChar}|\0\\d+[c!~]\x7F)*`;
|
|
6
7
|
/**
|
|
7
8
|
* 生成正则替换函数
|
|
8
9
|
* @param regex 正则表达式
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wikilint",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.1",
|
|
4
4
|
"description": "A Node.js linter for MediaWiki markup",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mediawiki",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
},
|
|
34
34
|
"scripts": {
|
|
35
35
|
"declaration": "grep -rl --include='*.d.ts' '@private' dist/ | xargs bash sed.sh -i -E '/^\\s+\\/\\*\\* @private/,+1d'; node ./dist/bin/declaration.js",
|
|
36
|
-
"prepublishOnly": "npm run build && rm dist/internal.js dist/
|
|
36
|
+
"prepublishOnly": "npm run build && rm dist/internal.js dist/[bmpu]*/*.d.ts",
|
|
37
37
|
"build": "bash build.sh",
|
|
38
38
|
"diff": "bash diff.sh",
|
|
39
39
|
"diff:stat": "f() { git diff --stat --ignore-all-space --color=always $1 $2 -- . ':!extensions/' ':!bin/' | grep '\\.ts'; }; f",
|