wikilint 2.36.0 → 2.37.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin/cli.js CHANGED
@@ -78,16 +78,8 @@ const throwOnLintConfig = (config) => {
78
78
  * load lintConfig
79
79
  * @param file lintConfig file path
80
80
  */
81
- const loadLintConfig = async (file) => {
82
- const symbol = Symbol('lintConfig');
83
- let lintConfig = symbol;
84
- try {
85
- lintConfig = require(file);
86
- }
87
- catch { }
88
- if (lintConfig === symbol) {
89
- lintConfig = await import(file);
90
- }
81
+ const loadLintConfig = (file) => {
82
+ let lintConfig = require(file);
91
83
  if (lintConfig && typeof lintConfig === 'object' && 'default' in lintConfig) {
92
84
  lintConfig = lintConfig.default;
93
85
  }
@@ -292,42 +284,28 @@ config = (config.includes('/')
292
284
  ? path_1.default.resolve(index_1.default.config)
293
285
  : path_1.default.join(configPath, index_1.default.config)) + (config.endsWith('.json') ? '' : '.json');
294
286
  const { mtimeMs } = fs_1.default.statSync(config), obj = cache?.[include ? 'include' : 'noinclude'];
295
- let minimatch;
296
- try {
297
- ({ minimatch } = require('minimatch'));
298
- }
299
- catch {
300
- /* eslint-disable n/no-unsupported-features/node-builtins */
301
- if (typeof path_1.default.matchesGlob !== 'function') {
302
- exit('Cannot load Node.js package "minimatch"');
303
- }
304
- minimatch = path_1.default.matchesGlob.bind(path_1.default);
305
- /* eslint-enable n/no-unsupported-features/node-builtins */
306
- }
307
287
  (async () => {
308
288
  if (lintConfigFile) {
309
289
  try {
310
- index_1.default.lintConfig = await loadLintConfig(lintConfigFile);
290
+ index_1.default.lintConfig = loadLintConfig(lintConfigFile);
311
291
  }
312
292
  catch {
313
293
  exit(`Cannot load lint config file: ${lintConfigFile}`);
314
294
  }
315
295
  }
316
296
  else {
317
- await (async () => {
318
- let cur = process.cwd(), last;
319
- while (last !== cur) {
320
- for (const file of lintConfigDefaults) {
321
- try {
322
- index_1.default.lintConfig = await loadLintConfig(path_1.default.join(cur, file));
323
- return;
324
- }
325
- catch { }
297
+ let cur = process.cwd(), last;
298
+ while (last !== cur) {
299
+ for (const file of lintConfigDefaults) {
300
+ try {
301
+ index_1.default.lintConfig = loadLintConfig(path_1.default.join(cur, file));
302
+ return;
326
303
  }
327
- last = cur;
328
- cur = path_1.default.dirname(cur);
304
+ catch { }
329
305
  }
330
- })();
306
+ last = cur;
307
+ cur = path_1.default.dirname(cur);
308
+ }
331
309
  }
332
310
  index_1.default.lintConfig.computeEditInfo = false;
333
311
  index_1.default.lintConfig.fix = true;
@@ -338,7 +316,7 @@ catch {
338
316
  exiting = true;
339
317
  continue;
340
318
  }
341
- else if (ignorePatterns.some(ignore => minimatch(file, ignore))) {
319
+ else if (ignorePatterns.some(ignore => path_1.default.matchesGlob(file, ignore))) {
342
320
  continue;
343
321
  }
344
322
  const fileCache = obj?.[file];
@@ -39,46 +39,7 @@ const filterGadget = (id) => {
39
39
  const n = Number(id);
40
40
  return n < 2300 || n > 2303; // Gadget, Gadget talk, Gadget definition, Gadget definition talk
41
41
  };
42
- /**
43
- * Execute the data script.
44
- * @param obj MediaWiki module implementation
45
- */
46
- const execute = (obj) => {
47
- Object.entries(obj.files).find(([k]) => k.endsWith('.data.js'))[1]();
48
- };
49
- const mw = {
50
- loader: {
51
- done: false,
52
- /** @ignore */
53
- impl(callback) {
54
- execute(callback()[1]);
55
- },
56
- /** @ignore */
57
- implement(name, callback) {
58
- if (typeof callback === 'object') {
59
- execute(callback);
60
- }
61
- else if (!this.done) {
62
- callback();
63
- }
64
- if (name.startsWith('ext.CodeMirror.data')) {
65
- this.done = true;
66
- }
67
- },
68
- /** @ignore */
69
- state() {
70
- //
71
- },
72
- },
73
- config: {
74
- /** @ignore */
75
- set({ extCodeMirrorConfig }) {
76
- mwConfig = extCodeMirrorConfig;
77
- },
78
- },
79
- };
80
- const pkg = "wikilint", version = "2.36.0";
81
- let mwConfig;
42
+ const pkg = "wikilint", version = "2.37.1";
82
43
  /**
83
44
  * Get the parser configuration for a Wikimedia Foundation project.
84
45
  * @param site site nickname
@@ -122,15 +83,28 @@ exports.default = async (site, url, user, force, internal) => {
122
83
  siprop: 'general|magicwords|functionhooks|namespaces|namespacealiases',
123
84
  format: 'json',
124
85
  formatversion: '2',
125
- }, { general: { articlepath, variants, langconversion }, magicwords, namespaces, namespacealiases, functionhooks, } = (await (await fetch(`${url}/api.php?${new URLSearchParams(params).toString()}`, headers)).json()).query;
126
- try {
127
- eval(m); // eslint-disable-line no-eval
86
+ }, { general: { articlepath, variants, langconversion }, magicwords, namespaces, namespacealiases, functionhooks, } = (await (await fetch(`${url}/api.php?${new URLSearchParams(params).toString()}`, headers)).json()).query, tempFile = path_1.default.join(__dirname, 'mw.js');
87
+ fs_1.default.writeFileSync(tempFile, m);
88
+ const { stdout, stderr } = (0, child_process_1.spawnSync)(process.execPath, [
89
+ '-r',
90
+ './env.js',
91
+ process.allowedNodeEnvironmentFlags.has('--permission')
92
+ ? '--permission'
93
+ : '--experimental-permission',
94
+ `--allow-fs-read=${__dirname}`,
95
+ '--disable-warning=ExperimentalWarning',
96
+ tempFile,
97
+ ], { cwd: __dirname, encoding: 'utf8' });
98
+ fs_1.default.unlinkSync(tempFile);
99
+ if (stderr) {
100
+ console.error(stderr);
101
+ throw new Error('Failed to execute the fetched MediaWiki module!', { cause: m });
128
102
  }
129
- catch (e) {
130
- console.log(m);
131
- throw e;
103
+ let mwConfig;
104
+ try {
105
+ mwConfig = JSON.parse(stdout);
132
106
  }
133
- if (!mwConfig) {
107
+ catch {
134
108
  throw new RangeError('Extension:CodeMirror is not installed!');
135
109
  }
136
110
  const ns = Object.entries(namespaces).filter(([id]) => filterGadget(id))
@@ -138,7 +112,7 @@ exports.default = async (site, url, user, force, internal) => {
138
112
  [id, name],
139
113
  ...name === canonical ? [] : [[id, canonical]],
140
114
  ]), config = {
141
- ...(0, cm_util_1.getParserConfig)(require(path_1.default.join(dir, 'minimum')), mwConfig),
115
+ ...(0, cm_util_1.getParserConfig)(require(path_1.default.join(dir, 'minimum.json')), mwConfig),
142
116
  ...(0, cm_util_1.getKeywords)(magicwords),
143
117
  variants: langconversion ? (0, cm_util_1.getVariants)(variants) : [],
144
118
  namespaces: Object.fromEntries(ns),
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * Execute the data script.
5
+ * @param obj MediaWiki module implementation
6
+ */
7
+ const execute = (obj) => {
8
+ Object.entries(obj.files).find(([k]) => k.endsWith('.data.js'))[1]();
9
+ };
10
+ Object.assign(globalThis, {
11
+ mw: {
12
+ loader: {
13
+ done: false,
14
+ /** @ignore */
15
+ impl(callback) {
16
+ execute(callback()[1]);
17
+ },
18
+ /** @ignore */
19
+ implement(name, callback) {
20
+ if (typeof callback === 'object') {
21
+ execute(callback);
22
+ }
23
+ else if (!this.done) {
24
+ callback();
25
+ }
26
+ if (name.startsWith('ext.CodeMirror.data')) {
27
+ this.done = true;
28
+ }
29
+ },
30
+ /** @ignore */
31
+ state() {
32
+ //
33
+ },
34
+ },
35
+ config: {
36
+ /** @ignore */
37
+ set({ extCodeMirrorConfig }) {
38
+ console.log(JSON.stringify(extCodeMirrorConfig));
39
+ },
40
+ },
41
+ },
42
+ });
package/dist/index.js CHANGED
@@ -17,20 +17,25 @@ const diff_1 = require("./util/diff");
17
17
  /* NOT FOR BROWSER ONLY */
18
18
  const re = new RegExp(String.raw `^https?:\/\/([^./]+)\.(${common_1.wmf})\.org`, 'iu');
19
19
  /**
20
- * 从根路径require
20
+ * require一个JSON文件
21
21
  * @param file 文件名
22
- * @param dir 子路径
23
22
  * @throws {RangeError} 仅支持JSON文件
24
23
  */
25
- const rootRequire = (file, dir) => {
26
- const fullPath = require.resolve(path_1.default.isAbsolute(file)
27
- ? /* c8 ignore next */ file
28
- : path_1.default.join('..', file.includes('/') ? '' : dir, file));
29
- if (!fullPath.endsWith('.json')) {
30
- throw new RangeError('Only JSON files are supported!');
24
+ const jsonRequire = (file) => {
25
+ const fullPath = require.resolve(file);
26
+ if (fullPath.endsWith('.json')) {
27
+ return require(fullPath);
31
28
  }
32
- return require(fullPath);
29
+ throw new RangeError('Only JSON files are supported!');
33
30
  };
31
+ /**
32
+ * 从根路径require
33
+ * @param file 文件名
34
+ * @param dir 子路径
35
+ */
36
+ const rootRequire = (file, dir) => jsonRequire(path_1.default.isAbsolute(file)
37
+ ? /* c8 ignore next */ file
38
+ : path_1.default.join('..', file.includes('/') ? '' : dir, file));
34
39
  /* NOT FOR BROWSER ONLY END */
35
40
  let viewOnly = true;
36
41
  let lintConfig = (() => {
@@ -92,7 +97,7 @@ const Parser = {
92
97
  if (!path_1.default.isAbsolute(this.config)) {
93
98
  for (const p of this.configPaths) {
94
99
  try {
95
- this.config = require(path_1.default.resolve(process.cwd(), p, this.config));
100
+ this.config = jsonRequire(path_1.default.resolve(process.cwd(), p, this.config));
96
101
  break;
97
102
  }
98
103
  catch { }
@@ -29,11 +29,10 @@ declare interface Texvcjs {
29
29
  };
30
30
  }
31
31
  export declare const loadTexvcjs: () => Texvcjs | null;
32
- export declare const jsonTags: string[];
33
32
  export declare const loadJsonLSP: () => JSONLanguageService | null;
34
33
  export declare const loadCssLSP: () => CSSLanguageService | null;
35
34
  export declare const loadHtmlData: () => IHTMLDataProvider | null;
36
- export declare const loadStylelint: () => Promise<PublicApi | null>;
35
+ export declare const loadStylelint: () => PublicApi | null;
37
36
  /** embedded document */
38
37
  declare class EmbeddedDocument implements TextDocument {
39
38
  #private;
@@ -3,9 +3,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.EmbeddedCSSDocument = exports.EmbeddedJSONDocument = exports.loadStylelint = exports.loadHtmlData = exports.loadCssLSP = exports.loadJsonLSP = exports.jsonTags = exports.loadTexvcjs = void 0;
6
+ exports.EmbeddedCSSDocument = exports.EmbeddedJSONDocument = exports.loadStylelint = exports.loadHtmlData = exports.loadCssLSP = exports.loadJsonLSP = exports.loadTexvcjs = void 0;
7
7
  const path_1 = __importDefault(require("path"));
8
8
  const common_1 = require("@bhsd/common");
9
+ const constants_1 = require("../util/constants");
9
10
  let texcvjs;
10
11
  const loadTexvcjs = () => {
11
12
  NPM: {
@@ -22,7 +23,6 @@ const loadTexvcjs = () => {
22
23
  }
23
24
  };
24
25
  exports.loadTexvcjs = loadTexvcjs;
25
- exports.jsonTags = ['templatedata', 'mapframe', 'maplink'];
26
26
  let jsonLSP;
27
27
  const loadJsonLSP = () => {
28
28
  if (jsonLSP === undefined) {
@@ -38,10 +38,10 @@ const loadJsonLSP = () => {
38
38
  });
39
39
  const dir = path_1.default.join('..', '..', 'data', 'ext');
40
40
  jsonLSP.configure({
41
- schemas: exports.jsonTags.map((tag) => {
42
- const uri = path_1.default.join(dir, tag);
41
+ schemas: constants_1.jsonTags.map((tag) => {
42
+ const uri = path_1.default.join(dir, `${tag}.json`);
43
43
  try {
44
- const schema = require(tag === 'maplink' ? path_1.default.join(dir, 'mapframe') : uri);
44
+ const schema = require(tag === 'maplink' ? path_1.default.join(dir, 'mapframe.json') : uri);
45
45
  return {
46
46
  uri,
47
47
  fileMatch: [tag],
@@ -96,15 +96,15 @@ exports.loadHtmlData = loadHtmlData;
96
96
  let stylelint;
97
97
  const loadStylelint = () => {
98
98
  NPM: {
99
- stylelint ??= (async () => {
99
+ if (stylelint === undefined) {
100
100
  try {
101
- return (await import('stylelint')).default;
101
+ stylelint = require('stylelint');
102
102
  }
103
103
  catch /* c8 ignore start */ {
104
- return null;
104
+ stylelint = null;
105
105
  }
106
106
  /* c8 ignore stop */
107
- })();
107
+ }
108
108
  return stylelint;
109
109
  }
110
110
  };
package/dist/lib/lsp.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import Parser from '../index';
2
+ import { Token } from '../src/index';
2
3
  import type { Range, Position, ColorInformation, ColorPresentation, FoldingRange, DocumentLink, Location, WorkspaceEdit, Diagnostic as DiagnosticBase, TextEdit, Hover, SignatureHelp, InlayHint, CodeAction, DocumentSymbol } from 'vscode-languageserver-types';
3
4
  import type { Config, LanguageService as LanguageServiceBase, CompletionItem, SignatureData } from '../base';
4
5
  import type { AttributeToken } from '../internal';
package/dist/lib/lsp.js CHANGED
@@ -22,6 +22,7 @@ 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
24
  const search_1 = __importDefault(require("../util/search"));
25
+ const constants_2 = require("../util/constants");
25
26
  const document_1 = require("./document");
26
27
  exports.tasks = new WeakMap();
27
28
  const refTags = new Set(['ref']), referencesTags = new Set(['ref', 'references']), nameAttrs = new Set(['name', 'follow']), groupAttrs = new Set(['group']), renameTypes = new Set([
@@ -38,7 +39,7 @@ const refTags = new Set(['ref']), referencesTags = new Set(['ref', 'references']
38
39
  'heading',
39
40
  'magic-word-name',
40
41
  ...renameTypes,
41
- ]), plainTypes = new Set(['text', 'comment', 'noinclude', 'include']), cssSelector = ['ext', 'html', 'table'].map(s => `${s}-attr#style`).join();
42
+ ]), plainTypes = new Set(['text', 'comment', 'noinclude', 'include']), rawLilyPondCommands = new Set(['paper', 'book', 'bookpart', 'score', 'markuplist'].map(c => `\\${c}`)), cssSelector = ['ext', 'html', 'table'].map(s => `${s}-attr#style`).join();
42
43
  const getLinkRegex = (0, common_1.getRegex)(protocol => new RegExp(`^(?:${protocol}|//)`, 'iu'));
43
44
  /**
44
45
  * Check if a token is a plain attribute.
@@ -279,7 +280,7 @@ const partialParse = async (wikitext, watch, include, config = index_1.default.g
279
280
  };
280
281
  /* NOT FOR BROWSER ONLY */
281
282
  /** @see https://www.npmjs.com/package/stylelint-config-recommended */
282
- const cssRules = { 'block-no-empty': null }, sources = { 'invalid-css': 'css', 'invalid-math': 'texvc' }, jsonSelector = document_1.jsonTags.map(s => `ext#${s}`).join(), scores = new Map();
283
+ 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();
283
284
  let colors;
284
285
  /**
285
286
  * Correct the position of an error.
@@ -372,15 +373,15 @@ class LanguageService {
372
373
  exports.tasks.set(uri, this);
373
374
  /* NOT FOR BROWSER ONLY */
374
375
  const dataDir = path_1.default.join('..', '..', 'data'), extDir = path_1.default.join(dataDir, 'ext');
375
- this.#lilypondData = require(path_1.default.join(extDir, 'score'));
376
- this.#mathData = require(path_1.default.join(extDir, 'math'));
376
+ this.#lilypondData = require(path_1.default.join(extDir, 'score.json'));
377
+ this.#mathData = require(path_1.default.join(extDir, 'math.json'));
377
378
  /* NOT FOR BROWSER ONLY END */
378
379
  Object.defineProperties(this, {
379
380
  config: { enumerable: false },
380
381
  data: {
381
382
  enumerable: false,
382
383
  /* NOT FOR BROWSER ONLY */
383
- value: require(path_1.default.join(dataDir, 'signatures')),
384
+ value: require(path_1.default.join(dataDir, 'signatures.json')),
384
385
  },
385
386
  });
386
387
  }
@@ -491,15 +492,15 @@ class LanguageService {
491
492
  async provideDocumentColors(rgba, text, hsl = true) {
492
493
  const root = await this.#queue(text);
493
494
  /* NOT FOR BROWSER ONLY */
494
- colors ??= (async () => {
495
+ if (colors === undefined) {
495
496
  try {
496
- return new RegExp(String.raw `\b${Object.keys((await import('color-name')).default).join('|')}\b`, 'giu');
497
+ const { default: colorName } = require('color-name');
498
+ colors = new RegExp(String.raw `\b${Object.keys(colorName).join('|')}\b`, 'giu');
497
499
  }
498
500
  catch {
499
- return false;
501
+ colors = false;
500
502
  }
501
- })();
502
- const re = await colors;
503
+ }
503
504
  /* NOT FOR BROWSER ONLY END */
504
505
  return root.querySelectorAll('attr-value,parameter-value,arg-default').reverse().flatMap(token => {
505
506
  const { type, childNodes,
@@ -515,13 +516,13 @@ class LanguageService {
515
516
  /* NOT FOR BROWSER ONLY END */
516
517
  }
517
518
  /* NOT FOR BROWSER ONLY */
518
- const isStyle = re && type === 'attr-value' && parentNode.name === 'style';
519
+ const isStyle = colors && type === 'attr-value' && parentNode.name === 'style';
519
520
  /* NOT FOR BROWSER ONLY END */
520
521
  return childNodes.filter((child) => child.type === 'text').reverse().flatMap(child => {
521
522
  const { data } = child, parts = (0, common_1.splitColors)(data, hsl).filter(([, , , isColor]) => isColor);
522
523
  /* NOT FOR BROWSER ONLY */
523
524
  if (isStyle) {
524
- parts.push(...[...data.matchAll(re)].map(({ index, 0: s }) => [s, index, index + s.length, true]));
525
+ parts.push(...[...data.matchAll(colors)].map(({ index, 0: s }) => [s, index, index + s.length, true]));
525
526
  }
526
527
  /* NOT FOR BROWSER ONLY END */
527
528
  if (parts.length === 0) {
@@ -687,6 +688,9 @@ class LanguageService {
687
688
  let type, parentNode;
688
689
  if (mt?.[8] === undefined) {
689
690
  cur = root.elementFromPoint(character, line);
691
+ if (!cur) {
692
+ return undefined;
693
+ }
690
694
  ({ type, parentNode } = cur);
691
695
  }
692
696
  if (mt?.[7] !== undefined || type === 'image-parameter') { // image parameter
@@ -762,7 +766,7 @@ class LanguageService {
762
766
  },
763
767
  }));
764
768
  }
765
- else if (type === 'ext-inner' && document_1.jsonTags.includes(cur.name)) {
769
+ else if (type === 'ext-inner' && constants_2.jsonTags.includes(cur.name)) {
766
770
  const jsonLSP = (0, document_1.loadJsonLSP)();
767
771
  if (!jsonLSP) {
768
772
  return undefined;
@@ -780,15 +784,12 @@ class LanguageService {
780
784
  && (before[comment + 1] === '{' || !before.slice(comment).includes('\n'))) {
781
785
  return undefined;
782
786
  }
783
- const word = /\\?\b(?:\w|\b(?:->?|\.)|\bly:)+$/u.exec(curLine.slice(0, character))?.[0];
787
+ const word = /(?<!\\)\\[-a-z]+$/u.exec(curLine.slice(0, character))?.[0];
784
788
  if (word) {
785
- const data = this.#lilypondData;
786
- return word.startsWith('\\')
787
- ? getCompletion(data.filter(w => w.startsWith('\\')), 'Function', word, position)
788
- : [
789
- ...getCompletion(data.filter(w => /^[a-z]/u.test(w)), 'Variable', word, position),
790
- ...getCompletion(data.filter(w => /^[A-Z]/u.test(w)), 'Class', word, position),
791
- ];
789
+ const words = parentNode.hasAttr('raw')
790
+ ? this.#lilypondData
791
+ : this.#lilypondData.filter(c => !rawLilyPondCommands.has(c));
792
+ return getCompletion(words, 'Function', word, position);
792
793
  }
793
794
  }
794
795
  else if (type === 'ext-inner' && constants_1.mathTags.has(cur.name)) {
@@ -822,7 +823,7 @@ class LanguageService {
822
823
  const root = await this.#queue(text), { lintConfig } = index_1.default, needFix = lintConfig.fix;
823
824
  lintConfig.fix = false;
824
825
  /* NOT FOR BROWSER ONLY */
825
- const stylelint = await (0, document_1.loadStylelint)(), jsonLSP = (0, document_1.loadJsonLSP)();
826
+ const stylelint = (0, document_1.loadStylelint)(), jsonLSP = (0, document_1.loadJsonLSP)();
826
827
  let s;
827
828
  NPM: if (jsonLSP) {
828
829
  s = lintConfig.rules['invalid-json'];
@@ -1188,7 +1189,11 @@ class LanguageService {
1188
1189
  * @param position position / 位置
1189
1190
  */
1190
1191
  async provideDefinition(text, position) {
1191
- const root = await this.#queue(text), node = root.elementFromPoint(position.character, position.line), ext = node.is('ext') && node.name === 'ref'
1192
+ const root = await this.#queue(text), node = root.elementFromPoint(position.character, position.line);
1193
+ if (!node) {
1194
+ return undefined;
1195
+ }
1196
+ const ext = node.is('ext') && node.name === 'ref'
1192
1197
  ? node
1193
1198
  : node.closest('ext#ref'), refName = getRefTagAttr(ext, 'name');
1194
1199
  if (!refName) {
@@ -1209,7 +1214,11 @@ class LanguageService {
1209
1214
  * @param position position / 位置
1210
1215
  */
1211
1216
  async resolveRenameLocation(text, position) {
1212
- const root = await this.#queue(text), node = root.elementFromPoint(position.character, position.line), { type } = node, refName = getRefName(node), refGroup = getRefGroup(node);
1217
+ const root = await this.#queue(text), node = root.elementFromPoint(position.character, position.line);
1218
+ if (!node) {
1219
+ return undefined;
1220
+ }
1221
+ const { type } = node, refName = getRefName(node), refGroup = getRefGroup(node);
1213
1222
  return !refName && !refGroup && (!renameTypes.has(type)
1214
1223
  || type === 'parameter-key' && /^[1-9]\d*$/u.test(node.parentNode.name)
1215
1224
  || type === 'link-target' && !['link', 'redirect-target'].includes(node.parentNode.type))
@@ -1225,7 +1234,11 @@ class LanguageService {
1225
1234
  * @param newName new name / 新名称
1226
1235
  */
1227
1236
  async provideRenameEdits(text, position, newName) {
1228
- 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 => {
1237
+ const root = await this.#queue(text), node = root.elementFromPoint(position.character, position.line);
1238
+ if (!node) {
1239
+ return undefined;
1240
+ }
1241
+ const { type } = node, refName = getRefName(node), refNameGroup = refName && getRefTagAttr(node.parentNode.parentNode, 'group'), refGroup = getRefGroup(node), name = getName(node), refs = root.querySelectorAll(type).filter(token => {
1229
1242
  const { type: t } = token.parentNode;
1230
1243
  if (type === 'link-target' && t !== 'link' && t !== 'redirect-target') {
1231
1244
  return false;
@@ -1314,7 +1327,7 @@ class LanguageService {
1314
1327
  const textDoc = new document_1.EmbeddedCSSDocument(root, offsetNode);
1315
1328
  return (0, document_1.loadCssLSP)().doHover(textDoc, position, textDoc.styleSheet) ?? undefined;
1316
1329
  }
1317
- else if (type === 'ext-inner' && document_1.jsonTags.includes(name)) {
1330
+ else if (type === 'ext-inner' && constants_2.jsonTags.includes(name)) {
1318
1331
  const jsonLSP = (0, document_1.loadJsonLSP)();
1319
1332
  if (!jsonLSP) {
1320
1333
  return undefined;
@@ -1434,8 +1447,12 @@ class LanguageService {
1434
1447
  return hints;
1435
1448
  }
1436
1449
  /** @private */
1450
+ querySelectorAll(selector) {
1451
+ return this.#done.querySelectorAll(selector);
1452
+ }
1453
+ /** @private */
1437
1454
  findStyleTokens() {
1438
- return this.#done.querySelectorAll(cssSelector).filter(({ lastChild }) => isAttr(lastChild));
1455
+ return this.querySelectorAll(cssSelector).filter(({ lastChild }) => isAttr(lastChild));
1439
1456
  }
1440
1457
  /**
1441
1458
  * Provide refactoring actions
@@ -1577,7 +1594,7 @@ class LanguageService {
1577
1594
  async setTargetWikipedia(wiki, user) {
1578
1595
  const [site, host] = index_1.default.getWMFSite(wiki);
1579
1596
  try {
1580
- const config = require(path_1.default.join('..', '..', 'config', site));
1597
+ const config = require(path_1.default.join('..', '..', 'config', `${site}.json`));
1581
1598
  this.config = index_1.default.getConfig(config);
1582
1599
  }
1583
1600
  catch {
package/dist/lib/node.js CHANGED
@@ -196,10 +196,13 @@ let AstNode = (() => {
196
196
  : 0;
197
197
  }
198
198
  return (0, lint_1.cache)(this.#rIndex[j], () => {
199
- const { childNodes } = this, n = j + (j < 0 ? childNodes.length : 0);
199
+ const { childNodes } = this, parentAIndex = this.#aIndex?.[0] === debug_1.Shadow.rev && this.#aIndex[1], n = j + (j < 0 ? childNodes.length : 0);
200
200
  let acc = this.getAttribute('padding');
201
201
  for (let i = 0; i < n; i++) {
202
202
  this.#rIndex[i] = [debug_1.Shadow.rev, acc];
203
+ if (parentAIndex !== false) {
204
+ childNodes[i].#aIndex = [debug_1.Shadow.rev, parentAIndex + acc];
205
+ }
203
206
  acc += childNodes[i].toString().length + this.getGaps(i);
204
207
  }
205
208
  return acc;
@@ -108,14 +108,18 @@ let ConverterFlagsToken = (() => {
108
108
  }
109
109
  /** @private */
110
110
  // eslint-disable-next-line @typescript-eslint/class-methods-use-this
111
- isInvalidFlag(flag, variant, unknown, valid) {
112
- return Boolean(flag) && !variant.has(flag) && !unknown.has(flag) && (variant.size > 0 || !valid.has(flag));
111
+ isInvalidFlag(flag, variant, unknown) {
112
+ return Boolean(flag)
113
+ && !variant.has(flag)
114
+ && !unknown.has(flag)
115
+ && (variant.size > 0 || !definedFlags.has(flag));
113
116
  }
114
117
  /** @private */
115
118
  lint(start = this.getAbsoluteIndex(), re) {
116
119
  LINT: {
117
- const variantFlags = this.getVariantFlags(), unknownFlags = this.getUnknownFlags(), validFlags = new Set(this.#flags.filter(flag => definedFlags.has(flag))), emptyFlagCount = this.#flags.filter(flag => !flag).length, knownFlagCount = this.#flags.length - unknownFlags.size - emptyFlagCount, { lintConfig } = index_1.default, { computeEditInfo, fix } = lintConfig, errors = super.lint(start, re);
118
- if (variantFlags.size === knownFlagCount || validFlags.size === knownFlagCount) {
120
+ const variantFlags = this.getVariantFlags(), unknownFlags = this.getUnknownFlags(), emptyFlagCount = this.#flags.filter(flag => !flag).length, knownFlagCount = this.#flags.length - unknownFlags.size - emptyFlagCount, { lintConfig } = index_1.default, { computeEditInfo, fix } = lintConfig, errors = super.lint(start, re);
121
+ if (variantFlags.size === knownFlagCount
122
+ || this.#flags.filter(flag => definedFlags.has(flag)).length === knownFlagCount) {
119
123
  return errors;
120
124
  }
121
125
  const rule = 'no-ignored', s = lintConfig.getSeverity(rule, 'conversionFlag');
@@ -123,7 +127,7 @@ let ConverterFlagsToken = (() => {
123
127
  const rect = new rect_1.BoundingRect(this, start);
124
128
  for (let i = 0; i < this.length; i++) {
125
129
  const child = this.childNodes[i], flag = child.text().trim();
126
- if (this.isInvalidFlag(flag, variantFlags, unknownFlags, validFlags)) {
130
+ if (this.isInvalidFlag(flag, variantFlags, unknownFlags)) {
127
131
  const e = (0, lint_1.generateForChild)(child, rect, rule, 'invalid-conversion-flag', s);
128
132
  if (computeEditInfo || fix) {
129
133
  if (variantFlags.size === 0 && definedFlags.has(flag.toUpperCase())) {
@@ -5,12 +5,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.NowikiToken = void 0;
7
7
  const common_1 = require("@bhsd/common");
8
+ const constants_1 = require("../../util/constants");
8
9
  const lint_1 = require("../../util/lint");
9
10
  const rect_1 = require("../../lib/rect");
10
11
  const index_1 = __importDefault(require("../../index"));
11
12
  const base_1 = require("./base");
12
13
  /* NOT FOR BROWSER ONLY */
13
- const constants_1 = require("../../util/constants");
14
+ const constants_2 = require("../../util/constants");
14
15
  const document_1 = require("../../lib/document");
15
16
  /** @ignore */
16
17
  const updateLocation = ({ startIndex, startLine, startCol, endIndex, endLine, endCol }, { offset, line, column }, n) => {
@@ -56,22 +57,10 @@ class NowikiToken extends base_1.NowikiBaseToken {
56
57
  }
57
58
  NPM: {
58
59
  rule = 'invalid-json';
59
- const sSyntax = lintConfig.getSeverity(rule);
60
- /* NOT FOR BROWSER ONLY */
61
- const sDuplicate = lintConfig.getSeverity(rule, 'duplicate');
62
- /* NOT FOR BROWSER ONLY END */
63
- if (name === 'templatedata' && (sSyntax
64
- || sDuplicate)) {
65
- // browser版本使用`lintJSONNative()`
66
- return (0, common_1.lintJSON)(innerText).map(({ message, from, to = from, line, endLine = line, column, endColumn = column,
67
- /* NOT FOR BROWSER ONLY */
68
- severity, }) => {
69
- s =
70
- /* eslint-disable @stylistic/operator-linebreak */
71
- severity === 'warning' ?
72
- sDuplicate :
73
- /* eslint-enable @stylistic/operator-linebreak */
74
- sSyntax;
60
+ const sSyntax = lintConfig.getSeverity(rule), sDuplicate = lintConfig.getSeverity(rule, 'duplicate');
61
+ if (constants_1.jsonTags.includes(name) && (sSyntax || sDuplicate)) {
62
+ return (name === 'templatedata' ? common_1.lintJSON : common_1.lintJSONC)(innerText).map(({ message, from, to = from, line, endLine = line, column, endColumn = column, severity, }) => {
63
+ s = severity === 'warning' ? sDuplicate : sSyntax;
75
64
  if (!s) {
76
65
  return false;
77
66
  }
@@ -92,7 +81,7 @@ class NowikiToken extends base_1.NowikiBaseToken {
92
81
  /* NOT FOR BROWSER ONLY */
93
82
  rule = 'invalid-math';
94
83
  s = lintConfig.getSeverity(rule);
95
- if (s && constants_1.mathTags.has(name)) {
84
+ if (s && constants_2.mathTags.has(name)) {
96
85
  const texvcjs = (0, document_1.loadTexvcjs)();
97
86
  if (texvcjs) {
98
87
  const isChem = name !== 'math', display = previousSibling?.getAttr('display') ?? 'block';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.mathTags = exports.extensions = exports.galleryParams = exports.enMsg = exports.BuildMethod = exports.MAX_STAGE = void 0;
3
+ exports.mathTags = exports.jsonTags = exports.extensions = exports.galleryParams = exports.enMsg = exports.BuildMethod = exports.MAX_STAGE = void 0;
4
4
  exports.MAX_STAGE = 11;
5
5
  var BuildMethod;
6
6
  (function (BuildMethod) {
@@ -13,5 +13,6 @@ exports.enMsg = (() => {
13
13
  })();
14
14
  exports.galleryParams = new Set(['alt', 'link', 'lang', 'page', 'caption']);
15
15
  exports.extensions = new Set(['tiff', 'tif', 'png', 'gif', 'jpg', 'jpeg', 'webp', 'xcf', 'pdf', 'svg', 'djvu']);
16
+ exports.jsonTags = ['templatedata', 'mapframe', 'maplink'];
16
17
  /* NOT FOR BROWSER ONLY */
17
18
  exports.mathTags = new Set(['math', 'chem', 'ce']);