wikiparser-node 1.18.0 → 1.18.2

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.
@@ -51,7 +51,7 @@ const debug_1 = require("../util/debug");
51
51
  const document_1 = require("../lib/document");
52
52
  const fixed_1 = require("../mixin/fixed");
53
53
  const stages = { 'ext-attr': 0, 'html-attr': 2, 'table-attr': 3 };
54
- const insecureStyle = /expression|(?:accelerator|-o-link(?:-source)?|-o-replace)\s*:|(?:url|image(?:-set)?)\s*\(|attr\s*\([^)]+[\s,]url/u;
54
+ const insecureStyle = /expression|(?:accelerator|-o-link(?:-source)?|-o-replace)\s*:|(?:url|image(?:-set)?)\s*\(|attr\s*\([^)]+[\s,]url/u, complexTypes = new Set(['ext', 'arg', 'magic-word', 'template']);
55
55
  /**
56
56
  * attribute of extension and HTML tags
57
57
  *
@@ -201,9 +201,6 @@ let AttributeToken = (() => {
201
201
  e.suggestions = [{ desc: 'remove', range: [start, start + length], text: '' }];
202
202
  errors.push(e);
203
203
  }
204
- else if (sharable_1.obsoleteAttrs[tag]?.has(name)) {
205
- errors.push((0, lint_1.generateForChild)(firstChild, rect, 'obsolete-attr', 'obsolete attribute', 'warning'));
206
- }
207
204
  else if (name === 'style' && typeof value === 'string' && insecureStyle.test(value)) {
208
205
  errors.push((0, lint_1.generateForChild)(lastChild, rect, 'insecure-style', 'insecure style'));
209
206
  }
@@ -215,6 +212,15 @@ let AttributeToken = (() => {
215
212
  ];
216
213
  errors.push(e);
217
214
  }
215
+ else if (type !== 'ext-attr' && !lastChild.childNodes.some(({ type: t }) => complexTypes.has(t))) {
216
+ const data = lint_1.htmlData.provideValues(tag, name), v = String(value).toLowerCase();
217
+ if (data.length > 0 && data.every(({ name: n }) => n !== v)) {
218
+ errors.push((0, lint_1.generateForChild)(lastChild, rect, 'illegal-attr', 'illegal attribute value', 'warning'));
219
+ }
220
+ }
221
+ if (sharable_1.obsoleteAttrs[tag]?.has(name)) {
222
+ errors.push((0, lint_1.generateForChild)(firstChild, rect, 'obsolete-attr', 'obsolete attribute', 'warning'));
223
+ }
218
224
  return errors;
219
225
  }
220
226
  /**
package/dist/src/index.js CHANGED
@@ -61,6 +61,7 @@ const range_1 = require("../lib/range");
61
61
  /* NOT FOR BROWSER END */
62
62
  /* NOT FOR BROWSER ONLY */
63
63
  const document_1 = require("../lib/document");
64
+ const lsp_1 = require("../lib/lsp");
64
65
  /* NOT FOR BROWSER */
65
66
  /**
66
67
  * 可接受的Token类型
@@ -524,8 +525,7 @@ class Token extends element_1.AstElement {
524
525
  });
525
526
  /* NOT FOR BROWSER ONLY */
526
527
  }
527
- else if (document_1.cssLSP && this.type === 'attr-value' && this.length === 1 && this.firstChild.type === 'text'
528
- && this.parentNode.name === 'style') {
528
+ else if ((0, lsp_1.isAttr)(this, true)) {
529
529
  const root = this.getRootNode(), textDoc = new document_1.EmbeddedCSSDocument(root, this);
530
530
  errors.push(...document_1.cssLSP.doValidation(textDoc, textDoc.styleSheet)
531
531
  .filter(({ code }) => code !== 'css-ruleorselectorexpected')
@@ -62,6 +62,7 @@ let DoubleUnderscoreToken = (() => {
62
62
  if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
63
63
  __runInitializers(_classThis, _classExtraInitializers);
64
64
  }
65
+ /* NOT FOR BROWSER */
65
66
  #sensitive;
66
67
  /* NOT FOR BROWSER END */
67
68
  get type() {
@@ -73,10 +74,10 @@ let DoubleUnderscoreToken = (() => {
73
74
  */
74
75
  constructor(word, sensitive, config, accum) {
75
76
  super(word, config, accum);
77
+ const lc = word.toLowerCase(), { doubleUnderscore: [, , iAlias, sAlias] } = config;
78
+ this.setAttribute('name', (sensitive ? sAlias?.[word]?.toLowerCase() : iAlias?.[lc]) ?? lc);
76
79
  /* NOT FOR BROWSER */
77
- const lc = word.toLowerCase();
78
80
  this.#sensitive = sensitive;
79
- this.setAttribute('name', sensitive ? lc : config.doubleUnderscore[2]?.[lc] ?? lc);
80
81
  this.setAttribute('pattern', new RegExp(`^${word}$`, sensitive ? 'u' : 'iu'));
81
82
  }
82
83
  /** @private */
@@ -25,6 +25,7 @@ const basicMagicWords = new Map([['=', '='], ['!', '|']]);
25
25
  class TranscludeToken extends index_1.Token {
26
26
  modifier = '';
27
27
  #type = 'template';
28
+ #colon = ':';
28
29
  #raw = false;
29
30
  #args = new Map();
30
31
  #title;
@@ -60,7 +61,7 @@ class TranscludeToken extends index_1.Token {
60
61
  super(undefined, config, accum, {
61
62
  AtomToken: 0, SyntaxToken: 0, ParameterToken: '1:',
62
63
  });
63
- const { parserFunction: [insensitive, sensitive], variable } = config, argSubst = /^(?:\s|\0\d+[cn]\x7F)*\0\d+s\x7F/u.exec(title)?.[0];
64
+ const { parserFunction: [insensitive, sensitive], variable, functionHook } = config, argSubst = /^(?:\s|\0\d+[cn]\x7F)*\0\d+s\x7F/u.exec(title)?.[0];
64
65
  if (argSubst) {
65
66
  this.setAttribute('modifier', argSubst);
66
67
  title = title.slice(argSubst.length);
@@ -71,22 +72,28 @@ class TranscludeToken extends index_1.Token {
71
72
  title = arg.join(':').slice(mt.length);
72
73
  }
73
74
  }
74
- const isFunction = title.includes(':');
75
+ const colon = title.search(/[::]/u), fullWidth = title[colon] === '', isFunction = colon !== -1;
75
76
  if (isFunction || parts.length === 0 && !this.#raw) {
76
- const colon = title.indexOf(':'), magicWord = colon === -1 ? title : title.slice(0, colon), arg = colon === -1 ? undefined : title.slice(colon + 1), cleaned = (0, string_1.removeComment)(magicWord), name = cleaned[arg === undefined ? 'trim' : 'trimStart'](), lcName = name.toLowerCase(), isOldSchema = Array.isArray(sensitive), isSensitive = isOldSchema
77
+ const magicWord = isFunction ? title.slice(0, colon) : title, arg = isFunction && title.slice(colon + 1), cleaned = (0, string_1.removeComment)(magicWord), name = isFunction
78
+ ? cleaned.slice(cleaned.search(/\S/u)) + (fullWidth ? ':' : '')
79
+ : cleaned.trim(), lcName = name.toLowerCase(), isOldSchema = Array.isArray(sensitive), isSensitive = isOldSchema
77
80
  ? sensitive.includes(name)
78
81
  : Object.prototype.hasOwnProperty.call(sensitive, name), canonicalName = !isOldSchema && isSensitive
79
82
  ? sensitive[name]
80
- : Object.prototype.hasOwnProperty.call(insensitive, lcName) && insensitive[lcName], isVar = isOldSchema && isSensitive || variable.includes(canonicalName);
81
- if (isVar || isFunction && canonicalName) {
82
- this.setAttribute('name', canonicalName || lcName.replace(/^#/u, ''));
83
+ : Object.prototype.hasOwnProperty.call(insensitive, lcName) && insensitive[lcName], isFunc = isOldSchema && isSensitive
84
+ || !('functionHook' in config) || functionHook.includes(canonicalName), isVar = isOldSchema && isSensitive || variable.includes(canonicalName);
85
+ if (isFunction ? canonicalName && isFunc : isVar) {
86
+ this.setAttribute('name', canonicalName || lcName.replace(/^#|:$/u, ''));
83
87
  this.#type = 'magic-word';
88
+ if (fullWidth) {
89
+ this.#colon = ':';
90
+ }
84
91
  /^\s*uc\s*$/iu; // eslint-disable-line @typescript-eslint/no-unused-expressions
85
92
  const pattern = new RegExp(String.raw `^\s*${name}\s*$`, isSensitive ? 'u' : 'iu'), token = new syntax_1.SyntaxToken(magicWord, pattern, 'magic-word-name', config, accum, {
86
93
  'Stage-1': ':', '!ExtToken': '',
87
94
  });
88
95
  super.insertAt(token);
89
- if (arg !== undefined) {
96
+ if (arg !== false) {
90
97
  parts.unshift([arg]);
91
98
  }
92
99
  if (this.name === 'invoke') {
@@ -241,7 +248,7 @@ class TranscludeToken extends index_1.Token {
241
248
  toString(skip) {
242
249
  return `{{${this.modifier}${this.type === 'magic-word'
243
250
  ? this.firstChild.toString(skip)
244
- + (this.length === 1 ? '' : ':')
251
+ + (this.length === 1 ? '' : this.#colon)
245
252
  + this.childNodes.slice(1).map(child => child.toString(skip)).join('|')
246
253
  : super.toString(skip, '|')}}}`;
247
254
  }
@@ -251,7 +258,9 @@ class TranscludeToken extends index_1.Token {
251
258
  return type === 'magic-word' && name === 'vardefine'
252
259
  ? ''
253
260
  : `{{${modifier}${type === 'magic-word'
254
- ? firstChild.text() + (length === 1 ? '' : ':') + (0, string_1.text)(childNodes.slice(1), '|')
261
+ ? firstChild.text()
262
+ + (length === 1 ? '' : this.#colon)
263
+ + (0, string_1.text)(childNodes.slice(1), '|')
255
264
  : super.text('|')}}}`;
256
265
  }
257
266
  /** @private */
@@ -261,6 +270,8 @@ class TranscludeToken extends index_1.Token {
261
270
  return this.modifier.length + 2;
262
271
  case 'title':
263
272
  return this.#title;
273
+ case 'colon':
274
+ return this.#colon;
264
275
  /* NOT FOR BROWSER */
265
276
  case 'keys':
266
277
  return this.#keys;
@@ -468,7 +479,7 @@ class TranscludeToken extends index_1.Token {
468
479
  print() {
469
480
  const { childNodes, length, firstChild, modifier, type } = this;
470
481
  return `<span class="wpb-${type}">{{${(0, string_1.escape)(modifier)}${type === 'magic-word'
471
- ? firstChild.print() + (length === 1 ? '' : ':') + (0, string_1.print)(childNodes.slice(1), { sep: '|' })
482
+ ? firstChild.print() + (length === 1 ? '' : this.#colon) + (0, string_1.print)(childNodes.slice(1), { sep: '|' })
472
483
  : (0, string_1.print)(childNodes, { sep: '|' })}}}</span>`;
473
484
  }
474
485
  /* NOT FOR BROWSER */
@@ -476,7 +487,7 @@ class TranscludeToken extends index_1.Token {
476
487
  const [first, ...cloned] = this.cloneChildNodes(), config = this.getAttribute('config');
477
488
  return debug_1.Shadow.run(() => {
478
489
  // @ts-expect-error abstract class
479
- const token = new TranscludeToken(this.type === 'template' ? 'T' : `${first.text()}:`, [], config);
490
+ const token = new TranscludeToken(this.type === 'template' ? 'T' : first.text() + (cloned.length === 0 ? '' : this.#colon), [], config);
480
491
  if (this.#raw) {
481
492
  token.setModifier(this.modifier);
482
493
  }
@@ -484,7 +495,7 @@ class TranscludeToken extends index_1.Token {
484
495
  token.setAttribute('modifier', this.modifier);
485
496
  }
486
497
  token.firstChild.safeReplaceWith(first);
487
- if (this.type === 'magic-word') {
498
+ if (token.length > 1) {
488
499
  token.removeAt(1);
489
500
  }
490
501
  token.append(...cloned);
package/dist/util/diff.js CHANGED
@@ -73,7 +73,7 @@ const diff = async (oldStr, newStr, uid) => {
73
73
  newFile,
74
74
  ]);
75
75
  console.log(stdout?.split('\n').slice(4).join('\n'));
76
- await Promise.all([promises_1.default.unlink(oldFile), promises_1.default.unlink(newFile)]);
76
+ await Promise.allSettled([promises_1.default.unlink(oldFile), promises_1.default.unlink(newFile)]);
77
77
  };
78
78
  exports.diff = diff;
79
79
  /* istanbul ignore next */
package/dist/util/lint.js CHANGED
@@ -3,7 +3,7 @@ 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.cache = exports.generateForSelf = exports.generateForChild = exports.getEndPos = void 0;
6
+ exports.htmlData = exports.cache = exports.generateForSelf = exports.generateForChild = exports.getEndPos = void 0;
7
7
  const debug_1 = require("./debug");
8
8
  const rect_1 = require("../lib/rect");
9
9
  const index_1 = __importDefault(require("../index"));
@@ -65,3 +65,34 @@ const cache = (store, compute, update) => {
65
65
  return result;
66
66
  };
67
67
  exports.cache = cache;
68
+ exports.htmlData = (() => {
69
+ try {
70
+ return require('vscode-html-languageservice')
71
+ .getDefaultHTMLDataProvider();
72
+ }
73
+ catch {
74
+ /**
75
+ * 获取HTML属性值可选列表
76
+ * @param tag 标签名
77
+ * @param attribute 属性名
78
+ */
79
+ const provideValues = (tag, attribute) => {
80
+ if (tag === 'ol' && attribute === 'type') {
81
+ return ['1', 'a', 'A', 'i', 'I'];
82
+ }
83
+ else if (tag === 'th' && attribute === 'scope') {
84
+ return ['row', 'col', 'rowgroup', 'colgroup'];
85
+ }
86
+ else if (attribute === 'dir') {
87
+ return ['ltr', 'rtl', 'auto'];
88
+ }
89
+ return attribute === 'aria-hidden' ? ['true', 'false'] : [];
90
+ };
91
+ return {
92
+ /** @implements */
93
+ provideValues(tag, attribute) {
94
+ return provideValues(tag, attribute).map(value => ({ name: value }));
95
+ },
96
+ };
97
+ }
98
+ })();
@@ -1,6 +1,6 @@
1
1
  (() => {
2
2
  var _a;
3
- const version = '1.18.0', src = (_a = document.currentScript) === null || _a === void 0 ? void 0 : _a.src, file = /\/extensions\/dist\/base\.(?:min\.)?js$/u, CDN = src && file.test(src)
3
+ const version = '1.18.2', 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 = () => {
@@ -11,7 +11,6 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
11
11
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
12
12
  };
13
13
  var _LanguageService_id, _LanguageService_include;
14
- let data;
15
14
  class LanguageService {
16
15
  get include() {
17
16
  return __classPrivateFieldGet(this, _LanguageService_include, "f");
@@ -21,10 +20,6 @@ class LanguageService {
21
20
  _LanguageService_include.set(this, void 0);
22
21
  __classPrivateFieldSet(this, _LanguageService_id, wikiparse.id++, "f");
23
22
  __classPrivateFieldSet(this, _LanguageService_include, include, "f");
24
- data !== null && data !== void 0 ? data : (data = (async () => (await fetch(`${wikiparse.CDN}/data/signatures.json`)).json())());
25
- (async () => {
26
- wikiparse.provide('data', __classPrivateFieldGet(this, _LanguageService_id, "f"), await data, __classPrivateFieldGet(this, _LanguageService_include, "f"));
27
- })();
28
23
  }
29
24
  destroy() {
30
25
  wikiparse.provide('destroy', __classPrivateFieldGet(this, _LanguageService_id, "f"));
@@ -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.18.0', src = (_a = document.currentScript) === null || _a === void 0 ? void 0 : _a.src, file = /\/extensions\/dist\/base\.(?:min\.)?js$/u, CDN = src && file.test(src)
12
+ const version = '1.18.2', 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 = () => {
package/i18n/zh-hans.json CHANGED
@@ -21,6 +21,7 @@
21
21
  "HTML comment": "HTML注释",
22
22
  "HTML tag in table attributes": "表格属性中的HTML标签",
23
23
  "illegal attribute name": "非法的属性名",
24
+ "illegal attribute value": "非法的属性值",
24
25
  "illegal module name": "非法的模块名称",
25
26
  "inconsistent table layout": "不一致的表格布局",
26
27
  "insecure style": "不安全的样式",
package/i18n/zh-hant.json CHANGED
@@ -21,6 +21,7 @@
21
21
  "HTML comment": "HTML註釋",
22
22
  "HTML tag in table attributes": "表格屬性中的HTML標籤",
23
23
  "illegal attribute name": "非法的屬性名",
24
+ "illegal attribute value": "非法的屬性值",
24
25
  "illegal module name": "非法的模組名稱",
25
26
  "inconsistent table layout": "不一致的表格佈局",
26
27
  "insecure style": "不安全的樣式",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wikiparser-node",
3
- "version": "1.18.0",
3
+ "version": "1.18.2",
4
4
  "description": "A Node.js parser for MediaWiki markup with AST",
5
5
  "keywords": [
6
6
  "mediawiki",
@@ -55,7 +55,7 @@
55
55
  "diff": "bash diff.sh",
56
56
  "diff:stat": "f() { git diff --stat --ignore-all-space --color=always $1 $2 -- . | grep '\\.ts'; }; f",
57
57
  "lint:ts": "tsc --noEmit && eslint --cache .",
58
- "lint:json": "v8r -s config/.schema.json config/*.json && v8r -s data/.schema.json data/*.json && node dist/test/json.js",
58
+ "lint:json": "v8r -s config/.schema.json config/*.json && v8r -s data/.schema.json data/*.json && mocha dist/test/json.js",
59
59
  "lint": "npm run lint:ts && npm run lint:json",
60
60
  "prof": "node dist/test/prof.js",
61
61
  "coverage": "nyc --cache-dir=./.cache/nyc npm test && node dist/script/coverage.js && open coverage/index.html",
@@ -77,20 +77,23 @@
77
77
  ]
78
78
  },
79
79
  "dependencies": {
80
- "@bhsd/common": "^0.8.0",
80
+ "@bhsd/common": "^0.8.1",
81
81
  "vscode-languageserver-types": "^3.17.5"
82
82
  },
83
83
  "optionalDependencies": {
84
84
  "chalk": "^4.1.2",
85
+ "color-name": "^2.0.0",
85
86
  "entities": "^6.0.0",
86
87
  "stylelint": "^16.14.1",
87
88
  "vscode-css-languageservice": "^6.3.2",
89
+ "vscode-html-languageservice": "^5.3.1",
88
90
  "vscode-json-languageservice": "^5.4.3"
89
91
  },
90
92
  "devDependencies": {
91
93
  "@codemirror/lint": "^6.8.4",
92
94
  "@stylistic/eslint-plugin": "^3.1.0",
93
95
  "@stylistic/stylelint-plugin": "^3.1.2",
96
+ "@types/color-name": "^2.0.0",
94
97
  "@types/color-rgba": "^2.1.3",
95
98
  "@types/mocha": "^10.0.10",
96
99
  "@types/node": "^22.13.1",