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
@@ -99,7 +99,7 @@ export declare class AstRange {
99
99
  *
100
100
  * 比较端点和Range的位置
101
101
  * @param referenceNode node container / 端点容器
102
- * @param offset 端点位置
102
+ * @param offset node offset / 端点位置
103
103
  * @throws `RangeError` 不在同一个文档
104
104
  */
105
105
  comparePoint(referenceNode: AstNodes, offset: number): -1 | 0 | 1;
@@ -108,7 +108,7 @@ export declare class AstRange {
108
108
  *
109
109
  * 端点是否在Range中
110
110
  * @param referenceNode node container / 端点容器
111
- * @param offset 端点位置
111
+ * @param offset node offset / 端点位置
112
112
  */
113
113
  isPointInRange(referenceNode: AstNodes, offset: number): boolean;
114
114
  /**
package/dist/lib/range.js CHANGED
@@ -277,7 +277,7 @@ class AstRange {
277
277
  *
278
278
  * 比较端点和Range的位置
279
279
  * @param referenceNode node container / 端点容器
280
- * @param offset 端点位置
280
+ * @param offset node offset / 端点位置
281
281
  * @throws `RangeError` 不在同一个文档
282
282
  */
283
283
  comparePoint(referenceNode, offset) {
@@ -297,7 +297,7 @@ class AstRange {
297
297
  *
298
298
  * 端点是否在Range中
299
299
  * @param referenceNode node container / 端点容器
300
- * @param offset 端点位置
300
+ * @param offset node offset / 端点位置
301
301
  */
302
302
  isPointInRange(referenceNode, offset) {
303
303
  return this.comparePoint(referenceNode, offset) === 0;
package/dist/lib/text.js CHANGED
@@ -50,6 +50,7 @@ const node_1 = require("./node");
50
50
  const constants_1 = require("../util/constants");
51
51
  const debug_1 = require("../util/debug");
52
52
  const readOnly_1 = require("../mixin/readOnly");
53
+ const cached_1 = require("../mixin/cached");
53
54
  /* NOT FOR BROWSER END */
54
55
  const sp = String.raw `[${string_1.zs}\t]*`, source = String.raw `<\s*(?:/\s*)?([a-z]\w*)|\{+|\}+|\[{2,}|\[(?![^[]*?\])|((?:^|\])[^[]*?)\]+|(?:rfc|pmid)(?=[-::]?${sp}\d)|isbn(?=[-::]?${sp}(?:\d(?:${sp}|-)){6})`;
55
56
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
@@ -62,16 +63,6 @@ const errorSyntaxUrl = new RegExp(source, 'giu'), noLinkTypes = new Set(['attr-v
62
63
  '{': /[{}]/u,
63
64
  ']': /[[\]](?=[^[\]]*$)/u,
64
65
  '}': /[{}](?=[^{}]*$)/u,
65
- }, ruleMap = {
66
- '<': 'tag-like',
67
- '[': 'lonely-bracket',
68
- '{': 'lonely-bracket',
69
- ']': 'lonely-bracket',
70
- '}': 'lonely-bracket',
71
- h: 'lonely-http',
72
- r: 'lonely-http',
73
- p: 'lonely-http',
74
- i: 'lonely-http',
75
66
  }, disallowedTags = new Set([
76
67
  'html',
77
68
  'base',
@@ -142,10 +133,12 @@ let AstText = (() => {
142
133
  let _instanceExtraInitializers = [];
143
134
  let _private_setData_decorators;
144
135
  let _private_setData_descriptor;
136
+ let _toHtmlInternal_decorators;
145
137
  return class AstText extends _classSuper {
146
138
  static {
147
139
  const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
148
140
  _private_setData_decorators = [(0, readOnly_1.readOnly)()];
141
+ _toHtmlInternal_decorators = [(0, cached_1.cached)()];
149
142
  __esDecorate(this, _private_setData_descriptor = { value: __setFunctionName(function (text) {
150
143
  /* NOT FOR BROWSER */
151
144
  const { data } = this, e = new Event('text', { bubbles: true });
@@ -156,6 +149,7 @@ let AstText = (() => {
156
149
  this.dispatchEvent(e, { type: 'text', oldText: data });
157
150
  }
158
151
  }, "#setData") }, _private_setData_decorators, { kind: "method", name: "#setData", static: false, private: true, access: { has: obj => #setData in obj, get: obj => obj.#setData }, metadata: _metadata }, null, _instanceExtraInitializers);
152
+ __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);
159
153
  if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
160
154
  }
161
155
  data = (__runInitializers(this, _instanceExtraInitializers), '');
@@ -206,13 +200,9 @@ let AstText = (() => {
206
200
  throw new Error('An isolated text node cannot be linted!');
207
201
  }
208
202
  const { type, name, parentNode: grandparent } = parentNode;
209
- let isHtmlAttrVal = false;
210
203
  if (type === 'attr-value') {
211
- const { type: grandType, name: grandName, tag } = grandparent;
212
- if (grandType !== 'ext-attr') {
213
- isHtmlAttrVal = true;
214
- }
215
- else if (tag === 'ref' && (grandName === 'name' || grandName === 'extends' || grandName === 'follow')
204
+ const { name: grandName, tag } = grandparent;
205
+ if (tag === 'ref' && (grandName === 'name' || grandName === 'extends' || grandName === 'follow')
216
206
  || grandName === 'group' && (tag === 'ref' || tag === 'references')
217
207
  || tag === 'choose' && (grandName === 'before' || grandName === 'after')) {
218
208
  return [];
@@ -222,7 +212,7 @@ let AstText = (() => {
222
212
  || type === 'ext-link-url'
223
213
  || type === 'ext-link-text'
224
214
  || type === 'image-parameter' && name === 'link'
225
- || isHtmlAttrVal
215
+ || type === 'attr-value'
226
216
  ? errorSyntaxUrl
227
217
  : errorSyntax;
228
218
  if (data.search(errorRegex) === -1) {
@@ -248,72 +238,95 @@ let AstText = (() => {
248
238
  error = error.slice(length);
249
239
  }
250
240
  error = error.toLowerCase();
251
- const [char] = error, magicLink = char === 'r' || char === 'p' || char === 'i';
241
+ const [char] = error, magicLink = char === 'r' || char === 'p' || char === 'i', lbrace = char === '{', rbrace = char === '}', lbrack = char === '[', rbrack = char === ']';
252
242
  let { length } = error;
253
243
  if (char === '<' && !tags.has(tag.toLowerCase())
254
- || char === '[' && type === 'ext-link-text' && (/&(?:rbrack|#93|#x5[Dd];);/u.test(data.slice(index + 1))
244
+ || lbrack && type === 'ext-link-text' && (/&(?:rbrack|#93|#x5[Dd];);/u.test(data.slice(index + 1))
255
245
  || nextSibling?.is('ext') && nextName === 'nowiki'
256
246
  && nextSibling.innerText?.includes(']'))
257
247
  || magicLink && (!parentNode.isPlain() || noLinkTypes.has(type))) {
258
248
  continue;
259
249
  }
260
- else if (char === ']' && (index || length > 1)) {
250
+ else if (rbrack && (index || length > 1)) {
261
251
  errorRegex.lastIndex--;
262
252
  }
263
- let startIndex = start + index, endIndex = startIndex + length;
264
- const nextChar = rootStr[endIndex], previousChar = rootStr[startIndex - 1];
265
- let severity = length > 1 && !(char === '<' && (/^<\s/u.test(error) || !/[\s/>]/u.test(nextChar ?? '') || disallowedTags.has(tag))
266
- || isHtmlAttrVal && (char === '[' || char === ']')
267
- || magicLink && type === 'parameter-value'
268
- || /^(?:rfc|pmid|isbn)$/iu.test(error))
269
- || char === '{' && (nextChar === char || previousChar === '-' && variants.length > 0)
270
- || char === '}' && (previousChar === char || nextChar === '-' && variants.length > 0)
271
- || char === '[' && (type === 'ext-link-text' || nextType === 'free-ext-link' && !data.slice(index + 1).trim())
272
- || char === ']' && previousType === 'free-ext-link'
273
- && !data.slice(0, index).includes(']')
274
- ? 'error'
275
- : 'warning';
276
- const leftBracket = char === '{' || char === '[', rightBracket = char === ']' || char === '}';
277
- if (severity === 'warning' && (leftBracket || rightBracket)) {
278
- const regex = regexes[char], remains = leftBracket ? data.slice(index + 1) : data.slice(0, index);
279
- if (char === '{' && regex.exec(remains)?.[0] === '}'
280
- || char === '}' && regex.exec(remains)?.[0] === '{') {
281
- continue;
282
- }
283
- else if (!remains.includes(char)) {
284
- const sibling = leftBracket ? 'nextSibling' : 'previousSibling';
285
- let cur = this[sibling];
286
- while (cur && (cur.type !== 'text' || !regex.test(cur.data))) {
287
- cur = cur[sibling];
288
- }
289
- if (cur && regex.exec(cur.data)[0] !== char) {
290
- continue;
291
- }
292
- }
293
- }
253
+ // Rule & Severity
254
+ let startIndex = start + index, endIndex = startIndex + length, rule, severity;
255
+ const nextChar = rootStr[endIndex], previousChar = rootStr[startIndex - 1], leftBracket = lbrace || lbrack, lConverter = lbrace && previousChar === '-' && variants.length > 0, rConverter = rbrace && nextChar === '-' && variants.length > 0, brokenExtLink = lbrack && nextType === 'free-ext-link' && !data.slice(index + 1).trim()
256
+ || rbrack && previousType === 'free-ext-link'
257
+ && !data.slice(0, index).includes(']');
294
258
  if (magicLink) {
259
+ rule = 'lonely-http';
295
260
  error = error.toUpperCase();
261
+ severity = index_1.default.lintConfig.getSeverity(rule, error);
296
262
  }
297
- else if (error === '{' && previousChar === '-' && severity === 'error') {
298
- severity = 'warning';
299
- if (index > 0) {
263
+ else if (char === '<') {
264
+ rule = 'tag-like';
265
+ let key;
266
+ if (/^<\s/u.test(error) || !/[\s/>]/u.test(nextChar ?? '')) {
267
+ key = 'invalid';
268
+ }
269
+ else if (disallowedTags.has(tag)) {
270
+ key = 'disallowed';
271
+ }
272
+ severity = index_1.default.lintConfig.getSeverity(rule, key);
273
+ }
274
+ else if (lConverter || rConverter) {
275
+ rule = 'lonely-bracket';
276
+ severity = index_1.default.lintConfig.getSeverity(rule, 'converter');
277
+ if (lConverter && index > 0) {
300
278
  error = '-{';
301
279
  index--;
302
280
  startIndex--;
303
281
  length = 2;
304
282
  }
305
- }
306
- else if (error === '}' && nextChar === '-' && severity === 'error') {
307
- severity = 'warning';
308
- if (index < data.length - 1) {
283
+ else if (rConverter && index < data.length - 1) {
309
284
  error = '}-';
310
285
  endIndex++;
311
286
  length = 2;
312
287
  }
313
288
  }
289
+ else if (brokenExtLink) {
290
+ rule = 'lonely-bracket';
291
+ severity = index_1.default.lintConfig.getSeverity(rule, 'extLink');
292
+ }
293
+ else if (leftBracket || rbrace || rbrack) {
294
+ rule = 'lonely-bracket';
295
+ if (length > 1 || lbrace && nextChar === char || rbrace && previousChar === char) {
296
+ severity = index_1.default.lintConfig.getSeverity(rule, 'double');
297
+ }
298
+ else {
299
+ if (!lbrack || type !== 'ext-link-text') {
300
+ const regex = regexes[char], remains = leftBracket ? data.slice(index + 1) : data.slice(0, index);
301
+ if (lbrace && regex.exec(remains)?.[0] === '}'
302
+ || rbrace && regex.exec(remains)?.[0] === '{') {
303
+ continue;
304
+ }
305
+ else if (!remains.includes(char)) {
306
+ const sibling = leftBracket ? 'nextSibling' : 'previousSibling';
307
+ let cur = this[sibling];
308
+ while (cur && (cur.type !== 'text' || !regex.test(cur.data))) {
309
+ cur = cur[sibling];
310
+ }
311
+ if (cur && regex.exec(cur.data)[0] !== char) {
312
+ continue;
313
+ }
314
+ }
315
+ }
316
+ severity = index_1.default.lintConfig.getSeverity(rule, 'single');
317
+ }
318
+ }
319
+ else {
320
+ rule = 'lonely-http';
321
+ severity = index_1.default.lintConfig.getSeverity(rule);
322
+ }
323
+ if (!severity) {
324
+ continue;
325
+ }
326
+ // LintError
314
327
  const pos = this.posFromIndex(index), { line: startLine, character: startCol } = (0, lint_1.getEndPos)(top, left, pos.top + 1, pos.left), e = {
315
- rule: ruleMap[char],
316
- message: index_1.default.msg('lonely "$1"', magicLink || char === 'h' || error === '-{' || error === '}-' ? error : char),
328
+ rule,
329
+ message: index_1.default.msg('lonely "$1"', magicLink || char === 'h' || lConverter || rConverter ? error : char),
317
330
  severity,
318
331
  startIndex,
319
332
  endIndex,
@@ -322,17 +335,18 @@ let AstText = (() => {
322
335
  startCol,
323
336
  endCol: startCol + length,
324
337
  };
338
+ // Suggestions
325
339
  if (char === '<') {
326
340
  e.suggestions = [{ desc: 'escape', range: [startIndex, startIndex + 1], text: '&lt;' }];
327
341
  }
328
342
  else if (char === 'h' && type !== 'link-text' && wordRegex.test(previousChar || '')) {
329
343
  e.suggestions = [{ desc: 'whitespace', range: [startIndex, startIndex], text: ' ' }];
330
344
  }
331
- else if (char === '[' && type === 'ext-link-text') {
345
+ else if (lbrack && type === 'ext-link-text') {
332
346
  const i = parentNode.getAbsoluteIndex() + parentNode.toString().length;
333
347
  e.suggestions = [{ desc: 'escape', range: [i, i + 1], text: '&#93;' }];
334
348
  }
335
- else if (char === ']' && previousType === 'free-ext-link' && severity === 'error') {
349
+ else if (rbrack && brokenExtLink) {
336
350
  const i = start - previousSibling.toString().length;
337
351
  e.suggestions = [{ desc: 'left bracket', range: [i, i], text: '[' }];
338
352
  }
@@ -36,6 +36,13 @@ export declare class Title {
36
36
  /** @throws `RangeError` undefined namespace */
37
37
  set ns(ns: number);
38
38
  set fragment(fragment: string | undefined);
39
+ /**
40
+ * display title
41
+ *
42
+ * 用于显示的标题
43
+ * @since v1.22.0
44
+ */
45
+ get displayTitle(): string;
39
46
  /**
40
47
  * @see MediaWikiTitleCodec::splitTitleString
41
48
  *
@@ -75,14 +82,14 @@ export declare class Title {
75
82
  * 转换为主页面
76
83
  * @since v1.1.0
77
84
  */
78
- toSubjectPage(): void;
85
+ toSubjectPage(): this;
79
86
  /**
80
87
  * Get the title of its talk page
81
88
  *
82
89
  * 转换为讨论页面
83
90
  * @since v1.1.0
84
91
  */
85
- toTalkPage(): void;
92
+ toTalkPage(): this;
86
93
  /**
87
94
  * Check if the title is a talk page
88
95
  *
@@ -96,12 +103,12 @@ export declare class Title {
96
103
  * 转换为上一级页面
97
104
  * @since v1.1.0
98
105
  */
99
- toBasePage(): void;
106
+ toBasePage(): this;
100
107
  /**
101
108
  * Get the title of its root page
102
109
  *
103
110
  * 转换为根页面
104
111
  * @since v1.1.0
105
112
  */
106
- toRootPage(): void;
113
+ toRootPage(): this;
107
114
  }
package/dist/lib/title.js CHANGED
@@ -94,6 +94,15 @@ class Title {
94
94
  .replaceAll(' ', '_');
95
95
  }
96
96
  }
97
+ /**
98
+ * display title
99
+ *
100
+ * 用于显示的标题
101
+ * @since v1.22.0
102
+ */
103
+ get displayTitle() {
104
+ return this.title.replaceAll('_', ' ');
105
+ }
97
106
  /* NOT FOR BROWSER END */
98
107
  /**
99
108
  * @see MediaWikiTitleCodec::splitTitleString
@@ -236,12 +245,9 @@ class Title {
236
245
  /* NOT FOR BROWSER */
237
246
  /** @private */
238
247
  toString(display) {
239
- return (display ? this.title.replace(/_/gu, ' ') : this.title)
240
- + (this.#fragment === undefined
241
- && this.#redirectFragment === undefined
242
- ? ''
243
- : `#${this.#fragment
244
- ?? this.#redirectFragment}`);
248
+ return (display ? this.displayTitle : this.title) + (this.#fragment === undefined && this.#redirectFragment === undefined
249
+ ? ''
250
+ : `#${this.#fragment ?? this.#redirectFragment}`);
245
251
  }
246
252
  /**
247
253
  * 处理重定向
@@ -283,6 +289,7 @@ class Title {
283
289
  if (this.isTalkPage()) {
284
290
  this.#ns--;
285
291
  }
292
+ return this;
286
293
  }
287
294
  /**
288
295
  * Get the title of its talk page
@@ -294,6 +301,7 @@ class Title {
294
301
  if (!this.isTalkPage()) {
295
302
  this.#ns++;
296
303
  }
304
+ return this;
297
305
  }
298
306
  /**
299
307
  * Check if the title is a talk page
@@ -312,6 +320,7 @@ class Title {
312
320
  */
313
321
  toBasePage() {
314
322
  this.main = this.main.replace(/\/[^/]*$/u, '');
323
+ return this;
315
324
  }
316
325
  /**
317
326
  * Get the title of its root page
@@ -321,6 +330,7 @@ class Title {
321
330
  */
322
331
  toRootPage() {
323
332
  this.main = this.main.replace(/\/.*/u, '');
333
+ return this;
324
334
  }
325
335
  /** @private */
326
336
  getTitleAttr() {
@@ -8,19 +8,19 @@ export interface AttributesParentBase {
8
8
  /** id attribute / id属性 */
9
9
  id: string;
10
10
  /**
11
- * Get the attribute
11
+ * Check if the token has a certain attribute
12
12
  *
13
- * 获取指定属性
13
+ * 是否具有某属性
14
14
  * @param key attribute name / 属性键
15
15
  */
16
- getAttr(key: string): string | true | undefined;
16
+ hasAttr(key: string): boolean;
17
17
  /**
18
- * Check if the token has a certain attribute
18
+ * Get the attribute
19
19
  *
20
- * 是否具有某属性
20
+ * 获取指定属性
21
21
  * @param key attribute name / 属性键
22
22
  */
23
- hasAttr(key: string): boolean;
23
+ getAttr(key: string): string | true | undefined;
24
24
  /**
25
25
  * Get all attribute names
26
26
  *
@@ -43,15 +43,15 @@ const attributesParent = (i = 0) => (constructor) => {
43
43
  return this.childNodes[i];
44
44
  }
45
45
  /** @implements */
46
+ hasAttr(key) {
47
+ return this.#getAttributesChild().hasAttr(key);
48
+ }
49
+ /** @implements */
46
50
  getAttr(key) {
47
51
  return this.#getAttributesChild().getAttr(key);
48
52
  }
49
53
  /* NOT FOR BROWSER */
50
54
  /** @implements */
51
- hasAttr(key) {
52
- return this.#getAttributesChild().hasAttr(key);
53
- }
54
- /** @implements */
55
55
  getAttrNames() {
56
56
  return this.#getAttributesChild().getAttrNames();
57
57
  }
@@ -0,0 +1,5 @@
1
+ import type { Token } from '../internal';
2
+ /**
3
+ * 缓存计算结果
4
+ * @param force 是否强制缓存
5
+ */
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cached = void 0;
4
+ const lint_1 = require("../util/lint");
5
+ /* NOT FOR BROWSER */
6
+ const constants_1 = require("../util/constants");
7
+ /* NOT FOR BROWSER END */
8
+ /**
9
+ * 缓存计算结果
10
+ * @param force 是否强制缓存
11
+ */
12
+ const cached = (force = true) => (method) => {
13
+ const stores = new WeakMap();
14
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
+ return function (...args) {
16
+ return (0, lint_1.cache)(stores.get(this), () => method.apply(this, args), value => {
17
+ stores.set(this, value);
18
+ }, force);
19
+ };
20
+ };
21
+ exports.cached = cached;
22
+ constants_1.mixins['cached'] = __filename;
@@ -0,0 +1,5 @@
1
+ import type { Token } from '../internal';
2
+ /**
3
+ * 深拷贝节点
4
+ * @param method 方法
5
+ */
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.clone = void 0;
4
+ const debug_1 = require("../util/debug");
5
+ const constants_1 = require("../util/constants");
6
+ /**
7
+ * 深拷贝节点
8
+ * @param method 方法
9
+ */
10
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
11
+ const clone = (method) => function () {
12
+ const cloned = this.cloneChildNodes(), { type, name } = this;
13
+ return debug_1.Shadow.run(() => {
14
+ const newToken = method.call(this);
15
+ newToken.safeAppend(cloned);
16
+ if (type === 'ext-inner' && name) {
17
+ newToken.setAttribute('name', name);
18
+ }
19
+ return newToken;
20
+ });
21
+ };
22
+ exports.clone = clone;
23
+ constants_1.mixins['clone'] = __filename;
@@ -1,9 +1,44 @@
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
  Object.defineProperty(exports, "__esModule", { value: true });
3
37
  exports.hiddenToken = void 0;
4
38
  const debug_1 = require("../util/debug");
5
39
  /* NOT FOR BROWSER */
6
40
  const constants_1 = require("../util/constants");
41
+ const cached_1 = require("./cached");
7
42
  /* NOT FOR BROWSER END */
8
43
  /**
9
44
  * 解析后不可见的类
@@ -12,24 +47,39 @@ const constants_1 = require("../util/constants");
12
47
  */
13
48
  const hiddenToken = (linter = true, html = true) => (constructor) => {
14
49
  /** 解析后不可见的类 */
15
- class AnyHiddenToken extends constructor {
16
- /** 没有可见部分 */
17
- text() {
18
- return '';
19
- }
20
- lint(start) {
21
- // @ts-expect-error private argument
22
- return linter ? [] : super.lint(start);
23
- }
24
- /* NOT FOR BROWSER */
25
- /** @private */
26
- dispatchEvent() {
27
- //
28
- }
29
- toHtmlInternal(opt) {
30
- return html ? '' : super.toHtmlInternal(opt);
31
- }
32
- }
50
+ let AnyHiddenToken = (() => {
51
+ let _classSuper = constructor;
52
+ let _instanceExtraInitializers = [];
53
+ let _toHtmlInternal_decorators;
54
+ return class AnyHiddenToken extends _classSuper {
55
+ static {
56
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
57
+ _toHtmlInternal_decorators = [(0, cached_1.cached)()];
58
+ __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);
59
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
60
+ }
61
+ /** 没有可见部分 */
62
+ text() {
63
+ return '';
64
+ }
65
+ lint(start) {
66
+ // @ts-expect-error private argument
67
+ return linter ? [] : super.lint(start);
68
+ }
69
+ /* NOT FOR BROWSER */
70
+ /** @private */
71
+ dispatchEvent() {
72
+ //
73
+ }
74
+ toHtmlInternal(opt) {
75
+ return html ? '' : super.toHtmlInternal(opt);
76
+ }
77
+ constructor() {
78
+ super(...arguments);
79
+ __runInitializers(this, _instanceExtraInitializers);
80
+ }
81
+ };
82
+ })();
33
83
  (0, debug_1.mixin)(AnyHiddenToken, constructor);
34
84
  return AnyHiddenToken;
35
85
  };
package/dist/mixin/sol.js CHANGED
@@ -21,7 +21,7 @@ const sol = (self) => (constructor) => {
21
21
  }
22
22
  return parentNode?.type === 'root'
23
23
  || type === 'list' && parentNode?.is('list-range')
24
- || type !== 'heading' && parentNode?.type === 'ext-inner' && parentNode.name === 'poem'
24
+ || parentNode?.type === 'ext-inner' && parentNode.name === 'poem'
25
25
  ? ''
26
26
  : '\n';
27
27
  }
@@ -16,7 +16,9 @@ const onlyincludeLeft = '<onlyinclude>', onlyincludeRight = '</onlyinclude>', {
16
16
  const noincludeRegex = includeOnly ? 'includeonly' : '(?:no|only)include', includeRegex = includeOnly ? 'noinclude' : 'includeonly';
17
17
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
18
18
  /<!--[\s\S]*?(?:-->|$)|<foo(?:\s[^>]*)?\/?>|<\/foo\s*>|<(bar)(\s[^>]*?)?(?:\/>|>([\s\S]*?)<\/(\1\s*)>)|<(baz)(\s[^>]*?)?(?:\/>|>([\s\S]*?)(?:<\/(baz\s*)>|$))/giu;
19
- return (0, common_1.getRegex)(ext => new RegExp(String.raw `<!--[\s\S]*?(?:-->|$)|<${noincludeRegex}(?:\s[^>]*)?/?>|</${noincludeRegex}\s*>|<(${ext.join('|')})(\s[^>]*?)?(?:/>|>([\s\S]*?)</(\1\s*)>)|<(${includeRegex})(\s[^>]*?)?(?:/>|>([\s\S]*?)(?:</(${includeRegex}\s*)>|$))`, 'giu'));
19
+ return (0, common_1.getObjRegex)(ext => new RegExp(String.raw `<!--[\s\S]*?(?:-->|$)|<${noincludeRegex}(?:\s[^>]*)?/?>|</${noincludeRegex}\s*>|<(${ext.filter(tag => tag !== 'img').join('|')
20
+ // eslint-disable-next-line unicorn/prefer-string-raw
21
+ })(\s[^>]*?)?(?:/>|>([\s\S]*?)</(${'\\1'}\s*)>)|<(${includeRegex})(\s[^>]*?)?(?:/>|>([\s\S]*?)(?:</(${includeRegex}\s*)>|$))${ext.includes('img') ? String.raw `|<img(\s[^>]*?)?(/?)>` : ''}`, 'giu'));
20
22
  });
21
23
  /**
22
24
  * 更新`<onlyinclude>`和`</onlyinclude>`的位置
@@ -77,13 +79,13 @@ const parseCommentAndExt = (wikitext, config, accum, includeOnly) => {
77
79
  });
78
80
  wikitext = (0, string_1.restore)(wikitext, stack);
79
81
  }
80
- return wikitext.replace(getRegex[includeOnly ? 1 : 0](newExt), (substr, name, attr, inner, closing, include, includeAttr, includeInner, includeClosing) => {
82
+ return wikitext.replace(getRegex[includeOnly ? 1 : 0](newExt), (substr, name, attr, inner, closing, include, includeAttr, includeInner, includeClosing, imgAttr, imgClosing) => {
81
83
  const l = accum.length;
82
84
  let ch = 'n';
83
- if (name) {
85
+ if (name || newExt.includes('img') && imgClosing !== undefined) {
84
86
  ch = 'e';
85
87
  // @ts-expect-error abstract class
86
- new ext_1.ExtToken(name, attr, inner, closing, newConfig, include, accum);
88
+ new ext_1.ExtToken(name ?? 'img', name ? attr : imgAttr, inner, name ? closing : imgClosing && undefined, newConfig, include, accum);
87
89
  }
88
90
  else if (substr.startsWith('<!--')) {
89
91
  ch = 'c';
@@ -14,7 +14,7 @@ const constants_1 = require("../util/constants");
14
14
  const parseConverter = (text, config, accum) => {
15
15
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
16
16
  /;(?=(?:[^;]*?=>)?\s*zh\s*:|(?:\s|\0\d+[cn]\x7F)*$)/u;
17
- config.regexConverter ??= new RegExp(String.raw `;(?=(?:[^;]*?=>)?\s*(?:${config.variants.join('|')})\s*:|(?:\s|\0\d+[cn]\x7F)*$)`, 'u');
17
+ config.regexConverter ??= new RegExp(String.raw `;(?=(?:[^;]*?=>)?\s*(?:${config.variants.join('|')})\s*:|(?:\s|\0\d+[cn]\x7F)*$)`, 'iu');
18
18
  const regex1 = /-\{/gu, regex2 = /-\{|\}-/gu, stack = [];
19
19
  let regex = regex1, mt = regex.exec(text);
20
20
  while (mt) {