wikiparser-node 1.16.5 → 1.16.6
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/bundle/bundle.es7.js +27 -27
- package/bundle/bundle.lsp.js +29 -29
- package/bundle/bundle.min.js +27 -27
- package/dist/lib/element.js +1 -0
- package/dist/lib/lsp.js +109 -88
- package/dist/parser/braces.js +48 -18
- package/dist/parser/commentAndExt.js +19 -6
- package/dist/src/table/index.js +2 -1
- package/dist/src/table/td.js +3 -1
- package/extensions/dist/base.js +4 -10
- package/extensions/es7/base.js +4 -10
- package/package.json +1 -1
package/dist/lib/element.js
CHANGED
|
@@ -303,6 +303,7 @@ class AstElement extends node_1.AstNode {
|
|
|
303
303
|
acc += self.getAttribute('padding');
|
|
304
304
|
for (let i = 0; acc <= index && i < childNodes.length; i++) {
|
|
305
305
|
const cur = childNodes[i], { nextSibling } = cur, str = cur.toString(), l = str.length;
|
|
306
|
+
cur.setAttribute('aIndex', acc);
|
|
306
307
|
acc += l;
|
|
307
308
|
// 优先选择靠前的非文本兄弟节点,但永不进入假节点
|
|
308
309
|
if (acc > index
|
package/dist/lib/lsp.js
CHANGED
|
@@ -172,18 +172,24 @@ const getSectionEnd = (section, lines, line) => {
|
|
|
172
172
|
/** VSCode-style language service */
|
|
173
173
|
class LanguageService {
|
|
174
174
|
#text;
|
|
175
|
+
#text2;
|
|
175
176
|
#running;
|
|
177
|
+
#running2;
|
|
176
178
|
#done;
|
|
179
|
+
#done2;
|
|
177
180
|
#config;
|
|
181
|
+
#config2;
|
|
178
182
|
#completionConfig;
|
|
179
|
-
#signature;
|
|
180
183
|
/** @private */
|
|
181
184
|
data;
|
|
182
185
|
/** @param uri 任务标识 */
|
|
183
186
|
constructor(uri) {
|
|
184
187
|
exports.tasks.set(uri, this);
|
|
185
188
|
/* NOT FOR BROWSER ONLY */
|
|
186
|
-
|
|
189
|
+
Object.defineProperty(this, 'data', {
|
|
190
|
+
value: require(path.join('..', '..', 'data', 'signatures')),
|
|
191
|
+
enumerable: false,
|
|
192
|
+
});
|
|
187
193
|
}
|
|
188
194
|
/** @implements */
|
|
189
195
|
destroy() {
|
|
@@ -193,7 +199,7 @@ class LanguageService {
|
|
|
193
199
|
* 提交解析任务
|
|
194
200
|
* @param text 源代码
|
|
195
201
|
* @description
|
|
196
|
-
* -
|
|
202
|
+
* - 总是更新`#text`以便`#parse`完成时可以判断是否需要重新解析
|
|
197
203
|
* - 如果已有进行中或已完成的解析,则返回该解析的结果
|
|
198
204
|
* - 否则开始新的解析
|
|
199
205
|
*/
|
|
@@ -209,7 +215,7 @@ class LanguageService {
|
|
|
209
215
|
/**
|
|
210
216
|
* 执行解析
|
|
211
217
|
* @description
|
|
212
|
-
* -
|
|
218
|
+
* - 完成后会检查`#text`是否已更新,如果是则重新解析
|
|
213
219
|
* - 总是返回最新的解析结果
|
|
214
220
|
*/
|
|
215
221
|
async #parse() {
|
|
@@ -227,14 +233,41 @@ class LanguageService {
|
|
|
227
233
|
return this.#running;
|
|
228
234
|
}
|
|
229
235
|
/**
|
|
230
|
-
*
|
|
231
|
-
* @
|
|
236
|
+
* 提交签名解析任务
|
|
237
|
+
* @param text 源代码
|
|
238
|
+
* @description
|
|
239
|
+
* - 总是更新`#text2`以便`#parseSignature`完成时可以判断是否需要重新解析
|
|
240
|
+
* - 如果已有进行中或已完成的解析,则返回该解析的结果
|
|
241
|
+
* - 否则开始新的解析
|
|
242
|
+
*/
|
|
243
|
+
async #queueSignature(text) {
|
|
244
|
+
text = (0, string_1.tidy)(text);
|
|
245
|
+
if (this.#text2 === text && this.#config2 === index_1.default.config && !this.#running2) {
|
|
246
|
+
return this.#done2;
|
|
247
|
+
}
|
|
248
|
+
this.#text2 = text;
|
|
249
|
+
this.#running2 ??= this.#parseSignature(); // 不要提交多个解析任务
|
|
250
|
+
return this.#running2;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* 执行签名解析
|
|
254
|
+
* @description
|
|
255
|
+
* - 完成后会检查`#text2`是否已更新,如果是则重新解析
|
|
256
|
+
* - 总是返回最新的解析结果
|
|
232
257
|
*/
|
|
233
|
-
#
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
258
|
+
async #parseSignature() {
|
|
259
|
+
const config = index_1.default.getConfig();
|
|
260
|
+
this.#config2 = index_1.default.config;
|
|
261
|
+
const text = this.#text2, root = await index_1.default.partialParse(text, () => this.#text2, true, config);
|
|
262
|
+
if (this.#text2 === text && this.#config2 === index_1.default.config) {
|
|
263
|
+
this.#done2 = root;
|
|
264
|
+
this.#running2 = undefined;
|
|
265
|
+
return root;
|
|
237
266
|
}
|
|
267
|
+
/* istanbul ignore next */
|
|
268
|
+
this.#running2 = this.#parseSignature();
|
|
269
|
+
/* istanbul ignore next */
|
|
270
|
+
return this.#running2;
|
|
238
271
|
}
|
|
239
272
|
/**
|
|
240
273
|
* Provide color decorators
|
|
@@ -245,9 +278,8 @@ class LanguageService {
|
|
|
245
278
|
* @param hsl whether HSL colors are treated / 是否允许HSL颜色
|
|
246
279
|
*/
|
|
247
280
|
async provideDocumentColors(rgba, text, hsl = true) {
|
|
248
|
-
this.#checkSignature();
|
|
249
281
|
const root = await this.#queue(text);
|
|
250
|
-
return root.querySelectorAll('attr-value,parameter-value,arg-default')
|
|
282
|
+
return root.querySelectorAll('attr-value,parameter-value,arg-default').reverse()
|
|
251
283
|
.flatMap(({ type, childNodes }) => {
|
|
252
284
|
if (type !== 'attr-value' && !isPlain(childNodes)) {
|
|
253
285
|
return [];
|
|
@@ -336,7 +368,6 @@ class LanguageService {
|
|
|
336
368
|
* @param position 位置
|
|
337
369
|
*/
|
|
338
370
|
async provideCompletionItems(text, position) {
|
|
339
|
-
this.#checkSignature();
|
|
340
371
|
const { re, allTags, functions, switches, protocols, params, tags, ext } = this.#prepareCompletionConfig(), { line, character } = position, curLine = text.split(/\r?\n/u, line + 1)[line], mt = re.exec(curLine?.slice(0, character) ?? '');
|
|
341
372
|
if (mt?.[1] !== undefined) { // tag
|
|
342
373
|
const closing = mt[1].startsWith('/');
|
|
@@ -448,7 +479,6 @@ class LanguageService {
|
|
|
448
479
|
* @param warning whether to include warnings / 是否包含警告
|
|
449
480
|
*/
|
|
450
481
|
async provideDiagnostics(text, warning = true) {
|
|
451
|
-
this.#checkSignature();
|
|
452
482
|
const root = await this.#queue(text), errors = root.lint();
|
|
453
483
|
return (warning ? errors : errors.filter(({ severity }) => severity === 'error'))
|
|
454
484
|
.map(({ startLine, startCol, endLine, endCol, severity, rule, message, fix, suggestions }) => ({
|
|
@@ -474,34 +504,36 @@ class LanguageService {
|
|
|
474
504
|
* @param text source Wikitext / 源代码
|
|
475
505
|
*/
|
|
476
506
|
async provideFoldingRanges(text) {
|
|
477
|
-
this.#checkSignature();
|
|
478
507
|
const root = await this.#queue(text), { length } = root.getLines(), ranges = [], levels = new Array(6), tokens = root.querySelectorAll('heading-title,table,template,magic-word');
|
|
479
508
|
for (const token of [...tokens].reverse()) { // 提高 getBoundingClientRect 的性能
|
|
480
509
|
token.getRelativeIndex();
|
|
481
510
|
}
|
|
482
511
|
for (const token of tokens) {
|
|
483
|
-
const {
|
|
484
|
-
if (token.type === 'heading-title') {
|
|
485
|
-
const {
|
|
486
|
-
|
|
487
|
-
const
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
512
|
+
const { offsetHeight } = token;
|
|
513
|
+
if (token.type === 'heading-title' || offsetHeight > 2) {
|
|
514
|
+
const { top } = token.getBoundingClientRect();
|
|
515
|
+
if (token.type === 'heading-title') {
|
|
516
|
+
const { level } = token.parentNode;
|
|
517
|
+
for (let i = level - 1; i < 6; i++) {
|
|
518
|
+
const startLine = levels[i];
|
|
519
|
+
if (startLine !== undefined && startLine < top - 1) {
|
|
520
|
+
ranges.push({
|
|
521
|
+
startLine,
|
|
522
|
+
endLine: top - 1,
|
|
523
|
+
kind: 'region',
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
levels[i] = undefined;
|
|
494
527
|
}
|
|
495
|
-
levels[
|
|
528
|
+
levels[level - 1] = top + offsetHeight - 1; // 从标题的最后一行开始折叠
|
|
529
|
+
}
|
|
530
|
+
else {
|
|
531
|
+
ranges.push({
|
|
532
|
+
startLine: top, // 从表格或模板的第一行开始折叠
|
|
533
|
+
endLine: top + offsetHeight - 2,
|
|
534
|
+
kind: 'region',
|
|
535
|
+
});
|
|
496
536
|
}
|
|
497
|
-
levels[level - 1] = top + height - 1; // 从标题的最后一行开始折叠
|
|
498
|
-
}
|
|
499
|
-
else if (height > 2) {
|
|
500
|
-
ranges.push({
|
|
501
|
-
startLine: top, // 从表格或模板的第一行开始折叠
|
|
502
|
-
endLine: top + height - 2,
|
|
503
|
-
kind: 'region',
|
|
504
|
-
});
|
|
505
537
|
}
|
|
506
538
|
}
|
|
507
539
|
for (const startLine of levels) {
|
|
@@ -522,13 +554,13 @@ class LanguageService {
|
|
|
522
554
|
* @param text source Wikitext / 源代码
|
|
523
555
|
*/
|
|
524
556
|
async provideLinks(text) {
|
|
525
|
-
this.#checkSignature();
|
|
526
557
|
/^(?:http:\/\/|\/\/)/iu; // eslint-disable-line @typescript-eslint/no-unused-expressions
|
|
527
558
|
const { articlePath, protocol } = index_1.default.getConfig(), absolute = articlePath?.includes('//'), protocolRegex = new RegExp(`^(?:${protocol}|//)`, 'iu');
|
|
528
559
|
return (await this.#queue(text))
|
|
529
|
-
.querySelectorAll(`magic-link,ext-link-url,free-ext-link,attr-value,image-parameter#link${absolute ? ',link-target,template-name,invoke-module' : ''}`)
|
|
560
|
+
.querySelectorAll(`magic-link,ext-link-url,free-ext-link,attr-value,image-parameter#link${absolute ? ',link-target,template-name,invoke-module' : ''}`)
|
|
561
|
+
.reverse()
|
|
530
562
|
.map((token) => {
|
|
531
|
-
const { type, parentNode, firstChild, lastChild, childNodes } = token, { name, tag } = parentNode;
|
|
563
|
+
const { type, parentNode, firstChild, lastChild, childNodes, length } = token, { name, tag } = parentNode;
|
|
532
564
|
if (!(type !== 'attr-value'
|
|
533
565
|
|| name === 'src' && ['templatestyles', 'img'].includes(tag)
|
|
534
566
|
|| name === 'cite' && ['blockquote', 'del', 'ins', 'q'].includes(tag))
|
|
@@ -536,7 +568,9 @@ class LanguageService {
|
|
|
536
568
|
return false;
|
|
537
569
|
}
|
|
538
570
|
let target = childNodes.filter((node) => node.type === 'text')
|
|
539
|
-
.map(({ data }) => data)
|
|
571
|
+
.map(({ data }) => data)
|
|
572
|
+
.join('')
|
|
573
|
+
.trim();
|
|
540
574
|
if (!target) {
|
|
541
575
|
return false;
|
|
542
576
|
}
|
|
@@ -583,7 +617,7 @@ class LanguageService {
|
|
|
583
617
|
}
|
|
584
618
|
target = new URL(target).href;
|
|
585
619
|
if (type === 'image-parameter') {
|
|
586
|
-
const { top, left, height, width } =
|
|
620
|
+
const rect = firstChild.getBoundingClientRect(), { top, left, height, width } = length === 1 ? rect : lastChild.getBoundingClientRect();
|
|
587
621
|
return {
|
|
588
622
|
range: {
|
|
589
623
|
start: { line: rect.top, character: rect.left },
|
|
@@ -597,7 +631,8 @@ class LanguageService {
|
|
|
597
631
|
catch {
|
|
598
632
|
return false;
|
|
599
633
|
}
|
|
600
|
-
})
|
|
634
|
+
})
|
|
635
|
+
.filter(Boolean);
|
|
601
636
|
}
|
|
602
637
|
/**
|
|
603
638
|
* Provide references
|
|
@@ -607,7 +642,6 @@ class LanguageService {
|
|
|
607
642
|
* @param position 位置
|
|
608
643
|
*/
|
|
609
644
|
async provideReferences(text, position) {
|
|
610
|
-
this.#checkSignature();
|
|
611
645
|
const root = await this.#queue(text), { offsetNode, offset } = caretPositionFromWord(root, position), element = offsetNode.type === 'text' ? offsetNode.parentNode : offsetNode, node = offset === 0 && (element.type === 'ext-attr-dirty' || element.type === 'html-attr-dirty')
|
|
612
646
|
? element.parentNode.parentNode
|
|
613
647
|
: element, { type } = node, refName = getRefName(node), refGroup = getRefGroup(node);
|
|
@@ -616,7 +650,7 @@ class LanguageService {
|
|
|
616
650
|
}
|
|
617
651
|
const name = getName(node), refs = root.querySelectorAll(type === 'heading-title' ? 'heading' : type).filter(token => type === 'attr-value'
|
|
618
652
|
? getRefName(token) === refName || getRefGroup(token) === refGroup
|
|
619
|
-
: getName(token) === name).map((token) => ({
|
|
653
|
+
: getName(token) === name).reverse().map((token) => ({
|
|
620
654
|
range: createNodeRange(token.type === 'parameter-key' ? token.parentNode : token),
|
|
621
655
|
}));
|
|
622
656
|
return refs.length === 0 ? undefined : refs;
|
|
@@ -629,7 +663,6 @@ class LanguageService {
|
|
|
629
663
|
* @param position 位置
|
|
630
664
|
*/
|
|
631
665
|
async provideDefinition(text, position) {
|
|
632
|
-
this.#checkSignature();
|
|
633
666
|
const root = await this.#queue(text), node = root.elementFromPoint(position.character, position.line), ext = node.is('ext') && node.name === 'ref'
|
|
634
667
|
? node
|
|
635
668
|
: node.closest('ext#ref'), refName = getRefTagAttr(ext, 'name');
|
|
@@ -638,7 +671,7 @@ class LanguageService {
|
|
|
638
671
|
}
|
|
639
672
|
const refGroup = getRefTagAttr(ext, 'group'), refs = root.querySelectorAll('ext#ref').filter(token => token.innerText
|
|
640
673
|
&& getRefTagAttr(token, 'name') === refName
|
|
641
|
-
&& getRefTagAttr(token, 'group') === refGroup).map(({ lastChild }) => ({
|
|
674
|
+
&& getRefTagAttr(token, 'group') === refGroup).reverse().map(({ lastChild }) => ({
|
|
642
675
|
range: createNodeRange(lastChild),
|
|
643
676
|
}));
|
|
644
677
|
return refs.length === 0 ? undefined : refs;
|
|
@@ -651,7 +684,6 @@ class LanguageService {
|
|
|
651
684
|
* @param position 位置
|
|
652
685
|
*/
|
|
653
686
|
async resolveRenameLocation(text, position) {
|
|
654
|
-
this.#checkSignature();
|
|
655
687
|
const root = await this.#queue(text), node = root.elementFromPoint(position.character, position.line), { type } = node, refName = getRefName(node), refGroup = getRefGroup(node);
|
|
656
688
|
return !refName && !refGroup && (!renameTypes.has(type)
|
|
657
689
|
|| type === 'parameter-key' && /^[1-9]\d*$/u.test(node.parentNode.name)
|
|
@@ -668,7 +700,6 @@ class LanguageService {
|
|
|
668
700
|
* @param newName new name / 新名称
|
|
669
701
|
*/
|
|
670
702
|
async provideRenameEdits(text, position, newName) {
|
|
671
|
-
this.#checkSignature();
|
|
672
703
|
const root = await this.#queue(text), node = root.elementFromPoint(position.character, position.line), { type } = node, refName = getRefName(node), refNameGroup = refName && getRefTagAttr(node.parentNode.parentNode, 'group'), refGroup = getRefGroup(node), name = getName(node), refs = root.querySelectorAll(type).filter(token => {
|
|
673
704
|
const { type: t } = token.parentNode;
|
|
674
705
|
if (type === 'link-target' && t !== 'link' && t !== 'redirect-target') {
|
|
@@ -684,7 +715,7 @@ class LanguageService {
|
|
|
684
715
|
? undefined
|
|
685
716
|
: {
|
|
686
717
|
changes: {
|
|
687
|
-
'': refs.map((ref) => ({
|
|
718
|
+
'': refs.reverse().map((ref) => ({
|
|
688
719
|
range: createNodeRange(ref),
|
|
689
720
|
newText: newName,
|
|
690
721
|
})),
|
|
@@ -711,7 +742,6 @@ class LanguageService {
|
|
|
711
742
|
if (!this.data) {
|
|
712
743
|
return undefined;
|
|
713
744
|
}
|
|
714
|
-
this.#checkSignature();
|
|
715
745
|
const root = await this.#queue(text), { offsetNode, offset } = caretPositionFromWord(root, position), token = offsetNode.type === 'text' ? offsetNode.parentNode : offsetNode, { type, parentNode, length, name } = token;
|
|
716
746
|
let info, f, range;
|
|
717
747
|
if (token.is('double-underscore') && offset > 0) {
|
|
@@ -760,13 +790,8 @@ class LanguageService {
|
|
|
760
790
|
/* istanbul ignore next */
|
|
761
791
|
if (!this.data) {
|
|
762
792
|
return undefined;
|
|
763
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
764
793
|
}
|
|
765
|
-
|
|
766
|
-
throw new Error('This is a regular language server!');
|
|
767
|
-
}
|
|
768
|
-
this.#signature = true;
|
|
769
|
-
const { line, character } = position, curLine = text.split(/\r?\n/u, line + 1)[line], { lastChild } = await this.#queue(`${curLine.slice(0, character + /^[^{}<]*/u.exec(curLine.slice(character))[0].length)}}}`);
|
|
794
|
+
const { line, character } = position, curLine = text.split(/\r?\n/u, line + 1)[line], { lastChild } = await this.#queueSignature(`${curLine.slice(0, character + /^[^{}<]*/u.exec(curLine.slice(character))[0].length)}}}`);
|
|
770
795
|
if (!lastChild.is('magic-word') || lastChild.length === 1) {
|
|
771
796
|
return undefined;
|
|
772
797
|
}
|
|
@@ -809,12 +834,12 @@ class LanguageService {
|
|
|
809
834
|
* @param text source Wikitext / 源代码
|
|
810
835
|
*/
|
|
811
836
|
async provideInlayHints(text) {
|
|
812
|
-
this.#checkSignature();
|
|
813
837
|
const hints = [], root = await this.#queue(text);
|
|
814
|
-
for (const
|
|
815
|
-
const { type, childNodes } =
|
|
838
|
+
for (const token of root.querySelectorAll('template,magic-word#invoke').reverse()) {
|
|
839
|
+
const { type, childNodes } = token;
|
|
816
840
|
hints.push(...childNodes.slice(type === 'template' ? 1 : 3).filter(({ anon }) => anon)
|
|
817
|
-
.reverse()
|
|
841
|
+
.reverse()
|
|
842
|
+
.map((parameter) => ({
|
|
818
843
|
position: positionAt(root, parameter.getAbsoluteIndex()),
|
|
819
844
|
label: `${parameter.name}=`,
|
|
820
845
|
kind: 2,
|
|
@@ -848,40 +873,36 @@ class LanguageService {
|
|
|
848
873
|
* @param text source Wikitext / 源代码
|
|
849
874
|
*/
|
|
850
875
|
async provideDocumentSymbols(text) {
|
|
851
|
-
this.#checkSignature();
|
|
852
876
|
const root = await this.#queue(text), lines = root.getLines(), { length } = lines, symbols = [], names = new Set(), sections = new Array(6), tokens = root.querySelectorAll('heading-title');
|
|
853
877
|
for (const token of [...tokens].reverse()) { // 提高 getBoundingClientRect 的性能
|
|
854
878
|
token.getRelativeIndex();
|
|
855
879
|
}
|
|
856
880
|
for (const token of tokens) {
|
|
857
|
-
const { top, height, left, width } = token.getBoundingClientRect();
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
}
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
else {
|
|
883
|
-
symbols.push(info);
|
|
884
|
-
}
|
|
881
|
+
const { top, height, left, width } = token.getBoundingClientRect(), { level } = token.parentNode;
|
|
882
|
+
for (let i = level - 1; i < 6; i++) {
|
|
883
|
+
getSectionEnd(sections[i], lines, top - 1);
|
|
884
|
+
sections[i] = undefined;
|
|
885
|
+
}
|
|
886
|
+
const section = token.text().trim() || ' ', name = names.has(section)
|
|
887
|
+
? new Array(names.size).fill('').map((_, i) => `${section.trim()}_${i + 2}`)
|
|
888
|
+
.find(s => !names.has(s))
|
|
889
|
+
: section, container = sections.slice(0, level - 1).reverse().find(Boolean), selectionRange = {
|
|
890
|
+
start: { line: top, character: left - level },
|
|
891
|
+
end: (0, lint_1.getEndPos)(top, left, height, width + level),
|
|
892
|
+
}, info = {
|
|
893
|
+
name,
|
|
894
|
+
kind: 15,
|
|
895
|
+
range: { start: selectionRange.start },
|
|
896
|
+
selectionRange,
|
|
897
|
+
};
|
|
898
|
+
names.add(name);
|
|
899
|
+
sections[level - 1] = info;
|
|
900
|
+
if (container) {
|
|
901
|
+
container.children ??= [];
|
|
902
|
+
container.children.push(info);
|
|
903
|
+
}
|
|
904
|
+
else {
|
|
905
|
+
symbols.push(info);
|
|
885
906
|
}
|
|
886
907
|
}
|
|
887
908
|
for (const section of sections) {
|
package/dist/parser/braces.js
CHANGED
|
@@ -13,7 +13,24 @@ const closes = {
|
|
|
13
13
|
'{': String.raw `\}{2,}|\|`,
|
|
14
14
|
'-': String.raw `\}-`,
|
|
15
15
|
'[': String.raw `\]\]`,
|
|
16
|
-
}, openBraces = String.raw `|\{{2,}`, marks = new Map([['!', '!'], ['!!', '+'], ['(!', '{'], ['!)', '}'], ['!-', '-'], ['=', '~'], ['server', 'm']])
|
|
16
|
+
}, openBraces = String.raw `|\{{2,}`, marks = new Map([['!', '!'], ['!!', '+'], ['(!', '{'], ['!)', '}'], ['!-', '-'], ['=', '~'], ['server', 'm']]);
|
|
17
|
+
/**
|
|
18
|
+
* 获取模板或魔术字对应的字符
|
|
19
|
+
* @param s 模板或魔术字名
|
|
20
|
+
*/
|
|
21
|
+
const getSymbol = (s) => {
|
|
22
|
+
const name = (0, string_1.removeComment)(s).trim().toLowerCase();
|
|
23
|
+
if (marks.has(name)) {
|
|
24
|
+
return marks.get(name); // 标记{{!}}等
|
|
25
|
+
}
|
|
26
|
+
else if (/^(?:filepath|(?:full|canonical)urle?):./u.test(name)) {
|
|
27
|
+
return 'm';
|
|
28
|
+
}
|
|
29
|
+
else if (/^#vardefine:./u.test(name)) {
|
|
30
|
+
return 'n';
|
|
31
|
+
}
|
|
32
|
+
return 't';
|
|
33
|
+
};
|
|
17
34
|
/**
|
|
18
35
|
* 解析花括号
|
|
19
36
|
* @param wikitext
|
|
@@ -22,11 +39,32 @@ const closes = {
|
|
|
22
39
|
* @throws TranscludeToken.constructor()
|
|
23
40
|
*/
|
|
24
41
|
const parseBraces = (wikitext, config, accum) => {
|
|
25
|
-
const source = String.raw `${config.excludes?.includes('heading') ? '' : String.raw `^((?:\0\d+[cno]\x7F)*)={1,6}|`}\[\[|-\{(?!\{)`, { parserFunction: [, , , subst] } = config, stack = [];
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
42
|
+
const source = String.raw `${config.excludes?.includes('heading') ? '' : String.raw `^((?:\0\d+[cno]\x7F)*)={1,6}|`}\[\[|-\{(?!\{)`, { parserFunction: [, , , subst] } = config, stack = [], linkStack = [];
|
|
43
|
+
/**
|
|
44
|
+
* 恢复内链
|
|
45
|
+
* @param s 不含内链的字符串
|
|
46
|
+
*/
|
|
47
|
+
const restore = (s) => s.replace(/\0(\d+)\x7F/gu, (_, p1) => linkStack[p1]);
|
|
48
|
+
wikitext = wikitext.replace(/\{\{([^\n{}[]*)\}\}(?!\})|\[\[[^\n[\]{]*\]\]/gu, (m, p1) => {
|
|
49
|
+
if (p1 !== undefined) {
|
|
50
|
+
try {
|
|
51
|
+
const { length } = accum, parts = p1.split('|');
|
|
52
|
+
// @ts-expect-error abstract class
|
|
53
|
+
new transclude_1.TranscludeToken(parts[0], parts.slice(1).map(part => {
|
|
54
|
+
const i = part.indexOf('=');
|
|
55
|
+
return i === -1 ? [part] : [part.slice(0, i), part.slice(i + 1)];
|
|
56
|
+
}), config, accum);
|
|
57
|
+
return `\0${length}${getSymbol(parts[0])}\x7F`;
|
|
58
|
+
}
|
|
59
|
+
catch (e) {
|
|
60
|
+
/* istanbul ignore if */
|
|
61
|
+
if (!(e instanceof SyntaxError) || e.message !== 'Invalid template name') {
|
|
62
|
+
throw e;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
linkStack.push(m);
|
|
67
|
+
return `\0${linkStack.length - 1}\x7F`;
|
|
30
68
|
});
|
|
31
69
|
const lastBraces = wikitext.lastIndexOf('}}') - wikitext.length;
|
|
32
70
|
let moreBraces = lastBraces + wikitext.length !== -1;
|
|
@@ -47,7 +85,7 @@ const parseBraces = (wikitext, config, accum) => {
|
|
|
47
85
|
* @param text wikitext全文
|
|
48
86
|
*/
|
|
49
87
|
const push = (text) => {
|
|
50
|
-
parts[parts.length - 1].push(text.slice(topPos, curIndex));
|
|
88
|
+
parts[parts.length - 1].push(restore(text.slice(topPos, curIndex)));
|
|
51
89
|
};
|
|
52
90
|
if (syntax === ']]' || syntax === '}-') { // 情形1:闭合内链或转换
|
|
53
91
|
lastIndex = curIndex + 2;
|
|
@@ -61,6 +99,7 @@ const parseBraces = (wikitext, config, accum) => {
|
|
|
61
99
|
if (rmt) {
|
|
62
100
|
wikitext = `${wikitext.slice(0, index)}\0${accum.length}h\x7F${wikitext.slice(curIndex)}`;
|
|
63
101
|
lastIndex = index + 4 + String(accum.length).length;
|
|
102
|
+
rmt[2] = restore(rmt[2]);
|
|
64
103
|
// @ts-expect-error abstract class
|
|
65
104
|
new heading_1.HeadingToken(rmt[1].length, rmt.slice(2), config, accum);
|
|
66
105
|
}
|
|
@@ -94,16 +133,7 @@ const parseBraces = (wikitext, config, accum) => {
|
|
|
94
133
|
try {
|
|
95
134
|
// @ts-expect-error abstract class
|
|
96
135
|
new transclude_1.TranscludeToken(parts[0][0], parts.slice(1), config, accum);
|
|
97
|
-
|
|
98
|
-
if (marks.has(name.toLowerCase())) {
|
|
99
|
-
ch = marks.get(name.toLowerCase()); // 标记{{!}}等
|
|
100
|
-
}
|
|
101
|
-
else if (/^(?:filepath|(?:full|canonical)urle?):./iu.test(name)) {
|
|
102
|
-
ch = 'm';
|
|
103
|
-
}
|
|
104
|
-
else if (/^#vardefine:./iu.test(name)) {
|
|
105
|
-
ch = 'n';
|
|
106
|
-
}
|
|
136
|
+
ch = getSymbol(parts[0][0]);
|
|
107
137
|
}
|
|
108
138
|
catch (e) {
|
|
109
139
|
/* istanbul ignore else */
|
|
@@ -149,7 +179,7 @@ const parseBraces = (wikitext, config, accum) => {
|
|
|
149
179
|
regex.lastIndex = lastIndex;
|
|
150
180
|
mt = regex.exec(wikitext);
|
|
151
181
|
}
|
|
152
|
-
return wikitext;
|
|
182
|
+
return restore(wikitext);
|
|
153
183
|
};
|
|
154
184
|
exports.parseBraces = parseBraces;
|
|
155
185
|
constants_1.parsers['parseBraces'] = __filename;
|
|
@@ -9,7 +9,24 @@ const comment_1 = require("../src/nowiki/comment");
|
|
|
9
9
|
/* NOT FOR BROWSER */
|
|
10
10
|
const constants_1 = require("../util/constants");
|
|
11
11
|
/* NOT FOR BROWSER END */
|
|
12
|
-
const onlyincludeLeft = '<onlyinclude>', onlyincludeRight = '</onlyinclude>', { length } = onlyincludeLeft;
|
|
12
|
+
const onlyincludeLeft = '<onlyinclude>', onlyincludeRight = '</onlyinclude>', { length } = onlyincludeLeft, regexInclude = new WeakMap(), regexNoinclude = new WeakMap();
|
|
13
|
+
/**
|
|
14
|
+
* 获取正则表达式
|
|
15
|
+
* @param ext 扩展标签
|
|
16
|
+
* @param includeOnly 是否嵌入
|
|
17
|
+
*/
|
|
18
|
+
const getRegex = (ext, includeOnly) => {
|
|
19
|
+
const regex = includeOnly ? regexInclude : regexNoinclude;
|
|
20
|
+
if (regex.has(ext)) {
|
|
21
|
+
return regex.get(ext);
|
|
22
|
+
}
|
|
23
|
+
const noincludeRegex = includeOnly ? 'includeonly' : '(?:no|only)include', includeRegex = includeOnly ? 'noinclude' : 'includeonly';
|
|
24
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
25
|
+
/<!--[\s\S]*?(?:-->|$)|<foo(?:\s[^>]*)?\/?>|<\/foo\s*>|<(bar)(\s[^>]*?)?(?:\/>|>([\s\S]*?)<\/(\1\s*)>)|<(baz)(\s[^>]*?)?(?:\/>|>([\s\S]*?)(?:<\/(baz\s*)>|$))/giu;
|
|
26
|
+
const re = new RegExp(String.raw `<!--[\s\S]*?(?:-->|$)|<${noincludeRegex}(?:\s[^>]*)?/?>|</${noincludeRegex}\s*>|<(${ext.join('|')})(\s[^>]*?)?(?:/>|>([\s\S]*?)</(\1\s*)>)|<(${includeRegex})(\s[^>]*?)?(?:/>|>([\s\S]*?)(?:</(${includeRegex}\s*)>|$))`, 'giu');
|
|
27
|
+
regex.set(ext, re);
|
|
28
|
+
return re;
|
|
29
|
+
};
|
|
13
30
|
/**
|
|
14
31
|
* 更新`<onlyinclude>`和`</onlyinclude>`的位置
|
|
15
32
|
* @param wikitext
|
|
@@ -55,11 +72,7 @@ const parseCommentAndExt = (wikitext, config, accum, includeOnly) => {
|
|
|
55
72
|
return str;
|
|
56
73
|
}
|
|
57
74
|
}
|
|
58
|
-
|
|
59
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
60
|
-
/<!--[\s\S]*?(?:-->|$)|<foo(?:\s[^>]*)?\/?>|<\/foo\s*>|<(bar)(\s[^>]*?)?(?:\/>|>([\s\S]*?)<\/(\1\s*)>)|<(baz)(\s[^>]*?)?(?:\/>|>([\s\S]*?)(?:<\/(baz\s*)>|$))/giu;
|
|
61
|
-
const /** Never cached due to the possibility of nested extension tags */ regex = new RegExp(String.raw `<!--[\s\S]*?(?:-->|$)|<${noincludeRegex}(?:\s[^>]*)?/?>|</${noincludeRegex}\s*>|<(${ext})(\s[^>]*?)?(?:/>|>([\s\S]*?)</(\1\s*)>)|<(${includeRegex})(\s[^>]*?)?(?:/>|>([\s\S]*?)(?:</(${includeRegex}\s*)>|$))`, 'giu');
|
|
62
|
-
return wikitext.replace(regex, (substr, name, attr, inner, closing, include, includeAttr, includeInner, includeClosing) => {
|
|
75
|
+
return wikitext.replace(getRegex(config.ext, includeOnly), (substr, name, attr, inner, closing, include, includeAttr, includeInner, includeClosing) => {
|
|
63
76
|
const l = accum.length;
|
|
64
77
|
let ch = 'n';
|
|
65
78
|
if (name) {
|
package/dist/src/table/index.js
CHANGED
|
@@ -575,7 +575,8 @@ class TableToken extends trBase_1.TrBaseToken {
|
|
|
575
575
|
const filter = (token) => token.childNodes.filter((0, debug_1.isToken)('table-inter'));
|
|
576
576
|
const { childNodes } = this, tr = childNodes.filter((0, debug_1.isToken)('tr')), newOpt = { ...opt, nowrap: true };
|
|
577
577
|
return `${[this, ...tr].flatMap(filter) // eslint-disable-line es-x/no-array-prototype-flat
|
|
578
|
-
.map(token => token.toHtmlInternal(newOpt).trim())
|
|
578
|
+
.map(token => token.toHtmlInternal(newOpt).trim())
|
|
579
|
+
.join(' ')}<table${childNodes[1].toHtmlInternal()}>${opt?.nowrap ? ' ' : '\n'}<tbody>${super.toHtmlInternal(opt)}${(0, html_1.html)(tr, '', opt)}</tbody></table>`;
|
|
579
580
|
}
|
|
580
581
|
}
|
|
581
582
|
exports.TableToken = TableToken;
|
package/dist/src/table/td.js
CHANGED
|
@@ -158,7 +158,9 @@ let TdToken = (() => {
|
|
|
158
158
|
const str = previousSibling.lastChild.toString();
|
|
159
159
|
result.escape ||= esc;
|
|
160
160
|
result.correction = str.includes('\n') && debug_1.Shadow.run(() => new index_2.Token(str, this.getAttribute('config'))
|
|
161
|
-
.parseOnce(0, this.getAttribute('include'))
|
|
161
|
+
.parseOnce(0, this.getAttribute('include'))
|
|
162
|
+
.parseOnce()
|
|
163
|
+
.parseOnce()
|
|
162
164
|
.toString()
|
|
163
165
|
.includes('\n'));
|
|
164
166
|
if (subtype === 'th' && result.subtype !== 'th') {
|
package/extensions/dist/base.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(() => {
|
|
2
2
|
var _a;
|
|
3
|
-
const version = '1.16.
|
|
3
|
+
const version = '1.16.6', src = (_a = document.currentScript) === null || _a === void 0 ? void 0 : _a.src, file = /\/extensions\/dist\/base\.(?:min\.)?js$/u, CDN = src && file.test(src)
|
|
4
4
|
? src.replace(file, '')
|
|
5
5
|
: `https://testingcf.jsdelivr.net/npm/wikiparser-node@${version}`;
|
|
6
6
|
const workerJS = () => {
|
|
@@ -18,11 +18,8 @@ const workerJS = () => {
|
|
|
18
18
|
}
|
|
19
19
|
return root;
|
|
20
20
|
};
|
|
21
|
-
const getLSP = (qid
|
|
22
|
-
|
|
23
|
-
if (signature) {
|
|
24
|
-
id += 0.5;
|
|
25
|
-
}
|
|
21
|
+
const getLSP = (qid) => {
|
|
22
|
+
const id = Math.floor(qid);
|
|
26
23
|
if (lsps.has(id)) {
|
|
27
24
|
return lsps.get(id);
|
|
28
25
|
}
|
|
@@ -85,13 +82,10 @@ const workerJS = () => {
|
|
|
85
82
|
break;
|
|
86
83
|
case 'destroy':
|
|
87
84
|
getLSP(qid).destroy();
|
|
88
|
-
getLSP(qid, true).destroy();
|
|
89
85
|
lsps.delete(qid);
|
|
90
|
-
lsps.delete(qid + 0.5);
|
|
91
86
|
break;
|
|
92
87
|
case 'data':
|
|
93
88
|
getLSP(qid).data = wikitext;
|
|
94
|
-
getLSP(qid, true).data = wikitext;
|
|
95
89
|
break;
|
|
96
90
|
case 'colorPresentations':
|
|
97
91
|
postMessage([qid, getLSP(qid).provideColorPresentations(wikitext)]);
|
|
@@ -148,7 +142,7 @@ const workerJS = () => {
|
|
|
148
142
|
break;
|
|
149
143
|
case 'signatureHelp':
|
|
150
144
|
(async () => {
|
|
151
|
-
postMessage([qid, await getLSP(qid
|
|
145
|
+
postMessage([qid, await getLSP(qid).provideSignatureHelp(wikitext, include), wikitext]);
|
|
152
146
|
})();
|
|
153
147
|
break;
|
|
154
148
|
case 'inlayHints':
|
package/extensions/es7/base.js
CHANGED
|
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
var _a;
|
|
12
|
-
const version = '1.16.
|
|
12
|
+
const version = '1.16.6', src = (_a = document.currentScript) === null || _a === void 0 ? void 0 : _a.src, file = /\/extensions\/dist\/base\.(?:min\.)?js$/u, CDN = src && file.test(src)
|
|
13
13
|
? src.replace(file, '')
|
|
14
14
|
: `https://testingcf.jsdelivr.net/npm/wikiparser-node@${version}`;
|
|
15
15
|
const workerJS = () => {
|
|
@@ -27,11 +27,8 @@ const workerJS = () => {
|
|
|
27
27
|
}
|
|
28
28
|
return root;
|
|
29
29
|
};
|
|
30
|
-
const getLSP = (qid
|
|
31
|
-
|
|
32
|
-
if (signature) {
|
|
33
|
-
id += 0.5;
|
|
34
|
-
}
|
|
30
|
+
const getLSP = (qid) => {
|
|
31
|
+
const id = Math.floor(qid);
|
|
35
32
|
if (lsps.has(id)) {
|
|
36
33
|
return lsps.get(id);
|
|
37
34
|
}
|
|
@@ -94,13 +91,10 @@ const workerJS = () => {
|
|
|
94
91
|
break;
|
|
95
92
|
case 'destroy':
|
|
96
93
|
getLSP(qid).destroy();
|
|
97
|
-
getLSP(qid, true).destroy();
|
|
98
94
|
lsps.delete(qid);
|
|
99
|
-
lsps.delete(qid + 0.5);
|
|
100
95
|
break;
|
|
101
96
|
case 'data':
|
|
102
97
|
getLSP(qid).data = wikitext;
|
|
103
|
-
getLSP(qid, true).data = wikitext;
|
|
104
98
|
break;
|
|
105
99
|
case 'colorPresentations':
|
|
106
100
|
postMessage([qid, getLSP(qid).provideColorPresentations(wikitext)]);
|
|
@@ -157,7 +151,7 @@ const workerJS = () => {
|
|
|
157
151
|
break;
|
|
158
152
|
case 'signatureHelp':
|
|
159
153
|
(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
160
|
-
postMessage([qid, yield getLSP(qid
|
|
154
|
+
postMessage([qid, yield getLSP(qid).provideSignatureHelp(wikitext, include), wikitext]);
|
|
161
155
|
}))();
|
|
162
156
|
break;
|
|
163
157
|
case 'inlayHints':
|