wikiparser-node 1.11.1 → 1.12.0-b

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 (175) hide show
  1. package/bundle/bundle.min.js +37 -0
  2. package/config/default.json +28 -28
  3. package/config/enwiki.json +14 -827
  4. package/config/llwiki.json +20 -54
  5. package/config/minimum.json +1 -1
  6. package/config/moegirl.json +20 -63
  7. package/config/zhwiki.json +27 -492
  8. package/extensions/dist/base.js +162 -0
  9. package/extensions/dist/codejar.js +52 -0
  10. package/extensions/dist/editor.js +159 -0
  11. package/extensions/dist/highlight.js +30 -0
  12. package/extensions/dist/lint.js +72 -0
  13. package/extensions/editor.css +59 -0
  14. package/extensions/ui.css +159 -0
  15. package/package.json +29 -21
  16. package/config/.schema.json +0 -186
  17. package/dist/addon/table.js +0 -486
  18. package/dist/addon/token.js +0 -304
  19. package/dist/addon/transclude.js +0 -184
  20. package/dist/base.d.ts +0 -81
  21. package/dist/base.js +0 -39
  22. package/dist/index.d.ts +0 -33
  23. package/dist/index.js +0 -235
  24. package/dist/internal.d.ts +0 -46
  25. package/dist/lib/element.d.ts +0 -125
  26. package/dist/lib/element.js +0 -375
  27. package/dist/lib/node.d.ts +0 -173
  28. package/dist/lib/node.js +0 -477
  29. package/dist/lib/range.d.ts +0 -105
  30. package/dist/lib/range.js +0 -406
  31. package/dist/lib/ranges.d.ts +0 -28
  32. package/dist/lib/ranges.js +0 -126
  33. package/dist/lib/rect.d.ts +0 -18
  34. package/dist/lib/rect.js +0 -34
  35. package/dist/lib/text.d.ts +0 -58
  36. package/dist/lib/text.js +0 -400
  37. package/dist/lib/title.d.ts +0 -42
  38. package/dist/lib/title.js +0 -208
  39. package/dist/mixin/attributesParent.d.ts +0 -49
  40. package/dist/mixin/attributesParent.js +0 -79
  41. package/dist/mixin/fixed.d.ts +0 -5
  42. package/dist/mixin/fixed.js +0 -32
  43. package/dist/mixin/flagsParent.d.ts +0 -43
  44. package/dist/mixin/flagsParent.js +0 -64
  45. package/dist/mixin/hidden.d.ts +0 -7
  46. package/dist/mixin/hidden.js +0 -37
  47. package/dist/mixin/magicLinkParent.d.ts +0 -19
  48. package/dist/mixin/magicLinkParent.js +0 -43
  49. package/dist/mixin/singleLine.d.ts +0 -5
  50. package/dist/mixin/singleLine.js +0 -25
  51. package/dist/mixin/sol.d.ts +0 -6
  52. package/dist/mixin/sol.js +0 -45
  53. package/dist/mixin/syntax.d.ts +0 -8
  54. package/dist/mixin/syntax.js +0 -46
  55. package/dist/parser/braces.js +0 -150
  56. package/dist/parser/commentAndExt.js +0 -79
  57. package/dist/parser/converter.js +0 -39
  58. package/dist/parser/externalLinks.js +0 -37
  59. package/dist/parser/hrAndDoubleUnderscore.js +0 -42
  60. package/dist/parser/html.js +0 -38
  61. package/dist/parser/links.js +0 -101
  62. package/dist/parser/list.js +0 -114
  63. package/dist/parser/magicLinks.js +0 -52
  64. package/dist/parser/quotes.js +0 -67
  65. package/dist/parser/redirect.js +0 -26
  66. package/dist/parser/selector.js +0 -394
  67. package/dist/parser/table.js +0 -123
  68. package/dist/src/arg.d.ts +0 -51
  69. package/dist/src/arg.js +0 -214
  70. package/dist/src/atom.d.ts +0 -14
  71. package/dist/src/atom.js +0 -52
  72. package/dist/src/attribute.d.ts +0 -64
  73. package/dist/src/attribute.js +0 -480
  74. package/dist/src/attributes.d.ts +0 -101
  75. package/dist/src/attributes.js +0 -381
  76. package/dist/src/converter.d.ts +0 -28
  77. package/dist/src/converter.js +0 -148
  78. package/dist/src/converterFlags.d.ts +0 -80
  79. package/dist/src/converterFlags.js +0 -239
  80. package/dist/src/converterRule.d.ts +0 -71
  81. package/dist/src/converterRule.js +0 -216
  82. package/dist/src/extLink.d.ts +0 -36
  83. package/dist/src/extLink.js +0 -218
  84. package/dist/src/gallery.d.ts +0 -47
  85. package/dist/src/gallery.js +0 -143
  86. package/dist/src/heading.d.ts +0 -40
  87. package/dist/src/heading.js +0 -192
  88. package/dist/src/hidden.d.ts +0 -9
  89. package/dist/src/hidden.js +0 -80
  90. package/dist/src/html.d.ts +0 -61
  91. package/dist/src/html.js +0 -343
  92. package/dist/src/imageParameter.d.ts +0 -60
  93. package/dist/src/imageParameter.js +0 -260
  94. package/dist/src/imagemap.d.ts +0 -47
  95. package/dist/src/imagemap.js +0 -146
  96. package/dist/src/imagemapLink.d.ts +0 -31
  97. package/dist/src/imagemapLink.js +0 -97
  98. package/dist/src/index.d.ts +0 -136
  99. package/dist/src/index.js +0 -834
  100. package/dist/src/link/base.d.ts +0 -52
  101. package/dist/src/link/base.js +0 -256
  102. package/dist/src/link/category.d.ts +0 -22
  103. package/dist/src/link/category.js +0 -34
  104. package/dist/src/link/file.d.ts +0 -102
  105. package/dist/src/link/file.js +0 -333
  106. package/dist/src/link/galleryImage.d.ts +0 -29
  107. package/dist/src/link/galleryImage.js +0 -132
  108. package/dist/src/link/index.d.ts +0 -39
  109. package/dist/src/link/index.js +0 -98
  110. package/dist/src/link/redirectTarget.d.ts +0 -27
  111. package/dist/src/link/redirectTarget.js +0 -69
  112. package/dist/src/magicLink.d.ts +0 -58
  113. package/dist/src/magicLink.js +0 -256
  114. package/dist/src/nested.d.ts +0 -40
  115. package/dist/src/nested.js +0 -106
  116. package/dist/src/nowiki/base.d.ts +0 -28
  117. package/dist/src/nowiki/base.js +0 -89
  118. package/dist/src/nowiki/comment.d.ts +0 -14
  119. package/dist/src/nowiki/comment.js +0 -121
  120. package/dist/src/nowiki/dd.d.ts +0 -8
  121. package/dist/src/nowiki/dd.js +0 -72
  122. package/dist/src/nowiki/doubleUnderscore.d.ts +0 -15
  123. package/dist/src/nowiki/doubleUnderscore.js +0 -97
  124. package/dist/src/nowiki/hr.d.ts +0 -5
  125. package/dist/src/nowiki/hr.js +0 -70
  126. package/dist/src/nowiki/index.d.ts +0 -14
  127. package/dist/src/nowiki/index.js +0 -28
  128. package/dist/src/nowiki/list.d.ts +0 -5
  129. package/dist/src/nowiki/list.js +0 -65
  130. package/dist/src/nowiki/listBase.d.ts +0 -23
  131. package/dist/src/nowiki/listBase.js +0 -99
  132. package/dist/src/nowiki/noinclude.d.ts +0 -6
  133. package/dist/src/nowiki/noinclude.js +0 -75
  134. package/dist/src/nowiki/quote.d.ts +0 -14
  135. package/dist/src/nowiki/quote.js +0 -140
  136. package/dist/src/onlyinclude.d.ts +0 -13
  137. package/dist/src/onlyinclude.js +0 -58
  138. package/dist/src/paramTag/index.d.ts +0 -28
  139. package/dist/src/paramTag/index.js +0 -78
  140. package/dist/src/paramTag/inputbox.d.ts +0 -8
  141. package/dist/src/paramTag/inputbox.js +0 -22
  142. package/dist/src/parameter.d.ts +0 -60
  143. package/dist/src/parameter.js +0 -264
  144. package/dist/src/pre.d.ts +0 -28
  145. package/dist/src/pre.js +0 -60
  146. package/dist/src/redirect.d.ts +0 -30
  147. package/dist/src/redirect.js +0 -126
  148. package/dist/src/syntax.d.ts +0 -17
  149. package/dist/src/syntax.js +0 -87
  150. package/dist/src/table/base.d.ts +0 -28
  151. package/dist/src/table/base.js +0 -81
  152. package/dist/src/table/index.d.ts +0 -230
  153. package/dist/src/table/index.js +0 -506
  154. package/dist/src/table/td.d.ts +0 -72
  155. package/dist/src/table/td.js +0 -370
  156. package/dist/src/table/tr.d.ts +0 -30
  157. package/dist/src/table/tr.js +0 -59
  158. package/dist/src/table/trBase.d.ts +0 -49
  159. package/dist/src/table/trBase.js +0 -164
  160. package/dist/src/tagPair/ext.d.ts +0 -29
  161. package/dist/src/tagPair/ext.js +0 -220
  162. package/dist/src/tagPair/include.d.ts +0 -33
  163. package/dist/src/tagPair/include.js +0 -130
  164. package/dist/src/tagPair/index.d.ts +0 -23
  165. package/dist/src/tagPair/index.js +0 -128
  166. package/dist/src/transclude.d.ts +0 -159
  167. package/dist/src/transclude.js +0 -587
  168. package/dist/util/constants.js +0 -25
  169. package/dist/util/debug.js +0 -95
  170. package/dist/util/diff.js +0 -83
  171. package/dist/util/html.js +0 -143
  172. package/dist/util/lint.js +0 -32
  173. package/dist/util/string.js +0 -87
  174. package/errors/README +0 -3
  175. package/printed/README +0 -3
package/dist/src/index.js DELETED
@@ -1,834 +0,0 @@
1
- "use strict";
2
- // PHP解析器的步骤:
3
- // -1. 替换签名和`{{subst:}}`,参见Parser::preSaveTransform;这在revision中不可能保留,可以跳过
4
- // 0. 移除特定字符`\0`和`\x7F`,参见Parser::parse
5
- // 1. 注释/扩展标签('<'相关),参见Preprocessor_Hash::buildDomTreeArrayFromText和Sanitizer::decodeTagAttributes
6
- // 2. 模板/模板变量/标题,注意rightmost法则,以及`-{`和`[[`可以破坏`{{`或`{{{`语法,
7
- // 参见Preprocessor_Hash::buildDomTreeArrayFromText
8
- // 3. HTML标签(允许不匹配),参见Sanitizer::internalRemoveHtmlTags
9
- // 4. 表格,参见Parser::handleTables
10
- // 5. 水平线、状态开关和余下的标题,参见Parser::internalParse
11
- // 6. 内链,含文件和分类,参见Parser::handleInternalLinks2
12
- // 7. `'`,参见Parser::doQuotes
13
- // 8. 外链,参见Parser::handleExternalLinks
14
- // 9. ISBN、RFC(未来将废弃,不予支持)和自由外链,参见Parser::handleMagicLinks
15
- // 10. 段落和列表,参见BlockLevelPass::execute
16
- // 11. 转换,参见LanguageConverter::recursiveConvertTopLevel
17
- // \0\d+.\x7F标记Token:
18
- // !: `{{!}}`专用
19
- // {: `{{(!}}`专用
20
- // }: `{{!)}}`专用
21
- // -: `{{!-}}`专用
22
- // +: `{{!!}}`专用
23
- // ~: `{{=}}`专用
24
- // a: AttributeToken
25
- // b: TableToken
26
- // c: CommentToken、NoIncludeToken和IncludeToken
27
- // d: ListToken
28
- // e: ExtToken
29
- // f: MagicLinkToken inside ImageParameterToken
30
- // h: HeadingToken
31
- // i: RFC/PMID/ISBN
32
- // l: LinkToken
33
- // m: `{{fullurl:}}`、`{{canonicalurl:}}`或`{{filepath:}}`
34
- // q: QuoteToken
35
- // r: HrToken
36
- // s: `{{{|subst:}}}`
37
- // t: ArgToken或TranscludeToken
38
- // u: DoubleUnderscoreToken
39
- // v: ConverterToken
40
- // w: ExtLinkToken
41
- // x: HtmlToken
42
- Object.defineProperty(exports, "__esModule", { value: true });
43
- exports.Token = void 0;
44
- const assert = require("assert/strict");
45
- const string_1 = require("../util/string");
46
- const html_1 = require("../util/html");
47
- const constants_1 = require("../util/constants");
48
- const debug_1 = require("../util/debug");
49
- const lint_1 = require("../util/lint");
50
- const ranges_1 = require("../lib/ranges");
51
- const index_1 = require("../index");
52
- const element_1 = require("../lib/element");
53
- const text_1 = require("../lib/text");
54
- /**
55
- * 可接受的Token类型
56
- * @param value 可接受的Token类型
57
- */
58
- const getAcceptable = (value) => {
59
- const acceptable = {};
60
- for (const [k, v] of Object.entries(value)) {
61
- if (k.startsWith('Stage-')) {
62
- for (let i = 0; i <= Number(k.slice(6)); i++) {
63
- for (const type of constants_1.aliases[i]) {
64
- acceptable[type] = new ranges_1.Ranges(v);
65
- }
66
- }
67
- }
68
- else if (k.startsWith('!')) { // `!`项必须放在最后
69
- delete acceptable[k.slice(1)];
70
- }
71
- else {
72
- acceptable[k] = new ranges_1.Ranges(v);
73
- }
74
- }
75
- return acceptable;
76
- };
77
- /* NOT FOR BROWSER END */
78
- /**
79
- * 所有节点的基类
80
- * @classdesc `{childNodes: ...(AstText|Token)}`
81
- */
82
- class Token extends element_1.AstElement {
83
- #type = 'plain';
84
- /** 解析阶段,参见顶部注释。只对plain Token有意义。 */
85
- #stage = 0;
86
- #config;
87
- /** 这个数组起两个作用:1. 数组中的Token会在build时替换`/\0\d+.\x7F/`标记;2. 数组中的Token会依次执行parseOnce和build方法。 */
88
- #accum;
89
- #include;
90
- #built = false;
91
- #string;
92
- /* NOT FOR BROWSER */
93
- #acceptable;
94
- #protectedChildren = new ranges_1.Ranges();
95
- /* NOT FOR BROWSER END */
96
- get type() {
97
- return this.#type;
98
- }
99
- set type(value) {
100
- /* NOT FOR BROWSER */
101
- const plainTypes = [
102
- 'plain',
103
- 'root',
104
- 'table-inter',
105
- 'arg-default',
106
- 'attr-value',
107
- 'ext-link-text',
108
- 'heading-title',
109
- 'parameter-key',
110
- 'parameter-value',
111
- 'link-text',
112
- 'td-inner',
113
- 'ext-inner',
114
- 'list-range',
115
- ];
116
- if (!plainTypes.includes(value)) {
117
- throw new RangeError(`"${value}" is not a valid type for ${this.constructor.name}!`);
118
- }
119
- /* NOT FOR BROWSER END */
120
- this.#type = value;
121
- }
122
- /* NOT FOR BROWSER */
123
- /** 所有图片,包括图库 */
124
- get images() {
125
- return this.querySelectorAll('file, gallery-image, imagemap-image');
126
- }
127
- /** 所有内链、外链和自由外链 */
128
- get links() {
129
- return this.querySelectorAll('link, redirect-target, ext-link, free-ext-link, magic-link, image-parameter#link');
130
- }
131
- /** 所有模板和模块 */
132
- get embeds() {
133
- return this.querySelectorAll('template, magic-word#invoke');
134
- }
135
- /* NOT FOR BROWSER END */
136
- /** @class */
137
- constructor(wikitext, config = index_1.default.getConfig(), accum = [], acceptable) {
138
- super();
139
- if (typeof wikitext === 'string') {
140
- this.insertAt(wikitext);
141
- }
142
- this.#config = config;
143
- this.#accum = accum;
144
- accum.push(this);
145
- /* NOT FOR BROWSER */
146
- this.setAttribute('acceptable', acceptable);
147
- }
148
- /** @private */
149
- parseOnce(n = this.#stage, include = false) {
150
- if (n < this.#stage || this.length === 0 || !this.getAttribute('plain')) {
151
- return this;
152
- }
153
- else if (this.#stage >= constants_1.MAX_STAGE) {
154
- /* NOt FOR BROWSER */
155
- if (this.type === 'root') {
156
- index_1.default.error('Fully parsed!');
157
- }
158
- /* NOT FOR BROWSER END */
159
- return this;
160
- }
161
- switch (n) {
162
- case 0:
163
- if (this.type === 'root') {
164
- this.#accum.pop();
165
- const isRedirect = this.#parseRedirect();
166
- include &&= !isRedirect;
167
- }
168
- this.#include = include;
169
- this.#parseCommentAndExt(include);
170
- break;
171
- case 1:
172
- this.#parseBraces();
173
- break;
174
- case 2:
175
- this.#parseHtml();
176
- break;
177
- case 3:
178
- this.#parseTable();
179
- break;
180
- case 4:
181
- this.#parseHrAndDoubleUnderscore();
182
- break;
183
- case 5:
184
- this.#parseLinks();
185
- break;
186
- case 6:
187
- this.#parseQuotes();
188
- break;
189
- case 7:
190
- this.#parseExternalLinks();
191
- break;
192
- case 8:
193
- this.#parseMagicLinks();
194
- break;
195
- case 9:
196
- this.#parseList();
197
- break;
198
- case 10:
199
- this.#parseConverter();
200
- // no default
201
- }
202
- if (this.type === 'root') {
203
- for (const token of this.#accum) {
204
- token?.parseOnce(n, include); // eslint-disable-line @typescript-eslint/no-unnecessary-condition
205
- }
206
- }
207
- this.#stage++;
208
- return this;
209
- }
210
- /** @private */
211
- buildFromStr(str, type) {
212
- const nodes = str.split(/[\0\x7F]/u).map((s, i) => {
213
- if (i % 2 === 0) {
214
- return new text_1.AstText(s);
215
- }
216
- else if (isNaN(s.slice(-1))) {
217
- return this.#accum[Number(s.slice(0, -1))];
218
- }
219
- throw new Error(`Failed to build! Unrecognized token: ${s}`);
220
- });
221
- if (type === constants_1.BuildMethod.String) {
222
- return nodes.map(String).join('');
223
- }
224
- else if (type === constants_1.BuildMethod.Text) {
225
- return (0, string_1.text)(nodes);
226
- }
227
- return nodes;
228
- }
229
- /** @private */
230
- build() {
231
- this.#stage = constants_1.MAX_STAGE;
232
- const { length, firstChild } = this, str = String(firstChild);
233
- if (length === 1 && firstChild.type === 'text' && str.includes('\0')) {
234
- this.replaceChildren(...this.buildFromStr(str));
235
- this.normalize();
236
- if (this.type === 'root') {
237
- for (const token of this.#accum) {
238
- token?.build(); // eslint-disable-line @typescript-eslint/no-unnecessary-condition
239
- }
240
- }
241
- }
242
- }
243
- /** @private */
244
- afterBuild() {
245
- if (this.type === 'root') {
246
- for (const token of this.#accum) {
247
- token?.afterBuild(); // eslint-disable-line @typescript-eslint/no-unnecessary-condition
248
- }
249
- }
250
- this.#built = true;
251
- }
252
- /** @private */
253
- parse(n = constants_1.MAX_STAGE, include) {
254
- n = Math.min(n, constants_1.MAX_STAGE);
255
- while (this.#stage < n) {
256
- this.parseOnce(this.#stage, include);
257
- }
258
- if (n) {
259
- this.build();
260
- this.afterBuild();
261
- }
262
- return this;
263
- }
264
- /** 解析重定向 */
265
- #parseRedirect() {
266
- const { parseRedirect } = require('../parser/redirect');
267
- const wikitext = this.firstChild.toString(), parsed = parseRedirect(wikitext, this.#config, this.#accum);
268
- if (parsed) {
269
- this.setText(parsed);
270
- }
271
- return Boolean(parsed);
272
- }
273
- /**
274
- * 解析HTML注释和扩展标签
275
- * @param includeOnly 是否嵌入
276
- */
277
- #parseCommentAndExt(includeOnly) {
278
- const { parseCommentAndExt } = require('../parser/commentAndExt');
279
- this.setText(parseCommentAndExt(this.firstChild.toString(), this.#config, this.#accum, includeOnly));
280
- }
281
- /** 解析花括号 */
282
- #parseBraces() {
283
- const { parseBraces } = require('../parser/braces');
284
- const str = this.type === 'root' ? this.firstChild.toString() : `\0${this.firstChild.toString()}`, parsed = parseBraces(str, this.#config, this.#accum);
285
- this.setText(this.type === 'root' ? parsed : parsed.slice(1));
286
- }
287
- /** 解析HTML标签 */
288
- #parseHtml() {
289
- if (this.#config.excludes?.includes('html')) {
290
- return;
291
- }
292
- const { parseHtml } = require('../parser/html');
293
- this.setText(parseHtml(this.firstChild.toString(), this.#config, this.#accum));
294
- }
295
- /** 解析表格 */
296
- #parseTable() {
297
- if (this.#config.excludes?.includes('table')) {
298
- return;
299
- }
300
- const { parseTable } = require('../parser/table');
301
- this.setText(parseTable(this, this.#config, this.#accum));
302
- }
303
- /** 解析`<hr>`和状态开关 */
304
- #parseHrAndDoubleUnderscore() {
305
- if (this.#config.excludes?.includes('hr')) {
306
- return;
307
- }
308
- const { parseHrAndDoubleUnderscore } = require('../parser/hrAndDoubleUnderscore');
309
- this.setText(parseHrAndDoubleUnderscore(this, this.#config, this.#accum));
310
- }
311
- /** 解析内部链接 */
312
- #parseLinks() {
313
- const { parseLinks } = require('../parser/links');
314
- this.setText(parseLinks(this.firstChild.toString(), this.#config, this.#accum));
315
- }
316
- /** 解析单引号 */
317
- #parseQuotes() {
318
- if (this.#config.excludes?.includes('quote')) {
319
- return;
320
- }
321
- const { parseQuotes } = require('../parser/quotes');
322
- const lines = this.firstChild.toString().split('\n');
323
- for (let i = 0; i < lines.length; i++) {
324
- lines[i] = parseQuotes(lines[i], this.#config, this.#accum);
325
- }
326
- this.setText(lines.join('\n'));
327
- }
328
- /** 解析外部链接 */
329
- #parseExternalLinks() {
330
- if (this.#config.excludes?.includes('extLink')) {
331
- return;
332
- }
333
- const { parseExternalLinks } = require('../parser/externalLinks');
334
- this.setText(parseExternalLinks(this.firstChild.toString(), this.#config, this.#accum));
335
- }
336
- /** 解析自由外链 */
337
- #parseMagicLinks() {
338
- if (this.#config.excludes?.includes('magicLink')) {
339
- return;
340
- }
341
- const { parseMagicLinks } = require('../parser/magicLinks');
342
- this.setText(parseMagicLinks(this.firstChild.toString(), this.#config, this.#accum));
343
- }
344
- /** 解析列表 */
345
- #parseList() {
346
- if (this.#config.excludes?.includes('list')) {
347
- return;
348
- }
349
- const { parseList } = require('../parser/list');
350
- const lines = this.firstChild.toString().split('\n'), state = { lastPrefix: '' };
351
- let i = this.type === 'root' || this.type === 'ext-inner' && this.name === 'poem' ? 0 : 1;
352
- for (; i < lines.length; i++) {
353
- lines[i] = parseList(lines[i], state, this.#config, this.#accum);
354
- }
355
- this.setText(lines.join('\n'));
356
- }
357
- /** 解析语言变体转换 */
358
- #parseConverter() {
359
- if (this.#config.variants.length > 0) {
360
- const { parseConverter } = require('../parser/converter');
361
- this.setText(parseConverter(this.firstChild.toString(), this.#config, this.#accum));
362
- }
363
- }
364
- /** @private */
365
- getAttribute(key) {
366
- switch (key) {
367
- case 'plain':
368
- return (this.constructor === Token);
369
- case 'config':
370
- return this.#config;
371
- case 'include':
372
- return (this.#include ?? Boolean(this.getRootNode().#include));
373
- case 'accum':
374
- return this.#accum;
375
- case 'built':
376
- return this.#built;
377
- /* NOT FOR BROWSER */
378
- case 'stage':
379
- return this.#stage;
380
- case 'protectedChildren':
381
- return this.#protectedChildren;
382
- /* NOT FOR BROWSER END */
383
- default:
384
- return super.getAttribute(key);
385
- }
386
- }
387
- /** @private */
388
- setAttribute(key, value) {
389
- switch (key) {
390
- case 'stage':
391
- if (this.#stage === 0 && this.type === 'root') {
392
- this.#accum.shift();
393
- }
394
- this.#stage = value;
395
- break;
396
- /* NOT FOR BROWSER */
397
- case 'acceptable':
398
- this.#acceptable = value && (() => getAcceptable(value));
399
- break;
400
- /* NOT FOR BROWSER END */
401
- default:
402
- super.setAttribute(key, value);
403
- }
404
- }
405
- insertAt(child, i = this.length) {
406
- const token = typeof child === 'string' ? new text_1.AstText(child) : child;
407
- /* NOT FOR BROWSER */
408
- const acceptable = this.getAcceptable();
409
- if (!debug_1.Shadow.running && acceptable) {
410
- const acceptableIndices = Object.fromEntries(Object.entries(acceptable).map(([str, ranges]) => [str, ranges.applyTo(this.length + 1)])), nodesAfter = this.childNodes.slice(i), insertedName = token.constructor.name;
411
- i += i < 0 ? this.length : 0;
412
- if (!acceptableIndices[insertedName]?.includes(i)) {
413
- this.constructorError(`cannot insert a ${insertedName} at position ${i}`);
414
- }
415
- else if (nodesAfter.some(({ constructor: { name } }, j) => !acceptableIndices[name]?.includes(i + j + 1))) {
416
- this.constructorError(`violates the order of acceptable nodes by inserting a child node at position ${i}`);
417
- }
418
- }
419
- /* NOT FOR BROWSER END */
420
- super.insertAt(token, i);
421
- /* NOT FOR BROWSER */
422
- const e = new Event('insert', { bubbles: true });
423
- this.dispatchEvent(e, { type: 'insert', position: i < 0 ? i + this.length - 1 : i });
424
- if (token.type !== 'list-range' && token.constructor === Token && this.getAttribute('plain')) {
425
- index_1.default.warn('You are inserting a plain token as a child of another plain token. '
426
- + 'Consider calling Token.flatten method afterwards.');
427
- }
428
- /* NOT FOR BROWSER END */
429
- if (token.type === 'root') {
430
- token.type = 'plain';
431
- }
432
- return token;
433
- }
434
- /** @private */
435
- normalizeTitle(title, defaultNs = 0, halfParsed, decode, selfLink) {
436
- return index_1.default.normalizeTitle(title, defaultNs, this.#include, this.#config, halfParsed, decode, selfLink);
437
- }
438
- /** @private */
439
- lint(start = this.getAbsoluteIndex(), re) {
440
- const { viewOnly } = index_1.default;
441
- index_1.default.viewOnly = true;
442
- let errors = super.lint(start, re);
443
- if (this.type === 'root') {
444
- const record = {};
445
- for (const cat of this.querySelectorAll('category')) {
446
- const thisCat = record[cat.name];
447
- if (thisCat) {
448
- thisCat.add(cat);
449
- }
450
- else {
451
- record[cat.name] = new Set([cat]);
452
- }
453
- }
454
- for (const value of Object.values(record)) {
455
- if (value.size > 1) {
456
- errors.push(...[...value].map(cat => {
457
- const e = (0, lint_1.generateForSelf)(cat, { start: cat.getAbsoluteIndex() }, 'no-duplicate', 'duplicated category');
458
- e.suggestions = [
459
- {
460
- desc: 'remove',
461
- range: [e.startIndex, e.endIndex],
462
- text: '',
463
- },
464
- ];
465
- return e;
466
- }));
467
- }
468
- }
469
- const regex = /<!--\s*lint-(disable(?:(?:-next)?-line)?|enable)(\s[\sa-z,-]*)?-->/gu, wikitext = this.toString(), ignores = [];
470
- let mt = regex.exec(wikitext), last = 0, curLine = 0;
471
- while (mt) {
472
- const { 1: type, index } = mt, detail = mt[2]?.trim();
473
- curLine += wikitext.slice(last, index).split('\n').length - 1;
474
- last = index;
475
- ignores.push({
476
- line: curLine + (type === 'disable-line' ? 0 : 1),
477
- from: type === 'disable' ? regex.lastIndex : undefined,
478
- to: type === 'enable' ? regex.lastIndex : undefined,
479
- rules: detail ? new Set(detail.split(',').map(r => r.trim())) : undefined,
480
- });
481
- mt = regex.exec(wikitext);
482
- }
483
- errors = errors.filter(({ rule, startLine, startIndex }) => {
484
- const nearest = { pos: 0 };
485
- for (const { line, from, to, rules } of ignores) {
486
- if (line > startLine + 1) {
487
- break;
488
- }
489
- else if (rules && !rules.has(rule)) {
490
- continue;
491
- }
492
- else if (line === startLine && from === undefined && to === undefined) {
493
- return false;
494
- }
495
- else if (from <= startIndex && from > nearest.pos) {
496
- nearest.pos = from;
497
- nearest.type = 'from';
498
- }
499
- else if (to <= startIndex && to > nearest.pos) {
500
- nearest.pos = to;
501
- nearest.type = 'to';
502
- }
503
- }
504
- return nearest.type !== 'from';
505
- });
506
- }
507
- index_1.default.viewOnly = viewOnly;
508
- return errors;
509
- }
510
- /** @private */
511
- toString(skip, separator) {
512
- const { rev } = debug_1.Shadow, root = this.getRootNode();
513
- if (this.#string && this.#string[0] !== rev) {
514
- this.#string = undefined;
515
- }
516
- if (!skip
517
- && root.type === 'root'
518
- && root.#built
519
- && index_1.default.viewOnly) {
520
- this.#string ??= [rev, super.toString(false, separator)];
521
- return this.#string[1];
522
- }
523
- return super.toString(skip, separator);
524
- }
525
- /* NOT FOR BROWSER */
526
- /** @private */
527
- getAcceptable() {
528
- if (typeof this.#acceptable === 'function') {
529
- this.#acceptable = this.#acceptable();
530
- }
531
- return this.#acceptable;
532
- }
533
- /** @private */
534
- dispatchEvent(e, data) {
535
- if (this.#built) {
536
- super.dispatchEvent(e, data);
537
- }
538
- }
539
- /** @private */
540
- protectChildren(...args) {
541
- this.#protectedChildren.push(...new ranges_1.Ranges(args));
542
- }
543
- /**
544
- * @override
545
- * @param i 移除位置
546
- */
547
- removeAt(i) {
548
- i += i < 0 ? this.length : 0;
549
- if (!debug_1.Shadow.running) {
550
- const protectedIndices = this.#protectedChildren.applyTo(this.childNodes);
551
- if (protectedIndices.includes(i)) {
552
- this.constructorError(`cannot remove the child node at position ${i}`);
553
- }
554
- const acceptable = this.getAcceptable();
555
- if (acceptable) {
556
- const acceptableIndices = Object.fromEntries(Object.entries(acceptable).map(([str, ranges]) => [str, ranges.applyTo(this.length - 1)])), nodesAfter = this.childNodes.slice(i + 1);
557
- if (nodesAfter.some(({ constructor: { name } }, j) => !acceptableIndices[name]?.includes(i + j))) {
558
- this.constructorError(`violates the order of acceptable nodes by removing the child node at position ${i}`);
559
- }
560
- }
561
- }
562
- const node = super.removeAt(i);
563
- const e = new Event('remove', { bubbles: true });
564
- this.dispatchEvent(e, { type: 'remove', position: i, removed: node });
565
- return node;
566
- }
567
- /**
568
- * 替换为同类节点
569
- * @param token 待替换的节点
570
- * @throws `Error` 不存在父节点
571
- */
572
- safeReplaceWith(token) {
573
- const { parentNode } = this;
574
- if (!parentNode) {
575
- throw new Error('The node does not have a parent node!');
576
- }
577
- else if (token.constructor !== this.constructor) {
578
- this.typeError('safeReplaceWith', this.constructor.name);
579
- }
580
- try {
581
- assert.deepEqual(token.getAcceptable(), this.getAcceptable());
582
- }
583
- catch (e) {
584
- if (e instanceof assert.AssertionError) {
585
- this.constructorError('has a different #acceptable property');
586
- }
587
- throw e;
588
- }
589
- const i = parentNode.childNodes.indexOf(this);
590
- super.removeAt.call(parentNode, i);
591
- super.insertAt.call(parentNode, token, i);
592
- if (token.type === 'root') {
593
- token.type = 'plain';
594
- }
595
- const e = new Event('replace', { bubbles: true });
596
- token.dispatchEvent(e, { type: 'replace', position: i, oldToken: this });
597
- }
598
- /**
599
- * 创建HTML注释
600
- * @param data 注释内容
601
- */
602
- createComment(data) {
603
- require('../addon/token');
604
- return this.createComment(data);
605
- }
606
- /**
607
- * 创建标签
608
- * @param tagName 标签名
609
- * @param options 选项
610
- * @param options.selfClosing 是否自封闭
611
- * @param options.closing 是否是闭合标签
612
- * @throws `RangeError` 非法的标签名
613
- */
614
- createElement(tagName, options) {
615
- require('../addon/token');
616
- return this.createElement(tagName, options);
617
- }
618
- /**
619
- * 创建纯文本节点
620
- * @param data 文本内容
621
- */
622
- createTextNode(data = '') {
623
- return new text_1.AstText(data);
624
- }
625
- /** 创建AstRange对象 */
626
- createRange() {
627
- const { AstRange } = require('../lib/range');
628
- return new AstRange();
629
- }
630
- /**
631
- * 找到给定位置
632
- * @param index 位置
633
- */
634
- caretPositionFromIndex(index) {
635
- require('../addon/token');
636
- return this.caretPositionFromIndex(index);
637
- }
638
- /**
639
- * 找到给定位置
640
- * @param x 列数
641
- * @param y 行数
642
- */
643
- caretPositionFromPoint(x, y) {
644
- return this.caretPositionFromIndex(this.indexFromPos(y, x));
645
- }
646
- /**
647
- * 找到给定位置所在的最外层节点
648
- * @param index 位置
649
- */
650
- elementFromIndex(index) {
651
- return this.caretPositionFromIndex(index)?.offsetNode;
652
- }
653
- /**
654
- * 找到给定位置所在的最外层节点
655
- * @param x 列数
656
- * @param y 行数
657
- */
658
- elementFromPoint(x, y) {
659
- return this.elementFromIndex(this.indexFromPos(y, x));
660
- }
661
- /**
662
- * 找到给定位置所在的所有节点
663
- * @param index 位置
664
- */
665
- elementsFromIndex(index) {
666
- const offsetNode = this.caretPositionFromIndex(index)?.offsetNode;
667
- return offsetNode ? [...offsetNode.getAncestors().reverse(), offsetNode] : [];
668
- }
669
- /**
670
- * 找到给定位置所在的所有节点
671
- * @param x 列数
672
- * @param y 行数
673
- */
674
- elementsFromPoint(x, y) {
675
- return this.elementsFromIndex(this.indexFromPos(y, x));
676
- }
677
- /**
678
- * 判断标题是否是跨维基链接
679
- * @param title 标题
680
- */
681
- isInterwiki(title) {
682
- return index_1.default.isInterwiki(title, this.#config);
683
- }
684
- /** @private */
685
- cloneChildNodes() {
686
- return this.childNodes.map(child => child.cloneNode());
687
- }
688
- /** 深拷贝节点 */
689
- cloneNode() {
690
- if (this.constructor !== Token) {
691
- this.constructorError('does not specify a cloneNode method');
692
- }
693
- const cloned = this.cloneChildNodes();
694
- return debug_1.Shadow.run(() => {
695
- const token = new Token(undefined, this.#config, [], this.getAcceptable());
696
- token.type = this.type;
697
- token.setAttribute('stage', this.#stage);
698
- token.setAttribute('name', this.name);
699
- token.append(...cloned);
700
- token.protectChildren(...this.#protectedChildren);
701
- return token;
702
- });
703
- }
704
- /** 获取全部章节 */
705
- sections() {
706
- require('../addon/token');
707
- return this.sections();
708
- }
709
- /**
710
- * 获取指定章节
711
- * @param n 章节序号
712
- */
713
- section(n) {
714
- return this.sections()?.[n];
715
- }
716
- /**
717
- * 获取指定的外层HTML标签
718
- * @param tag HTML标签名
719
- * @throws `RangeError` 非法的标签或空标签
720
- */
721
- findEnclosingHtml(tag) {
722
- require('../addon/token');
723
- return this.findEnclosingHtml(tag);
724
- }
725
- /** 获取全部分类 */
726
- getCategories() {
727
- const categories = this.querySelectorAll('category');
728
- return categories.map(({ name, sortkey }) => [name, sortkey]);
729
- }
730
- /**
731
- * 展开模板
732
- * @param context 模板调用环境
733
- */
734
- expand() {
735
- require('../addon/token');
736
- return this.expand();
737
- }
738
- /** 解析部分魔术字 */
739
- solveConst() {
740
- require('../addon/token');
741
- return this.solveConst();
742
- }
743
- /** 合并普通节点的普通子节点 */
744
- flatten() {
745
- if (this.getAttribute('plain')) {
746
- for (const child of this.childNodes) {
747
- if (child.type !== 'text' && child.getAttribute('plain')) {
748
- child.replaceWith(...child.childNodes);
749
- }
750
- }
751
- }
752
- }
753
- /** 生成HTML */
754
- toHtml() {
755
- if (this.type !== 'root') {
756
- return this.cloneNode().toHtmlInternal();
757
- }
758
- const lines = this.expand().toHtmlInternal().split('\n'), blockElems = 'table|h1|h2|h3|h4|h5|h6|pre|p|ul|ol|dl', antiBlockElems = 'td|th', openRegex = new RegExp(String.raw `<(?:${blockElems}|\/(?:${antiBlockElems})|\/?(?:tr|caption|dt|dd|li))\b`, 'iu'), closeRegex = new RegExp(String.raw `<(?:\/(?:${blockElems})|${antiBlockElems}|\/?(?:center|blockquote|div|hr|figure))\b`, 'iu');
759
- let output = '', inBlockElem = false, pendingPTag = false, inBlockquote = false, lastParagraph = '';
760
- const /** @ignore */ closeParagraph = () => {
761
- if (lastParagraph) {
762
- const result = `</${lastParagraph}>\n`;
763
- lastParagraph = '';
764
- return result;
765
- }
766
- return '';
767
- };
768
- for (let line of lines) {
769
- const openMatch = openRegex.test(line), closeMatch = closeRegex.test(line);
770
- if (openMatch || closeMatch) {
771
- pendingPTag = false;
772
- output += closeParagraph();
773
- inBlockquote = /<(\/?)blockquote[\s>](?!.*<\/?blockquote[\s>])/iu.exec(line)?.[1] === '';
774
- inBlockElem = !closeMatch;
775
- }
776
- else if (!inBlockElem) {
777
- if (line.startsWith(' ') && (lastParagraph === 'pre' || line.trim()) && !inBlockquote) {
778
- if (lastParagraph !== 'pre') {
779
- pendingPTag = false;
780
- output += `${closeParagraph()}<pre>`;
781
- lastParagraph = 'pre';
782
- }
783
- line = line.slice(1);
784
- }
785
- else if (/^(?:<link\b[^>]*>\s*)+$/iu.test(line)) {
786
- if (pendingPTag) {
787
- output += closeParagraph();
788
- pendingPTag = false;
789
- }
790
- }
791
- else if (!line.trim()) {
792
- if (pendingPTag) {
793
- output += `${pendingPTag}<br>`;
794
- pendingPTag = false;
795
- lastParagraph = 'p';
796
- }
797
- else if (lastParagraph === 'p') {
798
- pendingPTag = '</p><p>';
799
- }
800
- else {
801
- output += closeParagraph();
802
- pendingPTag = '<p>';
803
- }
804
- }
805
- else if (pendingPTag) {
806
- output += pendingPTag;
807
- pendingPTag = false;
808
- lastParagraph = 'p';
809
- }
810
- else if (lastParagraph !== 'p') {
811
- output += `${closeParagraph()}<p>`;
812
- lastParagraph = 'p';
813
- }
814
- }
815
- if (!pendingPTag) {
816
- output += `${line}\n`;
817
- }
818
- }
819
- output += closeParagraph();
820
- return output.trimEnd();
821
- }
822
- /** @private */
823
- toHtmlInternal(nowrap) {
824
- for (let i = 0; i < this.length; i++) {
825
- const child = this.childNodes[i];
826
- if (child.is('list') || child.is('dd')) {
827
- child.getRange();
828
- }
829
- }
830
- return (0, html_1.font)(this, (0, html_1.html)(this.childNodes, '', nowrap));
831
- }
832
- }
833
- exports.Token = Token;
834
- constants_1.classes['Token'] = __filename;