wikiparser-node 1.21.2 → 1.22.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 (97) hide show
  1. package/README.md +9 -5
  2. package/bundle/bundle-es8.min.js +25 -25
  3. package/bundle/bundle-lsp.min.js +26 -26
  4. package/bundle/bundle.min.js +25 -25
  5. package/config/default.json +15 -11
  6. package/config/enwiki.json +1 -1
  7. package/config/jawiki.json +1 -1
  8. package/config/minimum.json +2 -3
  9. package/config/moegirl.json +152 -15
  10. package/config/zhwiki.json +1 -1
  11. package/dist/addon/token.js +3 -0
  12. package/dist/base.d.mts +16 -9
  13. package/dist/base.d.ts +16 -9
  14. package/dist/bin/config.js +23 -11
  15. package/dist/index.d.ts +33 -4
  16. package/dist/index.js +37 -2
  17. package/dist/lib/element.d.ts +4 -4
  18. package/dist/lib/element.js +6 -5
  19. package/dist/lib/lintConfig.d.ts +13 -0
  20. package/dist/lib/lintConfig.js +278 -0
  21. package/dist/lib/lsp.d.ts +7 -7
  22. package/dist/lib/lsp.js +18 -20
  23. package/dist/lib/node.d.ts +1 -1
  24. package/dist/lib/node.js +646 -606
  25. package/dist/lib/range.d.ts +2 -2
  26. package/dist/lib/range.js +2 -2
  27. package/dist/lib/text.js +76 -62
  28. package/dist/lib/title.d.ts +11 -4
  29. package/dist/lib/title.js +16 -6
  30. package/dist/mixin/attributesParent.d.ts +6 -6
  31. package/dist/mixin/attributesParent.js +4 -4
  32. package/dist/mixin/cached.d.ts +5 -0
  33. package/dist/mixin/cached.js +22 -0
  34. package/dist/mixin/clone.d.ts +5 -0
  35. package/dist/mixin/clone.js +23 -0
  36. package/dist/mixin/hidden.js +68 -18
  37. package/dist/mixin/sol.js +1 -1
  38. package/dist/parser/commentAndExt.js +6 -4
  39. package/dist/parser/converter.js +1 -1
  40. package/dist/parser/html.js +3 -3
  41. package/dist/parser/table.js +2 -2
  42. package/dist/src/arg.js +24 -17
  43. package/dist/src/atom.js +76 -31
  44. package/dist/src/attribute.js +79 -39
  45. package/dist/src/attributes.d.ts +7 -7
  46. package/dist/src/attributes.js +417 -366
  47. package/dist/src/commented.js +81 -35
  48. package/dist/src/converter.js +13 -7
  49. package/dist/src/converterFlags.js +33 -22
  50. package/dist/src/converterRule.js +263 -216
  51. package/dist/src/extLink.js +21 -16
  52. package/dist/src/gallery.js +44 -27
  53. package/dist/src/heading.js +48 -43
  54. package/dist/src/hidden.js +14 -9
  55. package/dist/src/html.js +92 -60
  56. package/dist/src/imageParameter.js +13 -6
  57. package/dist/src/imagemap.js +32 -25
  58. package/dist/src/index.d.ts +2 -2
  59. package/dist/src/index.js +61 -50
  60. package/dist/src/link/base.d.ts +1 -1
  61. package/dist/src/link/base.js +35 -23
  62. package/dist/src/link/file.js +409 -354
  63. package/dist/src/link/galleryImage.js +9 -5
  64. package/dist/src/link/index.d.ts +1 -1
  65. package/dist/src/link/index.js +8 -4
  66. package/dist/src/link/redirectTarget.js +7 -3
  67. package/dist/src/magicLink.js +39 -26
  68. package/dist/src/nested.js +122 -74
  69. package/dist/src/nowiki/base.js +5 -2
  70. package/dist/src/nowiki/comment.js +5 -1
  71. package/dist/src/nowiki/index.js +4 -4
  72. package/dist/src/nowiki/quote.js +32 -46
  73. package/dist/src/onlyinclude.js +17 -9
  74. package/dist/src/paramTag/index.js +21 -14
  75. package/dist/src/parameter.js +26 -20
  76. package/dist/src/pre.js +91 -45
  77. package/dist/src/syntax.js +14 -10
  78. package/dist/src/table/index.js +554 -501
  79. package/dist/src/table/td.d.ts +1 -1
  80. package/dist/src/table/td.js +91 -82
  81. package/dist/src/table/trBase.js +183 -130
  82. package/dist/src/tagPair/ext.js +38 -23
  83. package/dist/src/tagPair/include.js +5 -5
  84. package/dist/src/tagPair/index.js +2 -3
  85. package/dist/src/tagPair/translate.js +150 -103
  86. package/dist/src/transclude.d.ts +15 -1
  87. package/dist/src/transclude.js +56 -21
  88. package/dist/util/html.js +46 -41
  89. package/dist/util/lint.js +7 -9
  90. package/dist/util/sharable.js +1 -1
  91. package/dist/util/sharable.mjs +2 -2
  92. package/dist/util/string.js +13 -7
  93. package/extensions/dist/base.js +9 -2
  94. package/extensions/typings.d.ts +2 -1
  95. package/i18n/zh-hans.json +1 -1
  96. package/i18n/zh-hant.json +1 -1
  97. package/package.json +20 -15
@@ -1,4 +1,38 @@
1
1
  "use strict";
2
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
3
+ var useValue = arguments.length > 2;
4
+ for (var i = 0; i < initializers.length; i++) {
5
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
6
+ }
7
+ return useValue ? value : void 0;
8
+ };
9
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
10
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
11
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
12
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
13
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
14
+ var _, done = false;
15
+ for (var i = decorators.length - 1; i >= 0; i--) {
16
+ var context = {};
17
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
18
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
19
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
20
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
21
+ if (kind === "accessor") {
22
+ if (result === void 0) continue;
23
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
24
+ if (_ = accept(result.get)) descriptor.get = _;
25
+ if (_ = accept(result.set)) descriptor.set = _;
26
+ if (_ = accept(result.init)) initializers.unshift(_);
27
+ }
28
+ else if (_ = accept(result)) {
29
+ if (kind === "field") initializers.unshift(_);
30
+ else descriptor[key] = _;
31
+ }
32
+ }
33
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
34
+ done = true;
35
+ };
2
36
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
37
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
38
  };
@@ -14,6 +48,7 @@ const string_1 = require("../../util/string");
14
48
  const debug_1 = require("../../util/debug");
15
49
  const constants_1 = require("../../util/constants");
16
50
  const title_1 = require("../../lib/title");
51
+ const cached_1 = require("../../mixin/cached");
17
52
  const frame = new Map([
18
53
  ['manualthumb', 'Thumb'],
19
54
  ['frameless', 'Frameless'],
@@ -59,381 +94,401 @@ const filterArgs = (args, types) => args.filter(({ childNodes }) => {
59
94
  * 图片
60
95
  * @classdesc `{childNodes: [AtomToken, ...ImageParameterToken[]]}`
61
96
  */
62
- class FileToken extends base_1.LinkBaseToken {
63
- /* NOT FOR BROWSER END */
64
- get type() {
65
- return 'file';
66
- }
67
- /**
68
- * file extension
69
- *
70
- * 扩展名
71
- * @since v1.5.3
72
- */
73
- get extension() {
74
- return this.getAttribute('title').extension;
75
- }
76
- /* NOT FOR BROWSER */
77
- /** image link / 图片链接 */
78
- get link() {
79
- return this.getArg('link')?.link ?? super.link;
80
- }
81
- set link(value) {
82
- this.setValue('link', value);
83
- }
84
- /** image size / 图片大小 */
85
- get size() {
86
- const fr = this.getFrame();
87
- return fr === 'framed' || fr instanceof title_1.Title ? undefined : this.getArg('width')?.size;
88
- }
89
- set size(size) {
90
- this.setValue('width', size && size.width + (size.height && 'x') + size.height);
91
- }
92
- /** image width / 图片宽度 */
93
- get width() {
94
- return this.is('gallery-image')
95
- ? this.parentNode?.widths.toString()
96
- : this.size?.width;
97
- }
98
- set width(width) {
99
- const arg = this.getArg('width');
100
- if (arg) {
101
- arg.width = width;
102
- }
103
- else {
104
- this.setValue('width', width);
97
+ let FileToken = (() => {
98
+ let _classSuper = base_1.LinkBaseToken;
99
+ let _instanceExtraInitializers = [];
100
+ let _toHtmlInternal_decorators;
101
+ return class FileToken extends _classSuper {
102
+ static {
103
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
104
+ _toHtmlInternal_decorators = [(0, cached_1.cached)()];
105
+ __esDecorate(this, null, _toHtmlInternal_decorators, { kind: "method", name: "toHtmlInternal", static: false, private: false, access: { has: obj => "toHtmlInternal" in obj, get: obj => obj.toHtmlInternal }, metadata: _metadata }, null, _instanceExtraInitializers);
106
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
105
107
  }
106
- }
107
- /** image height / 图片高度 */
108
- get height() {
109
- return this.is('gallery-image')
110
- ? this.parentNode?.heights.toString()
111
- : this.size?.height;
112
- }
113
- set height(height) {
114
- const arg = this.getArg('width');
115
- if (arg) {
116
- arg.height = height;
108
+ /* NOT FOR BROWSER END */
109
+ get type() {
110
+ return 'file';
117
111
  }
118
- else {
119
- this.setValue('width', height && `x${height}`);
112
+ /**
113
+ * file extension
114
+ *
115
+ * 扩展名
116
+ * @since v1.5.3
117
+ */
118
+ get extension() {
119
+ return this.getAttribute('title').extension;
120
120
  }
121
- }
122
- /* NOT FOR BROWSER END */
123
- /**
124
- * @param link 文件名
125
- * @param text 图片参数
126
- * @param delimiter `|`
127
- */
128
- constructor(link, text, config, accum = [], delimiter = '|') {
129
- super(link, undefined, config, accum, delimiter);
130
121
  /* NOT FOR BROWSER */
131
- this.setAttribute('acceptable', { AtomToken: 0, ImageParameterToken: '1:' });
132
- /* NOT FOR BROWSER END */
133
- const { extension } = this.getTitle(true, true);
134
- /-\{|\}-|\|/gu; // eslint-disable-line @typescript-eslint/no-unused-expressions
135
- this.safeAppend(explode(text).map(
136
- // @ts-expect-error abstract class
137
- (part) => new imageParameter_1.ImageParameterToken(part, extension, config, accum)));
138
- }
139
- /** @private */
140
- lint(start = this.getAbsoluteIndex(), re) {
141
- const errors = super.lint(start, re), args = filterArgs(this.getAllArgs(), argTypes), keys = [...new Set(args.map(({ name }) => name))], frameKeys = keys.filter(key => frame.has(key)), horizAlignKeys = keys.filter(key => horizAlign.has(key)), vertAlignKeys = keys.filter(key => vertAlign.has(key)), [fr] = frameKeys, unscaled = fr === 'framed' || fr === 'manualthumb', rect = new rect_1.BoundingRect(this, start);
142
- if (this.closest('ext-link-text')
143
- && this.getValue('link')?.trim() !== '') {
144
- errors.push((0, lint_1.generateForSelf)(this, rect, 'nested-link', 'internal link in an external link'));
145
- }
146
- if (unscaled) {
147
- for (const arg of args.filter(({ name }) => name === 'width')) {
148
- const e = (0, lint_1.generateForChild)(arg, rect, 'invalid-gallery', 'invalid image parameter');
149
- e.fix = { desc: 'remove', range: [e.startIndex - 1, e.endIndex], text: '' };
150
- errors.push(e);
122
+ /** image link / 图片链接 */
123
+ get link() {
124
+ return this.getArg('link')?.link ?? super.link;
125
+ }
126
+ set link(value) {
127
+ this.setValue('link', value);
128
+ }
129
+ /** image size / 图片大小 */
130
+ get size() {
131
+ const fr = this.getFrame();
132
+ return fr === 'framed' || fr instanceof title_1.Title ? undefined : this.getArg('width')?.size;
133
+ }
134
+ set size(size) {
135
+ this.setValue('width', size && size.width + (size.height && 'x') + size.height);
136
+ }
137
+ /** image width / 图片宽度 */
138
+ get width() {
139
+ return this.is('gallery-image')
140
+ ? this.parentNode?.widths.toString()
141
+ : this.size?.width;
142
+ }
143
+ set width(width) {
144
+ const arg = this.getArg('width');
145
+ if (arg) {
146
+ arg.width = width;
147
+ }
148
+ else {
149
+ this.setValue('width', width);
151
150
  }
152
151
  }
153
- if (args.length === keys.length
154
- && frameKeys.length < 2
155
- && horizAlignKeys.length < 2
156
- && vertAlignKeys.length < 2) {
157
- return errors;
152
+ /** image height / 图片高度 */
153
+ get height() {
154
+ return this.is('gallery-image')
155
+ ? this.parentNode?.heights.toString()
156
+ : this.size?.height;
157
+ }
158
+ set height(height) {
159
+ const arg = this.getArg('width');
160
+ if (arg) {
161
+ arg.height = height;
162
+ }
163
+ else {
164
+ this.setValue('width', height && `x${height}`);
165
+ }
158
166
  }
167
+ /* NOT FOR BROWSER END */
159
168
  /**
160
- * 图片参数到语法错误的映射
161
- * @param msg 消息键
162
- * @param p1 替换$1
163
- * @param severity 错误等级
169
+ * @param link 文件名
170
+ * @param text 图片参数
171
+ * @param delimiter `|`
164
172
  */
165
- const generate = (msg, p1, severity = true) => (arg) => {
166
- const isError = typeof severity === 'function' ? severity(arg) : severity, e = (0, lint_1.generateForChild)(arg, rect, 'no-duplicate', index_1.default.msg(`${msg} image $1 parameter`, p1), isError ? 'error' : 'warning');
167
- e.suggestions = [{ desc: 'remove', range: [e.startIndex - 1, e.endIndex], text: '' }];
168
- return e;
169
- };
170
- const { extension } = this;
171
- for (const key of keys) {
172
- if (key === 'invalid' || key === 'width' && unscaled) {
173
- continue;
173
+ constructor(link, text, config, accum = [], delimiter = '|') {
174
+ super(link, undefined, config, accum, delimiter);
175
+ __runInitializers(this, _instanceExtraInitializers);
176
+ /* NOT FOR BROWSER */
177
+ this.setAttribute('acceptable', { AtomToken: 0, ImageParameterToken: '1:' });
178
+ /* NOT FOR BROWSER END */
179
+ const { extension } = this.getTitle(true, true);
180
+ /-\{|\}-|\|/gu; // eslint-disable-line @typescript-eslint/no-unused-expressions
181
+ this.safeAppend(explode(text).map(
182
+ // @ts-expect-error abstract class
183
+ (part) => new imageParameter_1.ImageParameterToken(part, extension, config, accum)));
184
+ }
185
+ /** @private */
186
+ lint(start = this.getAbsoluteIndex(), re) {
187
+ const errors = super.lint(start, re), args = filterArgs(this.getAllArgs(), argTypes), keys = [...new Set(args.map(({ name }) => name))], frameKeys = keys.filter(key => frame.has(key)), horizAlignKeys = keys.filter(key => horizAlign.has(key)), vertAlignKeys = keys.filter(key => vertAlign.has(key)), [fr] = frameKeys, unscaled = fr === 'framed' || fr === 'manualthumb', rect = new rect_1.BoundingRect(this, start);
188
+ let rule = 'nested-link', s = index_1.default.lintConfig.getSeverity(rule, 'file');
189
+ if (s
190
+ && this.closest('ext-link-text')
191
+ && this.getValue('link')?.trim() !== '') {
192
+ errors.push((0, lint_1.generateForSelf)(this, rect, rule, 'internal link in an external link', s));
193
+ }
194
+ rule = 'invalid-gallery';
195
+ s = index_1.default.lintConfig.getSeverity(rule, 'parameter');
196
+ if (s && unscaled) {
197
+ for (const arg of args.filter(({ name }) => name === 'width')) {
198
+ const e = (0, lint_1.generateForChild)(arg, rect, rule, 'invalid image parameter', s);
199
+ e.fix = { desc: 'remove', range: [e.startIndex - 1, e.endIndex], text: '' };
200
+ errors.push(e);
201
+ }
174
202
  }
175
- const isCaption = key === 'caption';
176
- let relevantArgs = args.filter(({ name }) => name === key);
177
- if (isCaption) {
178
- relevantArgs = [
179
- ...relevantArgs.slice(0, -1).filter(arg => arg.text()),
180
- ...relevantArgs.slice(-1),
181
- ];
203
+ if (args.length === keys.length
204
+ && frameKeys.length < 2
205
+ && horizAlignKeys.length < 2
206
+ && vertAlignKeys.length < 2) {
207
+ return errors;
182
208
  }
183
- if (relevantArgs.length > 1) {
184
- let severity = !isCaption || !extension || extensions.has(extension);
185
- if (isCaption && severity) {
186
- const plainArgs = filterArgs(relevantArgs, transclusion);
187
- severity = plainArgs.length > 1 && ((arg) => plainArgs.includes(arg));
209
+ rule = 'no-duplicate';
210
+ const { extension } = this, severities = ['unknownImageParameter', 'imageParameter'].map(k => index_1.default.lintConfig.getSeverity(rule, k));
211
+ /**
212
+ * 图片参数到语法错误的映射
213
+ * @param tokens 图片参数节点
214
+ * @param msg 消息键
215
+ * @param p1 替换$1
216
+ * @param severity 错误等级
217
+ */
218
+ const generate = (tokens, msg, p1, severity = true) => tokens.map(arg => {
219
+ s = severities[Number(typeof severity === 'function' ? severity(arg) : severity)];
220
+ if (!s) {
221
+ return false;
222
+ }
223
+ const e = (0, lint_1.generateForChild)(arg, rect, rule, index_1.default.msg(`${msg} image $1 parameter`, p1), s);
224
+ e.suggestions = [{ desc: 'remove', range: [e.startIndex - 1, e.endIndex], text: '' }];
225
+ return e;
226
+ }).filter((e) => e !== false);
227
+ for (const key of keys) {
228
+ if (key === 'invalid' || key === 'width' && unscaled) {
229
+ continue;
230
+ }
231
+ const isCaption = key === 'caption';
232
+ let relevantArgs = args.filter(({ name }) => name === key);
233
+ if (isCaption) {
234
+ relevantArgs = [
235
+ ...relevantArgs.slice(0, -1).filter(arg => arg.text()),
236
+ ...relevantArgs.slice(-1),
237
+ ];
238
+ }
239
+ if (relevantArgs.length > 1) {
240
+ let severity = !isCaption || !extension || extensions.has(extension);
241
+ if (isCaption && severity) {
242
+ const plainArgs = filterArgs(relevantArgs, transclusion);
243
+ severity = plainArgs.length > 1 && ((arg) => plainArgs.includes(arg));
244
+ }
245
+ errors.push(...generate(relevantArgs, 'duplicated', key, severity));
188
246
  }
189
- errors.push(...relevantArgs.map(generate('duplicated', key, severity)));
190
247
  }
248
+ if (frameKeys.length > 1) {
249
+ errors.push(...generate(args.filter(({ name }) => frame.has(name)), 'conflicting', 'frame'));
250
+ }
251
+ if (horizAlignKeys.length > 1) {
252
+ errors.push(...generate(args.filter(({ name }) => horizAlign.has(name)), 'conflicting', 'horizontal-alignment'));
253
+ }
254
+ if (vertAlignKeys.length > 1) {
255
+ errors.push(...generate(args.filter(({ name }) => vertAlign.has(name)), 'conflicting', 'vertical-alignment'));
256
+ }
257
+ return errors;
191
258
  }
192
- if (frameKeys.length > 1) {
193
- errors.push(...args.filter(({ name }) => frame.has(name)).map(generate('conflicting', 'frame')));
259
+ /**
260
+ * Get all image parameter tokens
261
+ *
262
+ * 获取所有图片参数节点
263
+ */
264
+ getAllArgs() {
265
+ return this.childNodes.slice(1);
194
266
  }
195
- if (horizAlignKeys.length > 1) {
196
- errors.push(...args.filter(({ name }) => horizAlign.has(name))
197
- .map(generate('conflicting', 'horizontal-alignment')));
267
+ /**
268
+ * Get image parameters with the specified name
269
+ *
270
+ * 获取指定图片参数
271
+ * @param key parameter name / 参数名
272
+ */
273
+ getArgs(key) {
274
+ return this.getAllArgs().filter(({ name }) => key === name);
198
275
  }
199
- if (vertAlignKeys.length > 1) {
200
- errors.push(...args.filter(({ name }) => vertAlign.has(name))
201
- .map(generate('conflicting', 'vertical-alignment')));
276
+ /**
277
+ * Get the effective image parameter with the specified name
278
+ *
279
+ * 获取生效的指定图片参数
280
+ * @param key parameter name / 参数名
281
+ */
282
+ getArg(key) {
283
+ const args = this.getArgs(key);
284
+ return args[key === 'manualthumb' ? 0 : args.length - 1];
202
285
  }
203
- return errors;
204
- }
205
- /**
206
- * Get all image parameter tokens
207
- *
208
- * 获取所有图片参数节点
209
- */
210
- getAllArgs() {
211
- return this.childNodes.slice(1);
212
- }
213
- /**
214
- * Get image parameters with the specified name
215
- *
216
- * 获取指定图片参数
217
- * @param key parameter name / 参数名
218
- */
219
- getArgs(key) {
220
- return this.getAllArgs().filter(({ name }) => key === name);
221
- }
222
- /**
223
- * Get the effective image parameter with the specified name
224
- *
225
- * 获取生效的指定图片参数
226
- * @param key parameter name / 参数名
227
- */
228
- getArg(key) {
229
- const args = this.getArgs(key);
230
- return args[key === 'manualthumb' ? 0 : args.length - 1];
231
- }
232
- /**
233
- * Get the effective image parameter value
234
- *
235
- * 获取生效的指定图片参数值
236
- * @param key parameter name / 参数名
237
- */
238
- getValue(key) {
239
- return this.getArg(key)?.getValue();
240
- }
241
- /** @private */
242
- json(_, start = this.getAbsoluteIndex()) {
243
- const json = super.json(undefined, start), { extension } = this;
244
- if (extension) {
245
- json['extension'] = extension;
286
+ /**
287
+ * Get the effective image parameter value
288
+ *
289
+ * 获取生效的指定图片参数值
290
+ * @param key parameter name / 参数名
291
+ */
292
+ getValue(key) {
293
+ return this.getArg(key)?.getValue();
246
294
  }
247
- return json;
248
- }
249
- /* NOT FOR BROWSER */
250
- /**
251
- * 获取特定类型的图片属性参数节点
252
- * @param keys 接受的参数名
253
- * @param type 类型名
254
- */
255
- #getTypedArgs(keys, type) {
256
- const args = this.getAllArgs().filter(({ name }) => keys.has(name));
257
- if (args.length > 1) {
258
- index_1.default.warn(`The image ${this.name} has ${args.length} ${type} parameters. Only the last ${args[0].name} will take effect!`);
259
- }
260
- return args;
261
- }
262
- /**
263
- * Get image frame parameter tokens
264
- *
265
- * 获取图片框架属性参数节点
266
- */
267
- getFrameArgs() {
268
- return this.#getTypedArgs(frame, 'frame');
269
- }
270
- /**
271
- * Get image horizontal alignment parameter tokens
272
- *
273
- * 获取图片水平对齐参数节点
274
- */
275
- getHorizAlignArgs() {
276
- return this.#getTypedArgs(horizAlign, 'horizontal-align');
277
- }
278
- /**
279
- * Get image vertical alignment parameter tokens
280
- *
281
- * 获取图片垂直对齐参数节点
282
- */
283
- getVertAlignArgs() {
284
- return this.#getTypedArgs(vertAlign, 'vertical-align');
285
- }
286
- /**
287
- * Get the effective image frame paremter value
288
- *
289
- * 获取生效的图片框架属性参数
290
- * @since v1.11.0
291
- */
292
- getFrame() {
293
- const [arg] = this.getFrameArgs(), val = arg?.name;
294
- return val === 'manualthumb' ? this.normalizeTitle(arg.getValue(), 6) : val;
295
- }
296
- /**
297
- * Get the effective image horizontal alignment parameter value
298
- *
299
- * 获取生效的图片水平对齐参数
300
- * @since v1.11.0
301
- */
302
- getHorizAlign() {
303
- return this.getHorizAlignArgs()[0]?.name;
304
- }
305
- /**
306
- * Get the effective image vertical alignment parameter value
307
- *
308
- * 获取生效的图片垂直对齐参数
309
- * @since v1.11.0
310
- */
311
- getVertAlign() {
312
- return this.getVertAlignArgs()[0]?.name;
313
- }
314
- /**
315
- * Check if the image contains the specified parameter
316
- *
317
- * 是否具有指定图片参数
318
- * @param key parameter name / 参数名
319
- */
320
- hasArg(key) {
321
- return this.getArgs(key).length > 0;
322
- }
323
- /**
324
- * Remove the specified image parameter
325
- *
326
- * 移除指定图片参数
327
- * @param key parameter name / 参数名
328
- */
329
- removeArg(key) {
330
- for (const token of this.getArgs(key)) {
331
- this.removeChild(token);
295
+ /** @private */
296
+ json(_, start = this.getAbsoluteIndex()) {
297
+ const json = super.json(undefined, start), { extension } = this;
298
+ if (extension) {
299
+ json['extension'] = extension;
300
+ }
301
+ return json;
332
302
  }
333
- }
334
- /**
335
- * Get all image parameter names
336
- *
337
- * 获取图片参数名
338
- */
339
- getKeys() {
340
- return new Set(this.getAllArgs().map(({ name }) => name));
341
- }
342
- /**
343
- * Get the image parameter values with the specified name
344
- *
345
- * 获取指定的图片参数值
346
- * @param key parameter name / 参数名
347
- */
348
- getValues(key) {
349
- return this.getArgs(key).map(token => token.getValue());
350
- }
351
- /**
352
- * Set the image parameter
353
- *
354
- * 设置图片参数
355
- * @param key parameter name / 参数名
356
- * @param value parameter value / 参数值
357
- * @throws `RangeError` 未定义的图片参数
358
- */
359
- setValue(key, value = false) {
360
- if (value === false) {
361
- this.removeArg(key);
362
- return;
363
- }
364
- const token = this.getArg(key);
365
- if (token) {
366
- token.setValue(value);
367
- return;
368
- }
369
- const config = this.getAttribute('config'), syntax = key === 'caption' ? '$1' : Object.entries(config.img).find(([, name]) => name === key)?.[0];
370
- /* istanbul ignore if */
371
- if (syntax === undefined) {
372
- throw new RangeError(`Unknown image parameter: ${key}`);
373
- }
374
- const free = syntax.includes('$1');
375
- /* istanbul ignore if */
376
- if (value === true && free) {
377
- this.typeError('setValue', 'String');
378
- }
379
- const parameter = debug_1.Shadow.run(() =>
380
- // @ts-expect-error abstract class
381
- new imageParameter_1.ImageParameterToken(syntax.replace('$1', key === 'width' ? '1' : ''), this.extension, config));
382
- if (free) {
383
- const { childNodes } = index_1.default
384
- .parse(value, this.getAttribute('include'), undefined, config);
385
- parameter.safeReplaceChildren(childNodes);
386
- }
387
- this.insertAt(parameter);
388
- }
389
- /* istanbul ignore next */
390
- /**
391
- * @override
392
- * @throws `Error` 不适用于图片
393
- */
394
- setLinkText() {
395
- throw new Error('LinkBaseToken.setLinkText method is not applicable to images!');
396
- }
397
- /** @private */
398
- toHtmlInternal(opt) {
399
- /** @ignore */
400
- const isInteger = (n) => Boolean(n && !/\D/u.test(n));
401
- const { link, width, height, type } = this, file = this.getAttribute('title'), fr = this.getFrame(), manual = fr instanceof title_1.Title, visibleCaption = manual || fr === 'thumbnail' || fr === 'framed' || type === 'gallery-image', caption = this.getArg('caption')?.toHtmlInternal({
402
- ...opt,
403
- nowrap: true,
404
- }) ?? '', titleFromCaption = visibleCaption && type !== 'gallery-image' ? '' : (0, string_1.sanitizeAlt)(caption), hasLink = manual || link !== file, title = titleFromCaption || (hasLink && typeof link !== 'string' ? link.getTitleAttr() : ''), titleAttr = title && ` title="${title}"`, alt = (0, string_1.sanitizeAlt)(this.getArg('alt')?.toHtmlInternal({
405
- ...opt,
406
- nowrap: true,
407
- })) ?? titleFromCaption, horiz = this.getHorizAlign() ?? '', vert = this.getVertAlign() ?? '', className = `${horiz ? `mw-halign-${horiz}` : vert && `mw-valign-${vert}`}${this.getValue('border') ? ' mw-image-border' : ''} ${(0, string_1.sanitizeAlt)(this.getValue('class')) ?? ''}`.trim(), classAttr = className && ` class="${className}"`, img = `<img${alt && ` alt="${alt}"`} src="${(manual ? fr : file).getUrl()}" decoding="async" class="mw-file-element"${isInteger(width) ? ` width="${width}"` : ''}${isInteger(height) ? ` height="${height}"` : ''}>`;
408
- let href = '';
409
- if (link) {
410
- try {
411
- href = typeof link === 'string' ? this.getArg('link').getUrl() : link.getUrl();
412
- if (link === file) {
413
- const lang = this.getValue('lang'), page = this.getValue('page');
414
- if (lang) {
415
- href += `?lang=${lang}`;
416
- }
417
- else if (page) {
418
- href += `?page=${page}`;
303
+ /* NOT FOR BROWSER */
304
+ /**
305
+ * 获取特定类型的图片属性参数节点
306
+ * @param keys 接受的参数名
307
+ * @param type 类型名
308
+ */
309
+ #getTypedArgs(keys, type) {
310
+ const args = this.getAllArgs().filter(({ name }) => keys.has(name));
311
+ if (args.length > 1) {
312
+ index_1.default.warn(`The image ${this.name} has ${args.length} ${type} parameters. Only the last ${args[0].name} will take effect!`);
313
+ }
314
+ return args;
315
+ }
316
+ /**
317
+ * Get image frame parameter tokens
318
+ *
319
+ * 获取图片框架属性参数节点
320
+ */
321
+ getFrameArgs() {
322
+ return this.#getTypedArgs(frame, 'frame');
323
+ }
324
+ /**
325
+ * Get image horizontal alignment parameter tokens
326
+ *
327
+ * 获取图片水平对齐参数节点
328
+ */
329
+ getHorizAlignArgs() {
330
+ return this.#getTypedArgs(horizAlign, 'horizontal-align');
331
+ }
332
+ /**
333
+ * Get image vertical alignment parameter tokens
334
+ *
335
+ * 获取图片垂直对齐参数节点
336
+ */
337
+ getVertAlignArgs() {
338
+ return this.#getTypedArgs(vertAlign, 'vertical-align');
339
+ }
340
+ /**
341
+ * Get the effective image frame paremter value
342
+ *
343
+ * 获取生效的图片框架属性参数
344
+ * @since v1.11.0
345
+ */
346
+ getFrame() {
347
+ const [arg] = this.getFrameArgs(), val = arg?.name;
348
+ return val === 'manualthumb' ? this.normalizeTitle(arg.getValue(), 6) : val;
349
+ }
350
+ /**
351
+ * Get the effective image horizontal alignment parameter value
352
+ *
353
+ * 获取生效的图片水平对齐参数
354
+ * @since v1.11.0
355
+ */
356
+ getHorizAlign() {
357
+ return this.getHorizAlignArgs()[0]?.name;
358
+ }
359
+ /**
360
+ * Get the effective image vertical alignment parameter value
361
+ *
362
+ * 获取生效的图片垂直对齐参数
363
+ * @since v1.11.0
364
+ */
365
+ getVertAlign() {
366
+ return this.getVertAlignArgs()[0]?.name;
367
+ }
368
+ /**
369
+ * Check if the image contains the specified parameter
370
+ *
371
+ * 是否具有指定图片参数
372
+ * @param key parameter name / 参数名
373
+ */
374
+ hasArg(key) {
375
+ return this.getArgs(key).length > 0;
376
+ }
377
+ /**
378
+ * Remove the specified image parameter
379
+ *
380
+ * 移除指定图片参数
381
+ * @param key parameter name / 参数名
382
+ */
383
+ removeArg(key) {
384
+ for (const token of this.getArgs(key)) {
385
+ this.removeChild(token);
386
+ }
387
+ }
388
+ /**
389
+ * Get all image parameter names
390
+ *
391
+ * 获取图片参数名
392
+ */
393
+ getKeys() {
394
+ return new Set(this.getAllArgs().map(({ name }) => name));
395
+ }
396
+ /**
397
+ * Get the image parameter values with the specified name
398
+ *
399
+ * 获取指定的图片参数值
400
+ * @param key parameter name / 参数名
401
+ */
402
+ getValues(key) {
403
+ return this.getArgs(key).map(token => token.getValue());
404
+ }
405
+ /**
406
+ * Set the image parameter
407
+ *
408
+ * 设置图片参数
409
+ * @param key parameter name / 参数名
410
+ * @param value parameter value / 参数值
411
+ * @throws `RangeError` 未定义的图片参数
412
+ */
413
+ setValue(key, value = false) {
414
+ if (value === false) {
415
+ this.removeArg(key);
416
+ return;
417
+ }
418
+ const token = this.getArg(key);
419
+ if (token) {
420
+ token.setValue(value);
421
+ return;
422
+ }
423
+ const config = this.getAttribute('config'), syntax = key === 'caption' ? '$1' : Object.entries(config.img).find(([, name]) => name === key)?.[0];
424
+ /* istanbul ignore if */
425
+ if (syntax === undefined) {
426
+ throw new RangeError(`Unknown image parameter: ${key}`);
427
+ }
428
+ const free = syntax.includes('$1');
429
+ /* istanbul ignore if */
430
+ if (value === true && free) {
431
+ this.typeError('setValue', 'String');
432
+ }
433
+ const parameter = debug_1.Shadow.run(() =>
434
+ // @ts-expect-error abstract class
435
+ new imageParameter_1.ImageParameterToken(syntax.replace('$1', key === 'width' ? '1' : ''), this.extension, config));
436
+ if (free) {
437
+ const { childNodes } = index_1.default
438
+ .parse(value, this.getAttribute('include'), undefined, config);
439
+ parameter.safeReplaceChildren(childNodes);
440
+ }
441
+ this.insertAt(parameter);
442
+ }
443
+ /* istanbul ignore next */
444
+ /**
445
+ * @override
446
+ * @throws `Error` 不适用于图片
447
+ */
448
+ setLinkText() {
449
+ throw new Error('LinkBaseToken.setLinkText method is not applicable to images!');
450
+ }
451
+ /** @private */
452
+ toHtmlInternal(opt) {
453
+ /** @ignore */
454
+ const isInteger = (n) => Boolean(n && !/\D/u.test(n));
455
+ const { link, width, height, type } = this, file = this.getAttribute('title'), fr = this.getFrame(), manual = fr instanceof title_1.Title, visibleCaption = manual || fr === 'thumbnail' || fr === 'framed' || type === 'gallery-image', caption = this.getArg('caption')?.toHtmlInternal({
456
+ ...opt,
457
+ nowrap: true,
458
+ }) ?? '', titleFromCaption = visibleCaption && type !== 'gallery-image' ? '' : (0, string_1.sanitizeAlt)(caption), hasLink = manual || link !== file, title = titleFromCaption || (hasLink && typeof link !== 'string' ? link.getTitleAttr() : ''), titleAttr = title && ` title="${title}"`, alt = (0, string_1.sanitizeAlt)(this.getArg('alt')?.toHtmlInternal({
459
+ ...opt,
460
+ nowrap: true,
461
+ })) ?? titleFromCaption, horiz = this.getHorizAlign() ?? '', vert = this.getVertAlign() ?? '', className = `${horiz ? `mw-halign-${horiz}` : vert && `mw-valign-${vert}`}${this.getValue('border') ? ' mw-image-border' : ''} ${(0, string_1.sanitizeAlt)(this.getValue('class')) ?? ''}`.trim(), classAttr = className && ` class="${className}"`, img = `<img${alt && ` alt="${alt}"`} src="${(manual ? fr : file).getUrl()}" decoding="async" class="mw-file-element"${isInteger(width) ? ` width="${width}"` : ''}${isInteger(height) ? ` height="${height}"` : ''}>`;
462
+ let href = '';
463
+ if (link) {
464
+ try {
465
+ href = typeof link === 'string' ? this.getArg('link').getUrl() : link.getUrl();
466
+ if (link === file) {
467
+ const lang = this.getValue('lang'), page = this.getValue('page');
468
+ if (lang) {
469
+ href += `?lang=${lang}`;
470
+ }
471
+ else if (page) {
472
+ href += `?page=${page}`;
473
+ }
419
474
  }
420
475
  }
476
+ catch { }
421
477
  }
422
- catch { }
423
- }
424
- const a = link
425
- ? `<a${href && ` href="${href}"`}${hasLink ? '' : ' class="mw-file-description"'}${titleAttr}${typeof link === 'string' ? ' rel="nofollow"' : ''}>${img}</a>`
426
- : `<span${titleAttr}>${img}</span>`;
427
- if (type !== 'gallery-image') {
428
- return horiz || vert || visibleCaption
429
- ? `<figure${classAttr} typeof="mw:File${fr ? `/${manual ? 'Thumb' : frame.get(fr)}` : ''}">${a}<figcaption>${caption}</figcaption></figure>`
430
- : `<span${classAttr}>${a}</span>`;
431
- }
432
- const parent = this.parentNode, mode = parent?.parentNode?.getAttr('mode'), nolines = typeof mode === 'string' && mode.toLowerCase() === 'nolines', padding = nolines ? 0 : 30;
433
- return `\t<li class="gallerybox" style="width: ${Number(width) + padding + 5}px">\n\t\t<div class="thumb" style="width: ${Number(width) + padding}px${nolines ? '' : `; height: ${Number(height) + padding}px`}"><span>${a}</span></div>\n\t\t<div class="gallerytext">${parent?.parentNode?.getAttr('showfilename') === undefined
434
- ? ''
435
- : `<a href="${file.getUrl()}" class="galleryfilename galleryfilename-truncate" title="${file.title}">${file.main}</a>\n`}${caption}</div>\n\t</li>`;
436
- }
437
- }
478
+ const a = link
479
+ ? `<a${href && ` href="${href}"`}${hasLink ? '' : ' class="mw-file-description"'}${titleAttr}${typeof link === 'string' ? ' rel="nofollow"' : ''}>${img}</a>`
480
+ : `<span${titleAttr}>${img}</span>`;
481
+ if (type !== 'gallery-image') {
482
+ return horiz || vert || visibleCaption
483
+ ? `<figure${classAttr} typeof="mw:File${fr ? `/${manual ? 'Thumb' : frame.get(fr)}` : ''}">${a}<figcaption>${caption}</figcaption></figure>`
484
+ : `<span${classAttr}>${a}</span>`;
485
+ }
486
+ const parent = this.parentNode, mode = parent?.parentNode?.getAttr('mode'), nolines = typeof mode === 'string' && mode.toLowerCase() === 'nolines', padding = nolines ? 0 : 30;
487
+ return `\t<li class="gallerybox" style="width: ${Number(width) + padding + 5}px">\n\t\t<div class="thumb" style="width: ${Number(width) + padding}px${nolines ? '' : `; height: ${Number(height) + padding}px`}"><span>${a}</span></div>\n\t\t<div class="gallerytext">${parent?.parentNode?.hasAttr('showfilename')
488
+ ? `<a href="${file.getUrl()}" class="galleryfilename galleryfilename-truncate" title="${file.title}">${file.main}</a>\n`
489
+ : ''}${caption}</div>\n\t</li>`;
490
+ }
491
+ };
492
+ })();
438
493
  exports.FileToken = FileToken;
439
494
  constants_1.classes['FileToken'] = __filename;