wikilint 2.43.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.
Files changed (94) hide show
  1. package/config/default.json +32 -2
  2. package/config/enwiki.json +1 -1
  3. package/config/jawiki.json +1 -1
  4. package/config/minimum.json +1 -1
  5. package/config/moegirl.json +39 -1
  6. package/config/zhwiki.json +1 -1
  7. package/data/ext/templatedata.json +13 -5
  8. package/data/signatures.json +38 -32
  9. package/dist/base.d.mts +5 -5
  10. package/dist/base.d.ts +5 -5
  11. package/dist/base.js +1 -0
  12. package/dist/base.mjs +1 -0
  13. package/dist/bin/config.js +6 -5
  14. package/dist/index.js +9 -6
  15. package/dist/internal.d.ts +6 -1
  16. package/dist/lib/document.d.ts +17 -14
  17. package/dist/lib/element.js +5 -5
  18. package/dist/lib/lintConfig.js +11 -1
  19. package/dist/lib/lsp.d.ts +1 -2
  20. package/dist/lib/lsp.js +18 -42
  21. package/dist/lib/node.js +2 -2
  22. package/dist/lib/text.js +2 -2
  23. package/dist/lib/title.d.ts +4 -1
  24. package/dist/lib/title.js +5 -1
  25. package/dist/map.d.ts +4 -1
  26. package/dist/mixin/attributesParent.js +1 -1
  27. package/dist/mixin/elementLike.js +29 -31
  28. package/dist/mixin/hidden.js +0 -1
  29. package/dist/mixin/paramLineParent.d.ts +26 -0
  30. package/dist/mixin/paramLineParent.js +51 -0
  31. package/dist/parser/converter.js +1 -1
  32. package/dist/src/arg.js +17 -35
  33. package/dist/src/atom.d.ts +1 -1
  34. package/dist/src/atom.js +2 -0
  35. package/dist/src/attribute.js +10 -5
  36. package/dist/src/attributes.d.ts +1 -0
  37. package/dist/src/attributes.js +41 -15
  38. package/dist/src/commented.d.ts +1 -0
  39. package/dist/src/commented.js +1 -3
  40. package/dist/src/converterFlags.js +17 -8
  41. package/dist/src/converterRule.js +3 -3
  42. package/dist/src/funcTag.d.ts +23 -0
  43. package/dist/src/funcTag.js +85 -0
  44. package/dist/src/heading.js +8 -3
  45. package/dist/src/hidden.d.ts +3 -2
  46. package/dist/src/hidden.js +29 -5
  47. package/dist/src/imageParameter.d.ts +4 -3
  48. package/dist/src/imageParameter.js +29 -9
  49. package/dist/src/index.js +2 -2
  50. package/dist/src/link/base.js +14 -2
  51. package/dist/src/link/categorytree.d.ts +2 -0
  52. package/dist/src/link/categorytree.js +8 -5
  53. package/dist/src/link/file.d.ts +5 -4
  54. package/dist/src/link/file.js +19 -13
  55. package/dist/src/multiLine/charinsert.d.ts +16 -0
  56. package/dist/src/multiLine/charinsert.js +84 -0
  57. package/dist/src/multiLine/gallery.js +4 -4
  58. package/dist/src/multiLine/imagemap.d.ts +1 -1
  59. package/dist/src/multiLine/imagemap.js +7 -7
  60. package/dist/src/multiLine/index.d.ts +3 -0
  61. package/dist/src/multiLine/index.js +79 -18
  62. package/dist/src/multiLine/inputbox.d.ts +1 -0
  63. package/dist/src/multiLine/paramTag.d.ts +3 -0
  64. package/dist/src/multiLine/paramTag.js +60 -13
  65. package/dist/src/nested.js +7 -7
  66. package/dist/src/nowiki/index.d.ts +1 -0
  67. package/dist/src/nowiki/index.js +39 -28
  68. package/dist/src/nowiki/quote.js +6 -5
  69. package/dist/src/paramLine.d.ts +17 -3
  70. package/dist/src/paramLine.js +123 -31
  71. package/dist/src/parameter.d.ts +6 -0
  72. package/dist/src/parameter.js +15 -1
  73. package/dist/src/singleLine/charinsertLine.d.ts +21 -0
  74. package/dist/src/singleLine/charinsertLine.js +69 -0
  75. package/dist/src/{imagemapLink.d.ts → singleLine/imagemapLink.d.ts} +8 -7
  76. package/dist/src/singleLine/imagemapLink.js +95 -0
  77. package/dist/src/singleLine/index.d.ts +10 -0
  78. package/dist/src/singleLine/index.js +16 -0
  79. package/dist/src/tag/html.js +26 -8
  80. package/dist/src/tag/index.js +18 -17
  81. package/dist/src/tagPair/ext.d.ts +1 -0
  82. package/dist/src/tagPair/ext.js +59 -5
  83. package/dist/src/tagPair/index.js +1 -10
  84. package/dist/src/transclude.js +13 -13
  85. package/dist/util/sharable.js +22 -0
  86. package/dist/util/sharable.mjs +22 -0
  87. package/dist/util/string.js +33 -2
  88. package/dist/vendor/search.js +34 -0
  89. package/i18n/en.json +11 -0
  90. package/i18n/zh-hans.json +11 -0
  91. package/i18n/zh-hant.json +11 -0
  92. package/package.json +16 -25
  93. package/dist/src/imagemapLink.js +0 -34
  94. package/dist/util/search.js +0 -16
@@ -10,6 +10,7 @@ const child_process_1 = require("child_process");
10
10
  const strict_1 = __importDefault(require("assert/strict"));
11
11
  const cm_util_1 = require("@bhsd/cm-util");
12
12
  const diff_1 = require("../util/diff");
13
+ const string_1 = require("../util/string");
13
14
  /**
14
15
  * Converts an array to an object.
15
16
  * @param config parser configuration
@@ -40,7 +41,7 @@ const filterGadget = (id) => {
40
41
  const n = Number(id);
41
42
  return n < 2300 || n > 2303; // Gadget, Gadget talk, Gadget definition, Gadget definition talk
42
43
  };
43
- const pkg = "wikilint", version = "2.43.0";
44
+ const pkg = "wikilint", version = "2.45.0";
44
45
  /**
45
46
  * Get the parser configuration for a Wikimedia Foundation project.
46
47
  * @param site site nickname
@@ -108,7 +109,7 @@ exports.default = async (site, url, user, force, internal) => {
108
109
  siprop: `general|magicwords|namespaces|namespacealiases${mwConfig.functionHooks ? '' : '|functionhooks'}`,
109
110
  format: 'json',
110
111
  formatversion: '2',
111
- }, { general: { articlepath, server, variants, langconversion }, magicwords, namespaces, namespacealiases, functionhooks, } = (await (await fetch(`${url}/api.php?${new URLSearchParams(params).toString()}`, headers)).json()).query, ns = Object.entries(namespaces).filter(([id]) => filterGadget(id))
112
+ }, { general: { articlepath, server, variants, langconversion }, magicwords, namespaces, namespacealiases, functionhooks, } = (await (await fetch(`${url}/api.php?${String(new URLSearchParams(params))}`, headers)).json()).query, ns = Object.entries(namespaces).filter(([id]) => filterGadget(id))
112
113
  .flatMap(([id, { name, canonical = '' }]) => [
113
114
  [id, name],
114
115
  ...name === canonical ? [] : [[id, canonical]],
@@ -130,11 +131,11 @@ exports.default = async (site, url, user, force, internal) => {
130
131
  parserFunction[2] = getAliases(magicwords, new Set(['msg', 'raw']));
131
132
  parserFunction[3] = getAliases(magicwords, new Set(['subst', 'safesubst']));
132
133
  if (!mwConfig.functionHooks) {
133
- Object.assign(config, { functionHook: [...functionhooks.map(s => s.toLowerCase()), 'msgnw'] });
134
+ config.functionHook = [...(0, string_1.toLowerCase)(functionhooks), 'msgnw'];
134
135
  }
135
136
  if (!mwConfig.variableIDs) {
136
- const { variables } = (await (await fetch(`${url}/api.php?${new URLSearchParams({ ...params, siprop: 'variables' }).toString()}`, headers)).json()).query;
137
- Object.assign(config, { variable: [...new Set([...variables, '='])] });
137
+ const { variables } = (await (await fetch(`${url}/api.php?${String(new URLSearchParams({ ...params, siprop: 'variables' }))}`, headers)).json()).query;
138
+ config.variable = [...new Set([...variables, '='])];
138
139
  }
139
140
  if ('#choose' in parserFunction[0]) {
140
141
  delete parserFunction[0]['choose'];
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  /* eslint n/exports-style: 0 */
6
+ const cm_util_1 = require("@bhsd/cm-util");
6
7
  const base_1 = require("./base");
7
8
  const debug_1 = require("./util/debug");
8
9
  const constants_1 = require("./util/constants");
@@ -114,7 +115,8 @@ const Parser = {
114
115
  return this.getConfig();
115
116
  }
116
117
  /* NOT FOR BROWSER ONLY END */
117
- const parserConfig = config ?? this.config, { doubleUnderscore, ext, parserFunction, variable, } = parserConfig;
118
+ const parserConfig = config ?? this.config;
119
+ const { doubleUnderscore, ext, parserFunction, variable, variants, } = parserConfig;
118
120
  for (let i = 0; i < 2; i++) {
119
121
  if (doubleUnderscore[i].length === 0) {
120
122
  doubleUnderscore[i] = Object.keys(doubleUnderscore[i + 2]);
@@ -124,6 +126,7 @@ const Parser = {
124
126
  variable.push('translationlanguage');
125
127
  parserFunction[1]['TRANSLATIONLANGUAGE'] = 'translationlanguage';
126
128
  }
129
+ parserConfig.variants = (0, cm_util_1.getBCP47Variants)(variants);
127
130
  return {
128
131
  ...parserConfig,
129
132
  excludes: [],
@@ -135,19 +138,19 @@ const Parser = {
135
138
  && (this.i18n[msg] ?? msg).replace('$1', this.msg(arg));
136
139
  },
137
140
  /** @implements */
138
- normalizeTitle(title, defaultNs = 0, include, config = Parser.getConfig(), opt) {
141
+ normalizeTitle(title, defaultNs = 0, include, config = Parser.getConfig(), opt, accum = []) {
139
142
  let titleObj;
140
143
  if (opt?.halfParsed) {
141
- titleObj = new title_1.Title(title, defaultNs, config, opt);
144
+ titleObj = new title_1.Title(title, defaultNs, config, opt, accum);
142
145
  }
143
146
  else {
144
147
  const { Token } = require('./src/index');
145
148
  titleObj = debug_1.Shadow.run(() => {
146
- const root = new Token(title, config);
149
+ const root = new Token(title, config, accum);
147
150
  root.type = 'root';
148
151
  root.pageName = opt?.page;
149
152
  root.parseOnce(0, include).parseOnce();
150
- const t = new title_1.Title(root.firstChild.toString(), defaultNs, config, opt);
153
+ const t = new title_1.Title(root.firstChild.toString(), defaultNs, config, opt, accum);
151
154
  root.build();
152
155
  const keys = [
153
156
  'main',
@@ -189,7 +192,7 @@ const Parser = {
189
192
  maxStage ??= constants_1.MAX_STAGE;
190
193
  config ??= this.getConfig();
191
194
  let types;
192
- LINT: if (typeof maxStage !== 'number') {
195
+ LSP: if (typeof maxStage !== 'number') {
193
196
  types = Array.isArray(maxStage) ? maxStage : [maxStage];
194
197
  maxStage = Math.max(...types.map(t => base_1.stages[t] || constants_1.MAX_STAGE));
195
198
  }
@@ -38,15 +38,20 @@ export type { ConverterRuleToken } from './src/converterRule';
38
38
  export type { ConverterToken } from './src/converter';
39
39
  export type { NowikiToken } from './src/nowiki/index';
40
40
  export type { PreToken } from './src/pre';
41
+ export type { MultiLineToken } from './src/multiLine/index';
41
42
  export type { ParamTagToken } from './src/multiLine/paramTag';
42
43
  export type { InputboxToken } from './src/multiLine/inputbox';
43
44
  export type { NestedToken } from './src/nested';
44
45
  export type { GalleryToken } from './src/multiLine/gallery';
45
- export type { ImagemapLinkToken } from './src/imagemapLink';
46
+ export type { SingleLineToken } from './src/singleLine/index';
47
+ export type { ImagemapLinkToken } from './src/singleLine/imagemapLink';
46
48
  export type { ImagemapToken } from './src/multiLine/imagemap';
47
49
  export type { CommentedToken } from './src/commented';
48
50
  export type { CategorytreeToken } from './src/link/categorytree';
49
51
  export type { ParamLineToken } from './src/paramLine';
52
+ export type { CharinsertLineToken } from './src/singleLine/charinsertLine';
53
+ export type { CharinsertToken } from './src/multiLine/charinsert';
50
54
  export type { CommentLineToken } from './src/nowiki/commentLine';
51
55
  export type { TranslateToken } from './src/tagPair/translate';
52
56
  export type { TvarToken } from './src/tag/tvar';
57
+ export type { FuncTagToken } from './src/funcTag';
@@ -10,23 +10,26 @@ export interface TexvcLocation {
10
10
  line: number;
11
11
  column: number;
12
12
  }
13
+ export type TexvcReport = {
14
+ status: '+';
15
+ output: string;
16
+ } | {
17
+ status: 'C';
18
+ } | {
19
+ status: 'F' | 'S';
20
+ error: {
21
+ message: string;
22
+ location: {
23
+ start: TexvcLocation;
24
+ end: TexvcLocation;
25
+ };
26
+ };
27
+ };
13
28
  declare interface Texvcjs {
14
29
  check(input: string, options?: {
30
+ usemathrm?: boolean;
15
31
  usemhchem?: boolean;
16
- }): {
17
- status: '+';
18
- } | {
19
- status: 'C';
20
- } | {
21
- status: 'F' | 'S';
22
- error: {
23
- message: string;
24
- location: {
25
- start: TexvcLocation;
26
- end: TexvcLocation;
27
- };
28
- };
29
- };
32
+ }): TexvcReport;
30
33
  }
31
34
  export declare const loadTexvcjs: () => Texvcjs | null;
32
35
  export declare const loadJsonLSP: () => JSONLanguageService | null;
@@ -89,7 +89,7 @@ let AstElement = (() => {
89
89
  }
90
90
  /** @private */
91
91
  isInside(type) {
92
- return this.closest(`${type},ext`)?.type === type;
92
+ LINT: return this.closest(`${type},ext`)?.type === type;
93
93
  }
94
94
  /**
95
95
  * Insert a batch of child nodes at the end
@@ -145,7 +145,7 @@ let AstElement = (() => {
145
145
  return undefined;
146
146
  }
147
147
  const { length } = this.toString();
148
- if (index > length || index < -length) {
148
+ if (Math.abs(index) > length) {
149
149
  return undefined;
150
150
  }
151
151
  index += index < 0 ? length : 0;
@@ -201,9 +201,9 @@ let AstElement = (() => {
201
201
  /** @private */
202
202
  lint(start = this.getAbsoluteIndex(), re) {
203
203
  LINT: {
204
- const errors = [];
205
- for (let i = 0, cur = start + this.getAttribute('padding'); i < this.length; i++) {
206
- const child = this.childNodes[i];
204
+ const errors = [], { length, childNodes } = this;
205
+ for (let i = 0, cur = start + this.getAttribute('padding'); i < length; i++) {
206
+ const child = childNodes[i];
207
207
  child.setAttribute('aIndex', cur);
208
208
  const childErrors = child.lint(cur, re);
209
209
  if (childErrors.length > 0) {
@@ -61,8 +61,10 @@ const defaultLintRuleConfig = {
61
61
  'invalid-imagemap': [
62
62
  2,
63
63
  {
64
+ // coord: 2,
64
65
  // image: 2,
65
66
  // link: 2,
67
+ // shape: 2,
66
68
  },
67
69
  ],
68
70
  'invalid-invoke': [
@@ -79,6 +81,7 @@ const defaultLintRuleConfig = {
79
81
  duplicate: 1,
80
82
  },
81
83
  ],
84
+ 'invalid-ref': [2],
82
85
  'invalid-url': [1],
83
86
  'lonely-apos': [
84
87
  1,
@@ -120,6 +123,9 @@ const defaultLintRuleConfig = {
120
123
  // imageParameter: 2,
121
124
  // parameter: 2,
122
125
  unknownImageParameter: 1,
126
+ // dynamicpagelist: 2,
127
+ // inputbox: 2,
128
+ // seo: 2,
123
129
  },
124
130
  ],
125
131
  'no-ignored': [
@@ -137,11 +143,13 @@ const defaultLintRuleConfig = {
137
143
  nonWordAttributes: 1,
138
144
  redirect: 1,
139
145
  // categorytree: 2,
146
+ // charinsert: 2,
140
147
  // choose: 2,
141
148
  // combobox: 2,
142
149
  // dynamicpagelist: 2,
143
150
  // inputbox: 2,
144
151
  // references: 2,
152
+ // seo: 2,
145
153
  },
146
154
  ],
147
155
  'obsolete-attr': [1],
@@ -234,9 +242,11 @@ const defaultLintRuleConfig = {
234
242
  'void-ext': [
235
243
  2,
236
244
  {
237
- // img: 2,
245
+ // dynamicpagelist: 2,
238
246
  // languages: 2,
247
+ // rss: 2,
239
248
  // section: 2,
249
+ // templatedata: 2,
240
250
  // templatestyles: 2,
241
251
  },
242
252
  ],
package/dist/lib/lsp.d.ts CHANGED
@@ -24,9 +24,8 @@ export declare class LanguageService implements LanguageServiceBase {
24
24
  * 提供颜色指示
25
25
  * @param rgba color parser / 颜色解析函数
26
26
  * @param text source Wikitext / 源代码
27
- * @param hsl whether HSL colors are treated / 是否允许HSL颜色
28
27
  */
29
- provideDocumentColors(rgba: (s: string) => [number, number, number, number] | [], text: string, hsl?: boolean): Promise<ColorInformation[]>;
28
+ provideDocumentColors(rgba: (s: string) => [number, number, number, number] | [], text: string): Promise<ColorInformation[]>;
30
29
  /**
31
30
  * Provide color pickers
32
31
  *
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("../util/search"));
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 + (extra ?? ''),
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, hsl = true) {
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 = colors && type === 'attr-value' && parentNode.name === 'style';
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, hsl).filter(([, , , isColor]) => isColor);
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
- ...getCompletion(params, 'Property', match, position)
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 `<inputbox>`
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[cur.name], 'Property', key, position)
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 (const token of [...tokens].reverse()) { // 提高 getBoundingClientRect 的性能
993
- token.getRelativeIndex();
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 { type: t } = token.parentNode;
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 (const token of root.querySelectorAll('template,magic-word#invoke').reverse()) {
1421
- const { type, childNodes } = token;
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("../util/search"));
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
- LINT: {
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 === 'rfc' || error === 'pmid' || error === 'isbn', lbrace = char === '{', rbrace = char === '}', lbrack = char === '[', rbrack = char === ']';
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--;
@@ -1,10 +1,12 @@
1
1
  import type { Config } from '../base';
2
+ import type { Token } from '../internal';
2
3
  export interface TitleOptions {
3
4
  temporary?: boolean | undefined;
4
5
  decode?: boolean | undefined;
5
6
  selfLink?: boolean | undefined;
6
7
  halfParsed?: boolean | undefined;
7
8
  page?: string | undefined;
9
+ nowiki?: boolean;
8
10
  }
9
11
  /**
10
12
  * title object of a MediaWiki page
@@ -43,8 +45,9 @@ export declare class Title {
43
45
  * @param opt.decode 是否需要解码
44
46
  * @param opt.selfLink 是否允许selfLink
45
47
  * @param opt.page 当前页面标题
48
+ * @param opt.nowiki 是否剥离nowiki标签
46
49
  */
47
- constructor(title: string, defaultNs: number, config: Config, { temporary, decode, selfLink, page }?: TitleOptions);
50
+ constructor(title: string, defaultNs: number, config: Config, { temporary, decode, selfLink, page, nowiki }?: TitleOptions, accum?: Token[]);
48
51
  /**
49
52
  * Check if the title is a redirect and get the redirect target
50
53
  *
package/dist/lib/title.js CHANGED
@@ -74,9 +74,13 @@ class Title {
74
74
  * @param opt.decode 是否需要解码
75
75
  * @param opt.selfLink 是否允许selfLink
76
76
  * @param opt.page 当前页面标题
77
+ * @param opt.nowiki 是否剥离nowiki标签
77
78
  */
78
- constructor(title, defaultNs, config, { temporary, decode, selfLink, page } = {}) {
79
+ constructor(title, defaultNs, config, { temporary, decode, selfLink, page, nowiki } = {}, accum = []) {
79
80
  this.page = page;
81
+ if (nowiki) {
82
+ title = title.replace(/\0(\d+)e\x7F/gu, (_, p1) => accum[p1].innerText ?? '');
83
+ }
80
84
  const trimmed = title.trim(), subpage = trimmed.startsWith('../');
81
85
  if (decode && title.includes('%')) {
82
86
  try {
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;
@@ -14,7 +14,7 @@ const attributesParent = (i = 0) => (constructor) => {
14
14
  return this.childNodes[i];
15
15
  }
16
16
  hasAttr(key) {
17
- LSP: return this.#getAttributesChild().hasAttr(key);
17
+ return this.#getAttributesChild().hasAttr(key);
18
18
  }
19
19
  getAttr(key) {
20
20
  return this.#getAttributesChild().getAttr(key);
@@ -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
- class ElementLike extends constructor {
9
- #getCondition(selector) {
10
- return (0, selector_1.getCondition)(selector, this);
11
- }
12
- closest(selector) {
13
- const condition = this.#getCondition(selector);
14
- let { parentNode } = this;
15
- while (parentNode) {
16
- if (condition(parentNode)) {
17
- return parentNode;
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
- ({ parentNode } = parentNode);
22
+ return undefined;
20
23
  }
21
- return undefined;
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
- querySelector(selector) {
42
- LINT: return this.getElementBy(this.#getCondition(selector));
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
- querySelectorAll(selector) {
63
- LINT: return this.getElementsBy(this.#getCondition(selector));
64
- }
65
- escape() {
66
- LSP: {
67
- for (const child of this.childNodes) {
68
- child.escape();
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;
@@ -13,7 +13,6 @@ const hiddenToken = (linter = true, html = true) => (constructor) => {
13
13
  return '';
14
14
  }
15
15
  lint(start) {
16
- // @ts-expect-error private argument
17
16
  LINT: return linter ? [] : super.lint(start);
18
17
  }
19
18
  }
@@ -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
+ */