wikiparser-node 1.28.0 → 1.29.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/README.md +0 -2
- package/bundle/bundle-es8.min.js +25 -25
- package/bundle/bundle-lsp.min.js +30 -30
- package/bundle/bundle.min.js +24 -24
- package/config/default.json +15 -16
- package/config/jawiki.json +15 -16
- package/data/ext/ThirdPartyNotices.txt +33 -0
- package/data/ext/mapframe.json +489 -2
- package/dist/addon/magicWords.js +132 -0
- package/dist/addon/table.js +4 -4
- package/dist/addon/token.js +37 -126
- package/dist/addon/transclude.js +24 -30
- package/dist/base.d.mts +4 -2
- package/dist/base.d.ts +4 -2
- package/dist/base.js +2 -0
- package/dist/base.mjs +3 -1
- package/dist/bin/config.js +11 -11
- package/dist/index.d.ts +2 -1
- package/dist/index.js +27 -5
- package/dist/lib/document.d.ts +23 -7
- package/dist/lib/document.js +7 -27
- package/dist/lib/element.js +1 -1
- package/dist/lib/lintConfig.js +4 -0
- package/dist/lib/lsp.d.ts +1 -12
- package/dist/lib/lsp.js +45 -79
- package/dist/lib/node.js +25 -25
- package/dist/lib/range.js +2 -2
- package/dist/lib/title.d.ts +3 -1
- package/dist/lib/title.js +54 -33
- package/dist/mixin/elementLike.js +14 -9
- package/dist/parser/commentAndExt.js +34 -27
- package/dist/parser/hrAndDoubleUnderscore.js +9 -8
- package/dist/parser/links.js +4 -3
- package/dist/parser/redirect.js +1 -1
- package/dist/parser/selector.js +7 -9
- package/dist/src/arg.js +6 -9
- package/dist/src/attribute.js +37 -8
- package/dist/src/attributes.js +1 -1
- package/dist/src/converter.js +6 -3
- package/dist/src/converterRule.js +4 -6
- package/dist/src/extLink.js +3 -4
- package/dist/src/heading.js +1 -2
- package/dist/src/imageParameter.d.ts +4 -1
- package/dist/src/imageParameter.js +79 -26
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.js +21 -29
- package/dist/src/link/base.js +6 -8
- package/dist/src/link/file.js +10 -14
- package/dist/src/link/galleryImage.js +1 -1
- package/dist/src/link/redirectTarget.js +1 -1
- package/dist/src/magicLink.js +13 -3
- package/dist/src/multiLine/gallery.js +2 -2
- package/dist/src/multiLine/imagemap.js +3 -4
- package/dist/src/multiLine/paramTag.js +2 -2
- package/dist/src/nowiki/doubleUnderscore.d.ts +2 -1
- package/dist/src/nowiki/doubleUnderscore.js +9 -5
- package/dist/src/nowiki/index.js +58 -4
- package/dist/src/onlyinclude.js +2 -1
- package/dist/src/parameter.js +4 -6
- package/dist/src/redirect.js +2 -2
- package/dist/src/table/base.js +1 -2
- package/dist/src/table/index.js +3 -6
- package/dist/src/table/td.d.ts +2 -3
- package/dist/src/table/td.js +6 -6
- package/dist/src/table/trBase.js +1 -1
- package/dist/src/tag/html.js +3 -4
- package/dist/src/tag/tvar.js +1 -2
- package/dist/src/tagPair/ext.js +12 -5
- package/dist/src/tagPair/include.js +2 -2
- package/dist/src/tagPair/translate.js +2 -2
- package/dist/src/transclude.js +5 -5
- package/dist/util/constants.js +4 -1
- package/dist/util/debug.js +1 -1
- package/dist/util/html.js +13 -10
- package/dist/util/search.js +16 -0
- package/dist/util/sharable.js +27 -3
- package/dist/util/sharable.mjs +28 -4
- package/extensions/dist/base.js +1 -1
- package/i18n/en.json +4 -0
- package/i18n/zh-hans.json +4 -0
- package/i18n/zh-hant.json +4 -0
- package/package.json +9 -7
- package/data/ext/maplink.json +0 -4
package/dist/lib/title.js
CHANGED
|
@@ -9,6 +9,14 @@ const string_1 = require("../util/string");
|
|
|
9
9
|
/* NOT FOR BROWSER */
|
|
10
10
|
const constants_1 = require("../util/constants");
|
|
11
11
|
const index_1 = __importDefault(require("../index"));
|
|
12
|
+
/**
|
|
13
|
+
* 解析标题的路径
|
|
14
|
+
* @param title 标题
|
|
15
|
+
*/
|
|
16
|
+
const resolve = (title) => {
|
|
17
|
+
const [, { length }, sub] = /^((?:\.\.\/)*)([\s\S]*)/u.exec(title);
|
|
18
|
+
return [length / 3, sub];
|
|
19
|
+
};
|
|
12
20
|
/**
|
|
13
21
|
* title object of a MediaWiki page
|
|
14
22
|
*
|
|
@@ -20,6 +28,8 @@ class Title {
|
|
|
20
28
|
#path;
|
|
21
29
|
#ns;
|
|
22
30
|
#fragment;
|
|
31
|
+
/** @private */
|
|
32
|
+
page;
|
|
23
33
|
valid;
|
|
24
34
|
/** @private */
|
|
25
35
|
encoded = false;
|
|
@@ -115,9 +125,11 @@ class Title {
|
|
|
115
125
|
* @param opt.temporary 是否是临时标题
|
|
116
126
|
* @param opt.decode 是否需要解码
|
|
117
127
|
* @param opt.selfLink 是否允许selfLink
|
|
128
|
+
* @param opt.page 当前页面标题
|
|
118
129
|
*/
|
|
119
|
-
constructor(title, defaultNs, config, { temporary, decode, selfLink } = {}) {
|
|
120
|
-
|
|
130
|
+
constructor(title, defaultNs, config, { temporary, decode, selfLink, page } = {}) {
|
|
131
|
+
this.page = page;
|
|
132
|
+
const trimmed = title.trim(), subpage = trimmed.startsWith('../');
|
|
121
133
|
if (decode && title.includes('%')) {
|
|
122
134
|
try {
|
|
123
135
|
const encoded = /%(?!21|3[ce]|5[bd]|7[b-d])[\da-f]{2}/iu.test(title);
|
|
@@ -127,7 +139,7 @@ class Title {
|
|
|
127
139
|
catch { }
|
|
128
140
|
}
|
|
129
141
|
title = (0, string_1.decodeHtml)(title).replace(/[_ ]+/gu, ' ').trim();
|
|
130
|
-
if (subpage) {
|
|
142
|
+
if (subpage || page && trimmed.startsWith('/')) {
|
|
131
143
|
this.#ns = 0;
|
|
132
144
|
}
|
|
133
145
|
else {
|
|
@@ -165,11 +177,13 @@ class Title {
|
|
|
165
177
|
this.#fragment = fragment.replace(/ /gu, '_');
|
|
166
178
|
title = title.slice(0, i).trim();
|
|
167
179
|
}
|
|
180
|
+
const [level, sub] = subpage ? resolve(title) : [0, title];
|
|
168
181
|
this.valid = Boolean(title
|
|
169
182
|
|| this.interwiki
|
|
170
183
|
|| selfLink && this.ns === 0 && this.#fragment !== undefined)
|
|
171
184
|
&& (0, string_1.decodeHtml)(title) === title
|
|
172
|
-
&&
|
|
185
|
+
&& (level === 0 || page === undefined || page.split('/', level + 1).length > level)
|
|
186
|
+
&& !/^:|\0\d+[eh!+-]\x7F|[<>[\]{}|\n]|%[\da-f]{2}|(?:^|\/)\.{1,2}(?:$|\/)/iu.test(sub);
|
|
173
187
|
this.main = title;
|
|
174
188
|
this.#namespaces = config.namespaces;
|
|
175
189
|
this.#path = config.articlePath || '/wiki/$1';
|
|
@@ -187,6 +201,33 @@ class Title {
|
|
|
187
201
|
});
|
|
188
202
|
}
|
|
189
203
|
}
|
|
204
|
+
/**
|
|
205
|
+
* 生成标题
|
|
206
|
+
* @param prefix 前缀
|
|
207
|
+
*/
|
|
208
|
+
#getTitle(prefix) {
|
|
209
|
+
let title = (prefix + this.main).replace(/ /gu, '_');
|
|
210
|
+
if (title.startsWith('/')) {
|
|
211
|
+
title = (this.page ?? '') + title.replace(/(.)\/$/u, '$1');
|
|
212
|
+
}
|
|
213
|
+
else if (title.startsWith('../') && this.page?.includes('/')) {
|
|
214
|
+
const [level, sub] = resolve(title), dirs = this.page.split('/');
|
|
215
|
+
if (dirs.length > level) {
|
|
216
|
+
title = dirs.slice(0, -level).join('/') + (sub && '/') + sub;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/* NOT FOR BROWSER */
|
|
220
|
+
const media = title.startsWith('Media:');
|
|
221
|
+
let redirected = this.redirects.get(media ? `File:${title.slice(6)}` : title);
|
|
222
|
+
if (redirected) {
|
|
223
|
+
const hash = redirected.indexOf('#');
|
|
224
|
+
this.#redirectFragment = hash === -1 ? undefined : redirected.slice(hash + 1);
|
|
225
|
+
redirected = hash === -1 ? redirected : redirected.slice(0, hash);
|
|
226
|
+
return [true, media ? redirected.replace(/^File:/u, 'Media:') : redirected];
|
|
227
|
+
}
|
|
228
|
+
/* NOT FOR BROWSER */
|
|
229
|
+
return [false, title];
|
|
230
|
+
}
|
|
190
231
|
/**
|
|
191
232
|
* Check if the title is a redirect
|
|
192
233
|
*
|
|
@@ -194,22 +235,20 @@ class Title {
|
|
|
194
235
|
* @since v1.12.2
|
|
195
236
|
*/
|
|
196
237
|
getRedirection() {
|
|
197
|
-
const prefix
|
|
198
|
-
this.prefix;
|
|
199
|
-
let title = (prefix + this.main).replace(/ /gu, '_');
|
|
238
|
+
const { prefix,
|
|
200
239
|
/* NOT FOR BROWSER */
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
240
|
+
main, interwiki, } = this, pre = interwiki + (interwiki && ':') + // eslint-disable-line @stylistic/operator-linebreak
|
|
241
|
+
prefix, result = this.#getTitle(pre);
|
|
242
|
+
/* NOT FOR BROWSER */
|
|
243
|
+
if (result[0]) {
|
|
244
|
+
return result;
|
|
204
245
|
}
|
|
205
246
|
this.autoConvert();
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
if (redirected) {
|
|
209
|
-
return [true, redirected];
|
|
247
|
+
if (this.main !== main) {
|
|
248
|
+
return this.#getTitle(pre);
|
|
210
249
|
}
|
|
211
250
|
/* NOT FOR BROWSER END */
|
|
212
|
-
return
|
|
251
|
+
return result;
|
|
213
252
|
}
|
|
214
253
|
/** @private */
|
|
215
254
|
setFragment(fragment) {
|
|
@@ -250,24 +289,6 @@ class Title {
|
|
|
250
289
|
? ''
|
|
251
290
|
: `#${this.#fragment ?? this.#redirectFragment}`);
|
|
252
291
|
}
|
|
253
|
-
/**
|
|
254
|
-
* 处理重定向
|
|
255
|
-
* @param title 原标题
|
|
256
|
-
*/
|
|
257
|
-
#redirect(title) {
|
|
258
|
-
const media = title.startsWith('Media:');
|
|
259
|
-
if (media) {
|
|
260
|
-
title = `File:${title.slice(6)}`;
|
|
261
|
-
}
|
|
262
|
-
const redirected = this.redirects.get(title);
|
|
263
|
-
if (redirected) {
|
|
264
|
-
const hash = redirected.indexOf('#');
|
|
265
|
-
title = hash === -1 ? redirected : redirected.slice(0, hash);
|
|
266
|
-
this.#redirectFragment = hash === -1 ? undefined : redirected.slice(hash + 1);
|
|
267
|
-
return media ? title.replace(/^File:/u, 'Media:') : title;
|
|
268
|
-
}
|
|
269
|
-
return '';
|
|
270
|
-
}
|
|
271
292
|
/**
|
|
272
293
|
* Perform unidirectional language conversion
|
|
273
294
|
*
|
|
@@ -33,16 +33,17 @@ const elementLike = (constructor) => {
|
|
|
33
33
|
this);
|
|
34
34
|
}
|
|
35
35
|
getElementBy(condition) {
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
const stack = [...this.childNodes].reverse();
|
|
37
|
+
while (stack.length > 0) {
|
|
38
|
+
const child = stack.pop(), { type, childNodes } = child;
|
|
39
|
+
if (type === 'text') {
|
|
38
40
|
continue;
|
|
39
41
|
}
|
|
40
42
|
else if (condition(child)) {
|
|
41
43
|
return child;
|
|
42
44
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
return descendant;
|
|
45
|
+
for (let i = childNodes.length - 1; i >= 0; i--) {
|
|
46
|
+
stack.push(childNodes[i]);
|
|
46
47
|
}
|
|
47
48
|
}
|
|
48
49
|
return undefined;
|
|
@@ -50,15 +51,19 @@ const elementLike = (constructor) => {
|
|
|
50
51
|
querySelector(selector) {
|
|
51
52
|
return this.getElementBy(this.#getCondition(selector));
|
|
52
53
|
}
|
|
53
|
-
getElementsBy(condition
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
getElementsBy(condition) {
|
|
55
|
+
const stack = [...this.childNodes].reverse(), descendants = [];
|
|
56
|
+
while (stack.length > 0) {
|
|
57
|
+
const child = stack.pop(), { type, childNodes } = child;
|
|
58
|
+
if (type === 'text') {
|
|
56
59
|
continue;
|
|
57
60
|
}
|
|
58
61
|
else if (condition(child)) {
|
|
59
62
|
descendants.push(child);
|
|
60
63
|
}
|
|
61
|
-
|
|
64
|
+
for (let i = childNodes.length - 1; i >= 0; i--) {
|
|
65
|
+
stack.push(childNodes[i]);
|
|
66
|
+
}
|
|
62
67
|
}
|
|
63
68
|
return descendants;
|
|
64
69
|
}
|
|
@@ -12,11 +12,11 @@ const comment_1 = require("../src/nowiki/comment");
|
|
|
12
12
|
/* NOT FOR BROWSER */
|
|
13
13
|
const constants_1 = require("../util/constants");
|
|
14
14
|
/* NOT FOR BROWSER END */
|
|
15
|
-
const onlyincludeLeft = '<onlyinclude>', onlyincludeRight = '</onlyinclude>', { length } = onlyincludeLeft,
|
|
15
|
+
const onlyincludeLeft = '<onlyinclude>', onlyincludeRight = '</onlyinclude>', { length } = onlyincludeLeft, getExtRegex = [false, true].map(includeOnly => {
|
|
16
16
|
const noincludeRegex = includeOnly ? 'includeonly' : '(?:no|only)include', includeRegex = includeOnly ? 'noinclude' : 'includeonly';
|
|
17
17
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
18
18
|
/<!--[\s\S]*?(?:-->|$)|<foo(?:\s[^>]*)?\/?>|<\/foo\s*>|<(bar)(\s[^>]*?)?(?:\/>|>([\s\S]*?)<\/(\1\s*)>)|<(baz)(\s[^>]*?)?(?:\/>|>([\s\S]*?)(?:<\/(baz\s*)>|$))/giu;
|
|
19
|
-
return (0, common_1.
|
|
19
|
+
return (0, common_1.getRegex)(exts => new RegExp(String.raw `<!--[\s\S]*?(?:-->|$)|<${noincludeRegex}(?:\s[^>]*)?/?>|</${noincludeRegex}\s*>|<(${exts // eslint-disable-next-line unicorn/prefer-string-raw
|
|
20
20
|
})(\s[^>]*?)?(?:/>|>([\s\S]*?)</(${'\\1'}\s*)>)|<(${includeRegex})(\s[^>]*?)?(?:/>|>([\s\S]*?)(?:</(${includeRegex}\s*)>|$))`, 'giu'));
|
|
21
21
|
});
|
|
22
22
|
/**
|
|
@@ -64,8 +64,11 @@ const parseCommentAndExt = (wikitext, config, accum, includeOnly) => {
|
|
|
64
64
|
return str;
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
-
const { ext } = config
|
|
67
|
+
const { ext } = config;
|
|
68
|
+
let newExt = ext, newConfig = config;
|
|
68
69
|
if (ext.includes('translate')) {
|
|
70
|
+
newExt = ext.filter(e => e !== 'translate' && e !== 'tvar');
|
|
71
|
+
newConfig = { ...config, ext: newExt };
|
|
69
72
|
const stack = [];
|
|
70
73
|
wikitext = wikitext.replace(/<nowiki>[\s\S]*?<\/nowiki>/giu, m => {
|
|
71
74
|
stack.push(m);
|
|
@@ -78,30 +81,34 @@ const parseCommentAndExt = (wikitext, config, accum, includeOnly) => {
|
|
|
78
81
|
});
|
|
79
82
|
wikitext = (0, string_1.restore)(wikitext, stack);
|
|
80
83
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
84
|
+
const re = getExtRegex[includeOnly ? 1 : 0](newExt.join('|'));
|
|
85
|
+
re.lastIndex = 0;
|
|
86
|
+
return re.test(wikitext)
|
|
87
|
+
? wikitext.replace(re, (substr, name, attr, inner, closing, include, includeAttr, includeInner, includeClosing) => {
|
|
88
|
+
const l = accum.length;
|
|
89
|
+
let ch = 'n';
|
|
90
|
+
if (name) {
|
|
91
|
+
ch = 'e';
|
|
92
|
+
// @ts-expect-error abstract class
|
|
93
|
+
new ext_1.ExtToken(name, attr, inner, closing, newConfig, include, accum);
|
|
94
|
+
}
|
|
95
|
+
else if (substr.startsWith('<!--')) {
|
|
96
|
+
ch = 'c';
|
|
97
|
+
const closed = substr.endsWith('-->');
|
|
98
|
+
// @ts-expect-error abstract class
|
|
99
|
+
new comment_1.CommentToken((0, string_1.restore)(substr, accum, 1).slice(4, closed ? -3 : undefined), closed, config, accum);
|
|
100
|
+
}
|
|
101
|
+
else if (include) {
|
|
102
|
+
// @ts-expect-error abstract class
|
|
103
|
+
new include_1.IncludeToken(include, includeAttr && (0, string_1.restore)(includeAttr, accum, 1), includeInner && (0, string_1.restore)(includeInner, accum, 1), includeClosing, config, accum);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
// @ts-expect-error abstract class
|
|
107
|
+
new noinclude_1.NoincludeToken(substr, config, accum, true);
|
|
108
|
+
}
|
|
109
|
+
return `\0${l}${ch}\x7F`;
|
|
110
|
+
})
|
|
111
|
+
: wikitext;
|
|
105
112
|
};
|
|
106
113
|
exports.parseCommentAndExt = parseCommentAndExt;
|
|
107
114
|
constants_1.parsers['parseCommentAndExt'] = __filename;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseHrAndDoubleUnderscore = void 0;
|
|
4
|
+
const cm_util_1 = require("@bhsd/cm-util");
|
|
4
5
|
const hr_1 = require("../src/nowiki/hr");
|
|
5
6
|
const doubleUnderscore_1 = require("../src/nowiki/doubleUnderscore");
|
|
6
7
|
const heading_1 = require("../src/heading");
|
|
@@ -14,11 +15,11 @@ const constants_1 = require("../util/constants");
|
|
|
14
15
|
* @param accum
|
|
15
16
|
*/
|
|
16
17
|
const parseHrAndDoubleUnderscore = ({ firstChild: { data }, type, name }, config, accum) => {
|
|
17
|
-
const { doubleUnderscore: [insensitive, sensitive, aliases] } = config;
|
|
18
|
-
config.insensitiveDoubleUnderscore ??= new Set(insensitive);
|
|
19
|
-
config.sensitiveDoubleUnderscore ??= new Set(sensitive);
|
|
20
|
-
/__(toc|notoc)__/giu; // eslint-disable-line @typescript-eslint/no-unused-expressions
|
|
21
|
-
config.regexHrAndDoubleUnderscore ??= new RegExp(`__(${
|
|
18
|
+
const { doubleUnderscore: [insensitive, sensitive, aliases] } = config, all = [...insensitive, ...sensitive];
|
|
19
|
+
config.insensitiveDoubleUnderscore ??= new Set(insensitive.filter(cm_util_1.isUnderscore));
|
|
20
|
+
config.sensitiveDoubleUnderscore ??= new Set(sensitive.filter(cm_util_1.isUnderscore));
|
|
21
|
+
/__(toc|notoc)__|_{2}(目次)_{2}/giu; // eslint-disable-line @typescript-eslint/no-unused-expressions
|
|
22
|
+
config.regexHrAndDoubleUnderscore ??= new RegExp(`__(${all.filter(cm_util_1.isUnderscore).join('|')})__|_{2}(${all.filter(s => !(0, cm_util_1.isUnderscore)(s)).map(s => s.slice(2, -2)).join('|')})_{2}`, 'giu');
|
|
22
23
|
if (type !== 'root' && (type !== 'ext-inner' || name !== 'poem')) {
|
|
23
24
|
data = `\0${data}`;
|
|
24
25
|
}
|
|
@@ -26,11 +27,11 @@ const parseHrAndDoubleUnderscore = ({ firstChild: { data }, type, name }, config
|
|
|
26
27
|
// @ts-expect-error abstract class
|
|
27
28
|
new hr_1.HrToken(m, config, accum);
|
|
28
29
|
return `${lead}\0${accum.length - 1}r\x7F`;
|
|
29
|
-
}).replace(config.regexHrAndDoubleUnderscore, (m, p1) => {
|
|
30
|
-
const caseSensitive = config.sensitiveDoubleUnderscore.has(
|
|
30
|
+
}).replace(config.regexHrAndDoubleUnderscore, (m, p1, p2) => {
|
|
31
|
+
const key = p1 ?? p2, caseSensitive = config.sensitiveDoubleUnderscore.has(key), lc = key.toLowerCase(), caseInsensitive = config.insensitiveDoubleUnderscore.has(lc);
|
|
31
32
|
if (caseSensitive || caseInsensitive) {
|
|
32
33
|
// @ts-expect-error abstract class
|
|
33
|
-
new doubleUnderscore_1.DoubleUnderscoreToken(
|
|
34
|
+
new doubleUnderscore_1.DoubleUnderscoreToken(key, caseSensitive, Boolean(p2), config, accum);
|
|
34
35
|
return `\0${accum.length - 1}${caseInsensitive && (aliases?.[lc] ?? /* istanbul ignore next */ lc) === 'toc' ? 'u' : 'n'}\x7F`;
|
|
35
36
|
}
|
|
36
37
|
return m;
|
package/dist/parser/links.js
CHANGED
|
@@ -20,9 +20,10 @@ const regexImg = /^((?:(?!\0\d+!\x7F)[^\n[\]{}|])+)(\||\0\d+!\x7F)([\s\S]*)$/u;
|
|
|
20
20
|
* @param wikitext
|
|
21
21
|
* @param config
|
|
22
22
|
* @param accum
|
|
23
|
+
* @param page 页面名称
|
|
23
24
|
* @param tidy 是否整理链接
|
|
24
25
|
*/
|
|
25
|
-
const parseLinks = (wikitext, config, accum, tidy) => {
|
|
26
|
+
const parseLinks = (wikitext, config, accum, page, tidy) => {
|
|
26
27
|
/^\s*(?:ftp:\/\/|\/\/)/iu; // eslint-disable-line @typescript-eslint/no-unused-expressions
|
|
27
28
|
config.regexLinks ??= new RegExp(String.raw `^\s*(?:${config.protocol}|//)`, 'iu');
|
|
28
29
|
const regex = config.inExt
|
|
@@ -59,7 +60,7 @@ const parseLinks = (wikitext, config, accum, tidy) => {
|
|
|
59
60
|
}
|
|
60
61
|
const { ns, valid,
|
|
61
62
|
/* NOT FOR BROWSER */
|
|
62
|
-
interwiki, } = index_1.default.normalizeTitle(trimmed, 0, false, config, { halfParsed: true, temporary: true, decode: true, selfLink: true });
|
|
63
|
+
interwiki, } = index_1.default.normalizeTitle(trimmed, 0, false, config, { halfParsed: true, temporary: true, decode: true, selfLink: true, page });
|
|
63
64
|
if (!valid) {
|
|
64
65
|
s += `[[${x}`;
|
|
65
66
|
continue;
|
|
@@ -87,7 +88,7 @@ const parseLinks = (wikitext, config, accum, tidy) => {
|
|
|
87
88
|
break;
|
|
88
89
|
}
|
|
89
90
|
}
|
|
90
|
-
text = (0, exports.parseLinks)(text, config, accum, tidy);
|
|
91
|
+
text = (0, exports.parseLinks)(text, config, accum, page, tidy);
|
|
91
92
|
if (!found) {
|
|
92
93
|
s += `[[${link}${delimiter}${text}`;
|
|
93
94
|
continue;
|
package/dist/parser/redirect.js
CHANGED
|
@@ -21,7 +21,7 @@ const parseRedirect = (text, config, accum) => {
|
|
|
21
21
|
config.regexRedirect ??= new RegExp(String.raw `^(\s*)((?:${config.redirection.join('|')})\s*(?::\s*)?)\[\[([^\n|\]]+)(\|.*?)?\]\](\s*)`, 'iu');
|
|
22
22
|
const mt = config.regexRedirect.exec(text);
|
|
23
23
|
if (mt
|
|
24
|
-
&& index_1.default.normalizeTitle(mt[3], 0, false, config, { halfParsed: true, temporary: true, decode: true }).valid) {
|
|
24
|
+
&& index_1.default.normalizeTitle(mt[3], 0, false, config, { halfParsed: true, temporary: true, decode: true, page: '' }).valid) {
|
|
25
25
|
text = `\0${accum.length}o\x7F${text.slice(mt[0].length)}`;
|
|
26
26
|
// @ts-expect-error abstract class
|
|
27
27
|
new redirect_1.RedirectToken(...mt.slice(1), config, accum);
|
package/dist/parser/selector.js
CHANGED
|
@@ -10,15 +10,13 @@ const attributes_1 = require("../lib/attributes");
|
|
|
10
10
|
/**
|
|
11
11
|
* type和name选择器
|
|
12
12
|
* @param selector
|
|
13
|
-
* @param type
|
|
14
|
-
* @param name
|
|
15
13
|
*/
|
|
16
|
-
const basic = (selector
|
|
14
|
+
const basic = (selector) => {
|
|
17
15
|
if (selector.includes('#')) {
|
|
18
|
-
const i = selector.indexOf('#');
|
|
19
|
-
return (i === 0 ||
|
|
16
|
+
const i = selector.indexOf('#'), targetType = selector.slice(0, i), targetName = selector.slice(i + 1);
|
|
17
|
+
return (type, name) => (i === 0 || type === targetType) && name === targetName;
|
|
20
18
|
}
|
|
21
|
-
return
|
|
19
|
+
return selector ? (type) => type === selector : () => true;
|
|
22
20
|
};
|
|
23
21
|
/* NOT FOR BROWSER */
|
|
24
22
|
const simplePseudos = new Set([
|
|
@@ -174,7 +172,7 @@ const matches = (token, step, scope, has) => {
|
|
|
174
172
|
}
|
|
175
173
|
return token === scope;
|
|
176
174
|
default:
|
|
177
|
-
return basic(selector
|
|
175
|
+
return basic(selector)(type, name);
|
|
178
176
|
}
|
|
179
177
|
}
|
|
180
178
|
else if (selector.length === 4) { // 情形2:属性选择器
|
|
@@ -460,8 +458,8 @@ const getCondition = (selector, scope, has) => {
|
|
|
460
458
|
return checkToken(selector, scope, has);
|
|
461
459
|
}
|
|
462
460
|
/* NOT FOR BROWSER END */
|
|
463
|
-
const parts = selector.split(',');
|
|
464
|
-
return (({ type, name }) => parts.some(
|
|
461
|
+
const parts = selector.split(',').map(str => basic(str.trim()));
|
|
462
|
+
return (({ type, name }) => parts.some(condition => condition(type, name)));
|
|
465
463
|
};
|
|
466
464
|
exports.getCondition = getCondition;
|
|
467
465
|
constants_1.parsers['parseSelector'] = __filename;
|
package/dist/src/arg.js
CHANGED
|
@@ -158,13 +158,12 @@ let ArgToken = (() => {
|
|
|
158
158
|
argDefault.setAttribute('aIndex', index);
|
|
159
159
|
const childErrors = argDefault.lint(index, re);
|
|
160
160
|
if (childErrors.length > 0) {
|
|
161
|
-
|
|
161
|
+
Array.prototype.push.apply(errors, childErrors);
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
|
-
const rules = ['no-ignored', 'no-arg'], { lintConfig } = index_1.default, { computeEditInfo } = lintConfig, s = rules.map(rule => lintConfig.getSeverity(rule, 'arg'));
|
|
164
|
+
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'));
|
|
165
165
|
if (s[0] && rest.length > 0) {
|
|
166
|
-
|
|
167
|
-
errors.push(...rest.map(child => {
|
|
166
|
+
Array.prototype.push.apply(errors, rest.map(child => {
|
|
168
167
|
const e = (0, lint_1.generateForChild)(child, rect, rules[0], 'invisible-triple-braces', s[0]);
|
|
169
168
|
e.startIndex--;
|
|
170
169
|
e.startCol--;
|
|
@@ -178,7 +177,7 @@ let ArgToken = (() => {
|
|
|
178
177
|
}));
|
|
179
178
|
}
|
|
180
179
|
if (s[1] && !this.getAttribute('include')) {
|
|
181
|
-
const e = (0, lint_1.generateForSelf)(this,
|
|
180
|
+
const e = (0, lint_1.generateForSelf)(this, rect, rules[1], 'unexpected-argument', s[1]);
|
|
182
181
|
if (computeEditInfo && argDefault) {
|
|
183
182
|
e.suggestions = [(0, lint_1.fixBy)(e, 'expand', argDefault.text())];
|
|
184
183
|
}
|
|
@@ -261,8 +260,7 @@ let ArgToken = (() => {
|
|
|
261
260
|
* @param name new argument name / 新参数名
|
|
262
261
|
*/
|
|
263
262
|
setName(name) {
|
|
264
|
-
const { childNodes } = index_1.default
|
|
265
|
-
.parse(name, this.getAttribute('include'), 2, this.getAttribute('config'));
|
|
263
|
+
const { childNodes } = index_1.default.parseWithRef(name, this, 2);
|
|
266
264
|
this.firstChild.safeReplaceChildren(childNodes);
|
|
267
265
|
}
|
|
268
266
|
/**
|
|
@@ -276,8 +274,7 @@ let ArgToken = (() => {
|
|
|
276
274
|
this.removeAt(1);
|
|
277
275
|
return;
|
|
278
276
|
}
|
|
279
|
-
const root = index_1.default
|
|
280
|
-
.parse(value, this.getAttribute('include'), undefined, this.getAttribute('config')), { childNodes: [, oldDefault] } = this;
|
|
277
|
+
const { childNodes: [, oldDefault] } = this, root = index_1.default.parseWithRef(value, this);
|
|
281
278
|
if (oldDefault) {
|
|
282
279
|
oldDefault.safeReplaceChildren(root.childNodes);
|
|
283
280
|
}
|
package/dist/src/attribute.js
CHANGED
|
@@ -46,9 +46,11 @@ const rect_1 = require("../lib/rect");
|
|
|
46
46
|
const index_1 = __importDefault(require("../index"));
|
|
47
47
|
const index_2 = require("./index");
|
|
48
48
|
const atom_1 = require("./atom");
|
|
49
|
+
/* NOT FOR BROWSER ONLY */
|
|
50
|
+
const document_1 = require("../lib/document");
|
|
51
|
+
/* NOT FOR BROWSER ONLY END */
|
|
49
52
|
/* NOT FOR BROWSER */
|
|
50
53
|
const debug_1 = require("../util/debug");
|
|
51
|
-
const document_1 = require("../lib/document");
|
|
52
54
|
const fixed_1 = require("../mixin/fixed");
|
|
53
55
|
const cached_1 = require("../mixin/cached");
|
|
54
56
|
const stages = { 'ext-attr': 0, 'html-attr': 2, 'table-attr': 3 }, ariaAttrs = new Set(['aria-describedby', 'aria-flowto', 'aria-labelledby', 'aria-owns']);
|
|
@@ -138,6 +140,8 @@ let AttributeToken = (() => {
|
|
|
138
140
|
valueToken.setAttribute('stage', constants_1.MAX_STAGE - 1);
|
|
139
141
|
}
|
|
140
142
|
else if (tag === 'gallery' && key === 'caption'
|
|
143
|
+
|| tag === 'ref' && key === 'details'
|
|
144
|
+
|| (tag === 'mapframe' || tag === 'maplink') && key === 'text'
|
|
141
145
|
|| tag === 'choose' && (key === 'before' || key === 'after')) {
|
|
142
146
|
const newConfig = {
|
|
143
147
|
...config,
|
|
@@ -319,6 +323,30 @@ let AttributeToken = (() => {
|
|
|
319
323
|
if (s[1] && sharable_1.obsoleteAttrs[tag]?.has(name)) {
|
|
320
324
|
errors.push((0, lint_1.generateForChild)(firstChild, rect, rules[1], 'obsolete-attribute', s[1]));
|
|
321
325
|
}
|
|
326
|
+
/* NOT FOR BROWSER ONLY */
|
|
327
|
+
const rule = 'invalid-css', sError = lintConfig.getSeverity(rule), sWarn = lintConfig.getSeverity(rule, 'warn');
|
|
328
|
+
if (document_1.cssLSP
|
|
329
|
+
&& (sError || sWarn)
|
|
330
|
+
&& name === 'style'
|
|
331
|
+
&& lastChild.length === 1 && lastChild.firstChild.type === 'text') {
|
|
332
|
+
const root = this.getRootNode(), textDoc = new document_1.EmbeddedCSSDocument(root, lastChild);
|
|
333
|
+
Array.prototype.push.apply(errors, document_1.cssLSP.doValidation(textDoc, textDoc.styleSheet)
|
|
334
|
+
.filter(({ code, severity }) => code !== 'css-ruleorselectorexpected' && code !== 'emptyRules'
|
|
335
|
+
&& (severity === 1 ? sError : sWarn))
|
|
336
|
+
.map(({ range: { start: { line, character }, end }, message, severity, code }) => ({
|
|
337
|
+
code: code,
|
|
338
|
+
rule,
|
|
339
|
+
message,
|
|
340
|
+
severity: (severity === 1 ? sError : sWarn),
|
|
341
|
+
startLine: line,
|
|
342
|
+
startCol: character,
|
|
343
|
+
startIndex: root.indexFromPos(line, character),
|
|
344
|
+
endLine: end.line,
|
|
345
|
+
endCol: end.character,
|
|
346
|
+
endIndex: root.indexFromPos(end.line, end.character),
|
|
347
|
+
})));
|
|
348
|
+
}
|
|
349
|
+
/* NOT FOR BROWSER ONLY END */
|
|
322
350
|
return errors;
|
|
323
351
|
}
|
|
324
352
|
}
|
|
@@ -357,10 +385,10 @@ let AttributeToken = (() => {
|
|
|
357
385
|
/* PRINT ONLY END */
|
|
358
386
|
/* NOT FOR BROWSER */
|
|
359
387
|
cloneNode() {
|
|
360
|
-
const [key, value] = this.cloneChildNodes(), k = key.toString()
|
|
388
|
+
const [key, value] = this.cloneChildNodes(), k = key.toString();
|
|
361
389
|
return debug_1.Shadow.run(() => {
|
|
362
390
|
// @ts-expect-error abstract class
|
|
363
|
-
const token = new AttributeToken(this.type, this.tag, k, this.#equal, '', this.#quotes, config);
|
|
391
|
+
const token = new AttributeToken(this.type, this.tag, k, this.#equal, '', this.#quotes, this.getAttribute('config'));
|
|
364
392
|
token.firstChild.safeReplaceWith(key);
|
|
365
393
|
token.lastChild.safeReplaceWith(value);
|
|
366
394
|
return token;
|
|
@@ -401,7 +429,7 @@ let AttributeToken = (() => {
|
|
|
401
429
|
else if (value.includes('"') && value.includes(`'`)) {
|
|
402
430
|
throw new RangeError('Attribute values cannot contain single and double quotes simultaneously!');
|
|
403
431
|
}
|
|
404
|
-
const
|
|
432
|
+
const { childNodes } = index_1.default.parseWithRef(value, this, stages[type] + 1);
|
|
405
433
|
lastChild.safeReplaceChildren(childNodes);
|
|
406
434
|
if (value.includes('"')) {
|
|
407
435
|
this.#quotes = [`'`, `'`];
|
|
@@ -421,11 +449,12 @@ let AttributeToken = (() => {
|
|
|
421
449
|
* @throws `Error` title和alt属性不能更名
|
|
422
450
|
*/
|
|
423
451
|
rename(key) {
|
|
424
|
-
|
|
425
|
-
|
|
452
|
+
const { type, name, tag, firstChild } = this;
|
|
453
|
+
if (name === 'title' || name === 'alt' && tag === 'img') {
|
|
454
|
+
throw new Error(`${name} attribute cannot be renamed!`);
|
|
426
455
|
}
|
|
427
|
-
const
|
|
428
|
-
|
|
456
|
+
const { childNodes } = index_1.default.parseWithRef(key, this, stages[type] + 1);
|
|
457
|
+
firstChild.safeReplaceChildren(childNodes);
|
|
429
458
|
}
|
|
430
459
|
/** @private */
|
|
431
460
|
toHtmlInternal() {
|
package/dist/src/attributes.js
CHANGED
|
@@ -294,7 +294,7 @@ let AttributesToken = (() => {
|
|
|
294
294
|
const value = attr.getValue();
|
|
295
295
|
return [attr, value === true ? '' : value];
|
|
296
296
|
});
|
|
297
|
-
|
|
297
|
+
Array.prototype.push.apply(errors, pairs.map(([attr, value], i) => {
|
|
298
298
|
const e = (0, lint_1.generateForChild)(attr, rect, rules[1], index_1.default.msg('duplicate-attribute', key), severity);
|
|
299
299
|
if (computeEditInfo || fix) {
|
|
300
300
|
const remove = (0, lint_1.fixByRemove)(e);
|
package/dist/src/converter.js
CHANGED
|
@@ -108,9 +108,12 @@ let ConverterToken = (() => {
|
|
|
108
108
|
new converterRule_1.ConverterRuleToken(rules.join(';'), false, config, accum));
|
|
109
109
|
}
|
|
110
110
|
else {
|
|
111
|
-
this.
|
|
112
|
-
|
|
113
|
-
.
|
|
111
|
+
this.safeAppend([
|
|
112
|
+
firstRuleToken,
|
|
113
|
+
...rules.slice(1)
|
|
114
|
+
// @ts-expect-error abstract class
|
|
115
|
+
.map((rule) => new converterRule_1.ConverterRuleToken(rule, true, config, accum)),
|
|
116
|
+
]);
|
|
114
117
|
}
|
|
115
118
|
/* NOT FOR BROWSER */
|
|
116
119
|
this.protectChildren(0);
|
|
@@ -232,8 +232,7 @@ let ConverterRuleToken = (() => {
|
|
|
232
232
|
* @param to target of language conversion / 转换目标
|
|
233
233
|
*/
|
|
234
234
|
setTo(to) {
|
|
235
|
-
const { childNodes } = index_1.default
|
|
236
|
-
.parse(to, this.getAttribute('include'), undefined, this.getAttribute('config'));
|
|
235
|
+
const { childNodes } = index_1.default.parseWithRef(to, this);
|
|
237
236
|
this.lastChild.safeReplaceChildren(childNodes);
|
|
238
237
|
}
|
|
239
238
|
/**
|
|
@@ -243,9 +242,8 @@ let ConverterRuleToken = (() => {
|
|
|
243
242
|
* @param variant language variant / 语言变体
|
|
244
243
|
*/
|
|
245
244
|
setVariant(variant) {
|
|
246
|
-
const config = this.getAttribute('config');
|
|
247
245
|
if (this.length === 1) {
|
|
248
|
-
super.insertAt(debug_1.Shadow.run(() => new atom_1.AtomToken(variant, 'converter-rule-variant', config)), 0);
|
|
246
|
+
super.insertAt(debug_1.Shadow.run(() => new atom_1.AtomToken(variant, 'converter-rule-variant', this.getAttribute('config'))), 0);
|
|
249
247
|
}
|
|
250
248
|
else {
|
|
251
249
|
this.childNodes[this.length - 2].setText(variant);
|
|
@@ -263,9 +261,9 @@ let ConverterRuleToken = (() => {
|
|
|
263
261
|
if (!variant) {
|
|
264
262
|
throw new Error('Please specify the language variant first!');
|
|
265
263
|
}
|
|
266
|
-
const
|
|
264
|
+
const { childNodes } = index_1.default.parseWithRef(from, this);
|
|
267
265
|
if (!unidirectional) {
|
|
268
|
-
super.insertAt(debug_1.Shadow.run(() => new atom_1.AtomToken(undefined, 'converter-rule-from', config)), 0);
|
|
266
|
+
super.insertAt(debug_1.Shadow.run(() => new atom_1.AtomToken(undefined, 'converter-rule-from', this.getAttribute('config'))), 0);
|
|
269
267
|
}
|
|
270
268
|
this.firstChild.safeReplaceChildren(childNodes);
|
|
271
269
|
}
|
package/dist/src/extLink.js
CHANGED
|
@@ -201,9 +201,8 @@ let ExtLinkToken = (() => {
|
|
|
201
201
|
* @param str text of the link / 链接显示文字
|
|
202
202
|
*/
|
|
203
203
|
setLinkText(str) {
|
|
204
|
-
const root = index_1.default
|
|
205
|
-
|
|
206
|
-
if (this.length === 1) {
|
|
204
|
+
const { length, lastChild } = this, root = index_1.default.parseWithRef(str, this, 7);
|
|
205
|
+
if (length === 1) {
|
|
207
206
|
root.type = 'ext-link-text';
|
|
208
207
|
root.setAttribute('acceptable', {
|
|
209
208
|
'Stage-7': ':', ConverterToken: ':',
|
|
@@ -211,7 +210,7 @@ let ExtLinkToken = (() => {
|
|
|
211
210
|
this.insertAt(root);
|
|
212
211
|
}
|
|
213
212
|
else {
|
|
214
|
-
|
|
213
|
+
lastChild.safeReplaceChildren(root.childNodes);
|
|
215
214
|
}
|
|
216
215
|
this.#space ||= ' ';
|
|
217
216
|
}
|
package/dist/src/heading.js
CHANGED
|
@@ -100,8 +100,7 @@ let HeadingToken = (() => {
|
|
|
100
100
|
if (text.length > 1 && text.startsWith('=') && text.endsWith('=')) {
|
|
101
101
|
throw new Error('Please use HeadingToken.setLevel method to change the level of the heading!');
|
|
102
102
|
}
|
|
103
|
-
const { childNodes } = index_1.default
|
|
104
|
-
.parse(text, this.getAttribute('include'), undefined, this.getAttribute('config'));
|
|
103
|
+
const { childNodes } = index_1.default.parseWithRef(text, this);
|
|
105
104
|
this.firstChild.safeReplaceChildren(childNodes);
|
|
106
105
|
}
|
|
107
106
|
/**
|