wikilint 2.13.2 → 2.13.4

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.
@@ -383,7 +383,6 @@
383
383
  "#匹配式": "ifeq",
384
384
  "#若相等": "ifeq",
385
385
  "#如果相等": "ifeq",
386
- "#若表達式": "ifeq",
387
386
  "#ifeq": "ifeq",
388
387
  "#多选式": "switch",
389
388
  "#多条件式": "switch",
@@ -397,6 +396,7 @@
397
396
  "#如有": "ifexist",
398
397
  "#ifexist": "ifexist",
399
398
  "#若表达式": "ifexpr",
399
+ "#若表達式": "ifexpr",
400
400
  "#ifexpr": "ifexpr",
401
401
  "#错误式": "iferror",
402
402
  "#如果错误": "iferror",
@@ -364,7 +364,6 @@
364
364
  "#匹配式": "ifeq",
365
365
  "#若相等": "ifeq",
366
366
  "#如果相等": "ifeq",
367
- "#若表達式": "ifeq",
368
367
  "#ifeq": "ifeq",
369
368
  "#多选式": "switch",
370
369
  "#多条件式": "switch",
@@ -378,6 +377,7 @@
378
377
  "#如有": "ifexist",
379
378
  "#ifexist": "ifexist",
380
379
  "#若表达式": "ifexpr",
380
+ "#若表達式": "ifexpr",
381
381
  "#ifexpr": "ifexpr",
382
382
  "#错误式": "iferror",
383
383
  "#如果错误": "iferror",
@@ -4,169 +4,12 @@ exports.AttributeToken = void 0;
4
4
  const lint_1 = require("../util/lint");
5
5
  const string_1 = require("../util/string");
6
6
  const constants_1 = require("../util/constants");
7
+ const sharable_1 = require("../util/sharable");
7
8
  const rect_1 = require("../lib/rect");
8
9
  const index_1 = require("../index");
9
10
  const index_2 = require("./index");
10
11
  const atom_1 = require("./atom");
11
- const commonHtmlAttrs = new Set([
12
- 'id',
13
- 'class',
14
- 'style',
15
- 'lang',
16
- 'dir',
17
- 'title',
18
- 'tabindex',
19
- 'aria-describedby',
20
- 'aria-flowto',
21
- 'aria-hidden',
22
- 'aria-label',
23
- 'aria-labelledby',
24
- 'aria-level',
25
- 'aria-owns',
26
- 'role',
27
- 'about',
28
- 'property',
29
- 'resource',
30
- 'datatype',
31
- 'typeof',
32
- 'itemid',
33
- 'itemprop',
34
- 'itemref',
35
- 'itemscope',
36
- 'itemtype',
37
- ]), blockAttrs = new Set(['align']), citeAttrs = new Set(['cite']), citeAndAttrs = new Set(['cite', 'datetime']), widthAttrs = new Set(['width']), obsoleteTdAttrs = new Set(['axis', 'align', 'bgcolor', 'height', 'width', 'valign']), tdAttrs = new Set([...obsoleteTdAttrs, 'abbr', 'headers', 'scope', 'rowspan', 'colspan']), typeAttrs = new Set(['type']), obsoleteTableAttrs = new Set(['summary', 'align', 'bgcolor', 'cellpadding', 'cellspacing', 'frame', 'rules', 'width']), brAttrs = new Set(['clear']), trAttrs = new Set(['bgcolor', 'align', 'valign']), htmlAttrs = {
38
- div: blockAttrs,
39
- h1: blockAttrs,
40
- h2: blockAttrs,
41
- h3: blockAttrs,
42
- h4: blockAttrs,
43
- h5: blockAttrs,
44
- h6: blockAttrs,
45
- blockquote: citeAttrs,
46
- q: citeAttrs,
47
- p: blockAttrs,
48
- br: brAttrs,
49
- pre: widthAttrs,
50
- ins: citeAndAttrs,
51
- del: citeAndAttrs,
52
- ul: typeAttrs,
53
- ol: new Set(['type', 'start', 'reversed']),
54
- li: new Set(['type', 'value']),
55
- table: new Set([...obsoleteTableAttrs, 'border']),
56
- caption: blockAttrs,
57
- tr: trAttrs,
58
- td: tdAttrs,
59
- th: tdAttrs,
60
- img: new Set(['alt', 'src', 'width', 'height', 'srcset']),
61
- font: new Set(['size', 'color', 'face']),
62
- hr: widthAttrs,
63
- data: new Set(['value']),
64
- time: new Set(['datetime']),
65
- meta: new Set(['itemprop', 'content']),
66
- link: new Set(['itemprop', 'href', 'title']),
67
- gallery: typeAttrs,
68
- poem: blockAttrs,
69
- categorytree: blockAttrs,
70
- combooption: blockAttrs,
71
- }, empty = new Set(), extAttrs = {
72
- gallery: new Set(['mode', 'showfilename', 'caption', 'perrow', 'widths', 'heights', 'showthumbnails']),
73
- poem: new Set(['compact']),
74
- categorytree: new Set([
75
- 'hideroot',
76
- 'onlyroot',
77
- 'depth',
78
- 'mode',
79
- 'hideprefix',
80
- 'namespaces',
81
- 'showcount',
82
- 'notranslations',
83
- ]),
84
- combooption: new Set(['name', 'for', 'inline']),
85
- nowiki: empty,
86
- indicator: new Set(['name']),
87
- langconvert: new Set(['from', 'to']),
88
- ref: new Set(['group', 'name', 'extends', 'follow', 'dir']),
89
- references: new Set(['group', 'responsive']),
90
- charinsert: new Set(['label']),
91
- choose: new Set(['uncached', 'before', 'after']),
92
- option: new Set(['weight']),
93
- imagemap: empty,
94
- inputbox: empty,
95
- templatestyles: new Set(['src', 'wrapper']),
96
- dynamicpagelist: empty,
97
- poll: new Set(['id', 'show-results-before-voting']),
98
- sm2: typeAttrs,
99
- flashmp3: typeAttrs,
100
- score: new Set([
101
- 'line_width_inches',
102
- 'lang',
103
- 'override_midi',
104
- 'raw',
105
- 'note-language',
106
- 'override_audio',
107
- 'override_ogg',
108
- 'sound',
109
- 'vorbis',
110
- ]),
111
- seo: new Set([
112
- 'title',
113
- 'title_mode',
114
- 'title_separator',
115
- 'keywords',
116
- 'description',
117
- 'robots',
118
- 'google_bot',
119
- 'image',
120
- 'image_width',
121
- 'image_height',
122
- 'image_alt',
123
- 'type',
124
- 'site_name',
125
- 'locale',
126
- 'section',
127
- 'author',
128
- 'published_time',
129
- 'twitter_site',
130
- ]),
131
- tab: new Set([
132
- 'nested',
133
- 'name',
134
- 'index',
135
- 'class',
136
- 'block',
137
- 'inline',
138
- 'openname',
139
- 'closename',
140
- 'collapsed',
141
- 'dropdown',
142
- 'style',
143
- 'bgcolor',
144
- 'container',
145
- 'id',
146
- 'title',
147
- ]),
148
- tabs: new Set(['plain', 'class', 'container', 'id', 'title', 'style']),
149
- combobox: new Set(['placeholder', 'value', 'id', 'class', 'text', 'dropdown', 'style']),
150
- }, insecureStyle = /expression|(?:accelerator|-o-link(?:-source)?|-o-replace)\s*:|(?:url|image(?:-set)?)\s*\(|attr\s*\([^)]+[\s,]url/u, obsoleteAttrs = {
151
- table: obsoleteTableAttrs,
152
- td: new Set([...obsoleteTdAttrs, 'scope']),
153
- th: obsoleteTdAttrs,
154
- br: brAttrs,
155
- caption: blockAttrs,
156
- div: blockAttrs,
157
- hr: widthAttrs,
158
- h1: blockAttrs,
159
- h2: blockAttrs,
160
- h3: blockAttrs,
161
- h4: blockAttrs,
162
- h5: blockAttrs,
163
- h6: blockAttrs,
164
- li: typeAttrs,
165
- p: blockAttrs,
166
- pre: widthAttrs,
167
- tr: trAttrs,
168
- ul: typeAttrs,
169
- };
12
+ const insecureStyle = /expression|(?:accelerator|-o-link(?:-source)?|-o-replace)\s*:|(?:url|image(?:-set)?)\s*\(|attr\s*\([^)]+[\s,]url/u;
170
13
  /**
171
14
  * 扩展和HTML标签属性
172
15
  * @classdesc `{childNodes: [AtomToken, Token|AtomToken]}`
@@ -269,16 +112,17 @@ class AttributeToken extends index_2.Token {
269
112
  }
270
113
  errors.push(e);
271
114
  }
272
- const attrs = extAttrs[tag];
115
+ const attrs = sharable_1.extAttrs[tag], attrs2 = sharable_1.htmlAttrs[tag];
273
116
  if (!attrs?.has(name)
274
- && (type === 'ext-attr' ? attrs : !/\{\{[^{]+\}\}/u.test(name))
275
- && (type === 'ext-attr' && !(tag in htmlAttrs)
276
- || !htmlAttrs[tag]?.has(name)
277
- && !/^(?:xmlns:[\w:.-]+|data-(?!ooui|mw|parsoid)[^:]*)$/u.test(name)
278
- && (tag === 'meta' || tag === 'link' || !commonHtmlAttrs.has(name)))) {
117
+ && !attrs2?.has(name)
118
+ // 不是未定义的扩展标签或包含嵌入的HTML标签
119
+ && (type === 'ext-attr' ? attrs || attrs2 : !/\{\{[^{]+\}\}/u.test(name))
120
+ && (type === 'ext-attr' && !attrs2
121
+ || !/^(?:xmlns:[\w:.-]+|data-(?!ooui|mw|parsoid)[^:]*)$/u.test(name)
122
+ && (tag === 'meta' || tag === 'link' || !sharable_1.commonHtmlAttrs.has(name)))) {
279
123
  errors.push((0, lint_1.generateForChild)(firstChild, rect, 'illegal-attr', 'illegal attribute name'));
280
124
  }
281
- else if (obsoleteAttrs[tag]?.has(name)) {
125
+ else if (sharable_1.obsoleteAttrs[tag]?.has(name)) {
282
126
  errors.push((0, lint_1.generateForChild)(firstChild, rect, 'obsolete-attr', 'obsolete attribute', 'warning'));
283
127
  }
284
128
  else if (name === 'style' && typeof value === 'string' && insecureStyle.test(value)) {
@@ -59,7 +59,7 @@ class TranscludeToken extends index_2.Token {
59
59
  if (isFunction || parts.length === 0 && !this.#raw) {
60
60
  const [magicWord, ...arg] = title.split(':'), cleaned = (0, string_1.removeComment)(magicWord), name = cleaned[arg.length > 0 ? 'trimStart' : 'trim'](), lcName = name.toLowerCase(), canonicalName = Object.prototype.hasOwnProperty.call(insensitive, lcName) && insensitive[lcName], isSensitive = sensitive.includes(name), isVar = isSensitive || insensitiveVars.has(canonicalName);
61
61
  if (isVar || isFunction && canonicalName) {
62
- this.setAttribute('name', canonicalName || lcName);
62
+ this.setAttribute('name', canonicalName || lcName.replace(/^#/u, ''));
63
63
  this.#type = 'magic-word';
64
64
  const pattern = new RegExp(String.raw `^\s*${name}\s*$`, isSensitive ? 'u' : 'iu'), token = new syntax_1.SyntaxToken(magicWord, pattern, 'magic-word-name', config, accum, {});
65
65
  super.insertAt(token);
@@ -0,0 +1 @@
1
+ export declare const commonHtmlAttrs: Set<string>, htmlAttrs: Record<string, Set<string>>, extAttrs: Record<string, Set<string>>, obsoleteAttrs: Record<string, Set<string>>;
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.obsoleteAttrs = exports.extAttrs = exports.htmlAttrs = exports.commonHtmlAttrs = void 0;
4
+ const blockAttrs = new Set(['align']), citeAttrs = new Set(['cite']), citeAndAttrs = new Set(['cite', 'datetime']), widthAttrs = new Set(['width']), obsoleteTdAttrs = new Set(['axis', 'align', 'bgcolor', 'height', 'width', 'valign']), tdAttrs = new Set([...obsoleteTdAttrs, 'abbr', 'headers', 'scope', 'rowspan', 'colspan']), typeAttrs = new Set(['type']), obsoleteTableAttrs = new Set(['summary', 'align', 'bgcolor', 'cellpadding', 'cellspacing', 'frame', 'rules', 'width']), brAttrs = new Set(['clear']), trAttrs = new Set(['bgcolor', 'align', 'valign']), empty = new Set();
5
+ exports.commonHtmlAttrs = new Set([
6
+ 'id',
7
+ 'class',
8
+ 'style',
9
+ 'lang',
10
+ 'dir',
11
+ 'title',
12
+ 'tabindex',
13
+ 'aria-describedby',
14
+ 'aria-flowto',
15
+ 'aria-hidden',
16
+ 'aria-label',
17
+ 'aria-labelledby',
18
+ 'aria-level',
19
+ 'aria-owns',
20
+ 'role',
21
+ 'about',
22
+ 'property',
23
+ 'resource',
24
+ 'datatype',
25
+ 'typeof',
26
+ 'itemid',
27
+ 'itemprop',
28
+ 'itemref',
29
+ 'itemscope',
30
+ 'itemtype',
31
+ ]), exports.htmlAttrs = {
32
+ div: blockAttrs,
33
+ h1: blockAttrs,
34
+ h2: blockAttrs,
35
+ h3: blockAttrs,
36
+ h4: blockAttrs,
37
+ h5: blockAttrs,
38
+ h6: blockAttrs,
39
+ blockquote: citeAttrs,
40
+ q: citeAttrs,
41
+ p: blockAttrs,
42
+ br: brAttrs,
43
+ pre: widthAttrs,
44
+ ins: citeAndAttrs,
45
+ del: citeAndAttrs,
46
+ ul: typeAttrs,
47
+ ol: new Set(['type', 'start', 'reversed']),
48
+ li: new Set(['type', 'value']),
49
+ table: new Set([...obsoleteTableAttrs, 'border']),
50
+ caption: blockAttrs,
51
+ tr: trAttrs,
52
+ td: tdAttrs,
53
+ th: tdAttrs,
54
+ img: new Set(['alt', 'src', 'width', 'height', 'srcset']),
55
+ font: new Set(['size', 'color', 'face']),
56
+ hr: widthAttrs,
57
+ data: new Set(['value']),
58
+ time: new Set(['datetime']),
59
+ meta: new Set(['itemprop', 'content']),
60
+ link: new Set(['itemprop', 'href', 'title']),
61
+ gallery: typeAttrs,
62
+ poem: blockAttrs,
63
+ categorytree: blockAttrs,
64
+ combooption: blockAttrs,
65
+ }, exports.extAttrs = {
66
+ gallery: new Set(['mode', 'showfilename', 'caption', 'perrow', 'widths', 'heights', 'showthumbnails']),
67
+ poem: new Set(['compact']),
68
+ categorytree: new Set([
69
+ 'hideroot',
70
+ 'onlyroot',
71
+ 'depth',
72
+ 'mode',
73
+ 'hideprefix',
74
+ 'namespaces',
75
+ 'showcount',
76
+ 'notranslations',
77
+ ]),
78
+ combooption: new Set(['name', 'for', 'inline']),
79
+ nowiki: empty,
80
+ indicator: new Set(['name']),
81
+ langconvert: new Set(['from', 'to']),
82
+ ref: new Set(['group', 'name', 'extends', 'follow', 'dir']),
83
+ references: new Set(['group', 'responsive']),
84
+ charinsert: new Set(['label']),
85
+ choose: new Set(['uncached', 'before', 'after']),
86
+ option: new Set(['weight']),
87
+ imagemap: empty,
88
+ inputbox: empty,
89
+ templatestyles: new Set(['src', 'wrapper']),
90
+ dynamicpagelist: empty,
91
+ poll: new Set(['id', 'show-results-before-voting']),
92
+ sm2: typeAttrs,
93
+ flashmp3: typeAttrs,
94
+ score: new Set([
95
+ 'line_width_inches',
96
+ 'lang',
97
+ 'override_midi',
98
+ 'raw',
99
+ 'note-language',
100
+ 'override_audio',
101
+ 'override_ogg',
102
+ 'sound',
103
+ 'vorbis',
104
+ ]),
105
+ seo: new Set([
106
+ 'title',
107
+ 'title_mode',
108
+ 'title_separator',
109
+ 'keywords',
110
+ 'description',
111
+ 'robots',
112
+ 'google_bot',
113
+ 'image',
114
+ 'image_width',
115
+ 'image_height',
116
+ 'image_alt',
117
+ 'type',
118
+ 'site_name',
119
+ 'locale',
120
+ 'section',
121
+ 'author',
122
+ 'published_time',
123
+ 'twitter_site',
124
+ ]),
125
+ tab: new Set([
126
+ 'nested',
127
+ 'name',
128
+ 'index',
129
+ 'class',
130
+ 'block',
131
+ 'inline',
132
+ 'openname',
133
+ 'closename',
134
+ 'collapsed',
135
+ 'dropdown',
136
+ 'style',
137
+ 'bgcolor',
138
+ 'container',
139
+ 'id',
140
+ 'title',
141
+ ]),
142
+ tabs: new Set(['plain', 'class', 'container', 'id', 'title', 'style']),
143
+ combobox: new Set(['placeholder', 'value', 'id', 'class', 'text', 'dropdown', 'style']),
144
+ }, exports.obsoleteAttrs = {
145
+ table: obsoleteTableAttrs,
146
+ td: new Set([...obsoleteTdAttrs, 'scope']),
147
+ th: obsoleteTdAttrs,
148
+ br: brAttrs,
149
+ caption: blockAttrs,
150
+ div: blockAttrs,
151
+ hr: widthAttrs,
152
+ h1: blockAttrs,
153
+ h2: blockAttrs,
154
+ h3: blockAttrs,
155
+ h4: blockAttrs,
156
+ h5: blockAttrs,
157
+ h6: blockAttrs,
158
+ li: typeAttrs,
159
+ p: blockAttrs,
160
+ pre: widthAttrs,
161
+ tr: trAttrs,
162
+ ul: typeAttrs,
163
+ };
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.noWrap = exports.decodeNumber = exports.decodeHtml = exports.text = exports.rawurldecode = exports.escapeRegExp = exports.removeComment = exports.tidy = exports.extUrlChar = exports.extUrlCharFirst = void 0;
3
+ exports.noWrap = exports.decodeNumber = exports.decodeHtml = exports.text = exports.escapeRegExp = exports.removeComment = exports.tidy = exports.extUrlChar = exports.extUrlCharFirst = exports.rawurldecode = void 0;
4
+ var common_1 = require("@bhsd/common");
5
+ Object.defineProperty(exports, "rawurldecode", { enumerable: true, get: function () { return common_1.rawurldecode; } });
4
6
  const commonExtUrlChar = String.raw `[^[\]<>"\0-\x1F\x7F\p{Zs}\uFFFD]`;
5
7
  exports.extUrlCharFirst = String.raw `(?:\[[\da-f:.]+\]|${commonExtUrlChar})`;
6
8
  exports.extUrlChar = String.raw `(?:${commonExtUrlChar}|\0\d+[cn!~]\x7F)*`;
@@ -16,12 +18,6 @@ exports.tidy = factory(/[\0\x7F]|\r$/gmu, '');
16
18
  exports.removeComment = factory(/\0\d+[cn]\x7F/gu, '');
17
19
  /** escape special chars for RegExp constructor */
18
20
  exports.escapeRegExp = factory(/[\\{}()|.?*+^$[\]]/gu, String.raw `\$&`);
19
- /**
20
- * PHP的`rawurldecode`函数的JavaScript实现
21
- * @param str 要解码的字符串
22
- */
23
- const rawurldecode = (str) => decodeURIComponent(str.replace(/%(?![\da-f]{2})/giu, '%25'));
24
- exports.rawurldecode = rawurldecode;
25
21
  /**
26
22
  * extract effective wikitext
27
23
  * @param childNodes a Token's contents
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wikilint",
3
- "version": "2.13.2",
3
+ "version": "2.13.4",
4
4
  "description": "A Node.js linter for MediaWiki markup",
5
5
  "keywords": [
6
6
  "mediawiki",
@@ -51,11 +51,11 @@
51
51
  "chalk": "^4.1.2"
52
52
  },
53
53
  "devDependencies": {
54
- "@bhsd/common": "^0.3.0",
55
- "@types/node": "^20.11.6",
54
+ "@bhsd/common": "^0.4.3",
55
+ "@types/node": "^22.9.0",
56
56
  "v8r": "^3.0.0"
57
57
  },
58
58
  "engines": {
59
- "node": ">=20.9.0"
59
+ "node": ">=22.11.0"
60
60
  }
61
61
  }