wikilint 2.13.2 → 2.13.3

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.
@@ -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)) {
@@ -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
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wikilint",
3
- "version": "2.13.2",
3
+ "version": "2.13.3",
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.2",
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
  }