wikiparser-node 1.0.0-beta.3 → 1.0.1-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 (146) hide show
  1. package/README.md +10 -9
  2. package/bundle/bundle.min.js +37 -0
  3. package/config/llwiki.json +1 -35
  4. package/config/minimum.json +136 -0
  5. package/config/moegirl.json +1 -44
  6. package/config/zhwiki.json +1 -466
  7. package/extensions/dist/base.js +105 -0
  8. package/extensions/dist/editor.js +172 -0
  9. package/extensions/dist/highlight.js +46 -0
  10. package/extensions/dist/lint.js +43 -0
  11. package/extensions/editor.css +63 -0
  12. package/extensions/ui.css +119 -0
  13. package/package.json +35 -20
  14. package/config/.schema.json +0 -160
  15. package/dist/index.d.ts +0 -62
  16. package/dist/index.js +0 -305
  17. package/dist/internal.d.ts +0 -44
  18. package/dist/lib/element.d.ts +0 -186
  19. package/dist/lib/element.js +0 -659
  20. package/dist/lib/node.d.ts +0 -178
  21. package/dist/lib/node.js +0 -458
  22. package/dist/lib/range.d.ts +0 -132
  23. package/dist/lib/range.js +0 -387
  24. package/dist/lib/ranges.d.ts +0 -28
  25. package/dist/lib/ranges.js +0 -125
  26. package/dist/lib/text.d.ts +0 -78
  27. package/dist/lib/text.js +0 -227
  28. package/dist/lib/title.d.ts +0 -33
  29. package/dist/lib/title.js +0 -110
  30. package/dist/mixin/attributesParent.js +0 -93
  31. package/dist/mixin/fixed.js +0 -32
  32. package/dist/mixin/hidden.js +0 -23
  33. package/dist/mixin/singleLine.js +0 -26
  34. package/dist/mixin/sol.js +0 -44
  35. package/dist/parser/braces.js +0 -125
  36. package/dist/parser/commentAndExt.js +0 -58
  37. package/dist/parser/converter.js +0 -38
  38. package/dist/parser/externalLinks.js +0 -28
  39. package/dist/parser/hrAndDoubleUnderscore.js +0 -40
  40. package/dist/parser/html.js +0 -38
  41. package/dist/parser/links.js +0 -94
  42. package/dist/parser/list.js +0 -61
  43. package/dist/parser/magicLinks.js +0 -39
  44. package/dist/parser/quotes.js +0 -67
  45. package/dist/parser/selector.js +0 -165
  46. package/dist/parser/table.js +0 -117
  47. package/dist/src/arg.d.ts +0 -77
  48. package/dist/src/arg.js +0 -199
  49. package/dist/src/atom.d.ts +0 -11
  50. package/dist/src/atom.js +0 -24
  51. package/dist/src/attribute.d.ts +0 -106
  52. package/dist/src/attribute.js +0 -436
  53. package/dist/src/attributes.d.ts +0 -119
  54. package/dist/src/attributes.js +0 -366
  55. package/dist/src/converter.d.ts +0 -75
  56. package/dist/src/converter.js +0 -141
  57. package/dist/src/converterFlags.d.ts +0 -107
  58. package/dist/src/converterFlags.js +0 -238
  59. package/dist/src/converterRule.d.ts +0 -96
  60. package/dist/src/converterRule.js +0 -255
  61. package/dist/src/extLink.d.ts +0 -63
  62. package/dist/src/extLink.js +0 -157
  63. package/dist/src/gallery.d.ts +0 -70
  64. package/dist/src/gallery.js +0 -137
  65. package/dist/src/heading.d.ts +0 -82
  66. package/dist/src/heading.js +0 -135
  67. package/dist/src/hidden.d.ts +0 -19
  68. package/dist/src/hidden.js +0 -26
  69. package/dist/src/html.d.ts +0 -113
  70. package/dist/src/html.js +0 -245
  71. package/dist/src/imageParameter.d.ts +0 -82
  72. package/dist/src/imageParameter.js +0 -256
  73. package/dist/src/imagemap.d.ts +0 -77
  74. package/dist/src/imagemap.js +0 -169
  75. package/dist/src/imagemapLink.d.ts +0 -48
  76. package/dist/src/imagemapLink.js +0 -43
  77. package/dist/src/index.d.ts +0 -156
  78. package/dist/src/index.js +0 -819
  79. package/dist/src/link/base.d.ts +0 -69
  80. package/dist/src/link/base.js +0 -231
  81. package/dist/src/link/category.d.ts +0 -14
  82. package/dist/src/link/category.js +0 -28
  83. package/dist/src/link/file.d.ts +0 -105
  84. package/dist/src/link/file.js +0 -269
  85. package/dist/src/link/galleryImage.d.ts +0 -37
  86. package/dist/src/link/galleryImage.js +0 -100
  87. package/dist/src/link/index.d.ts +0 -50
  88. package/dist/src/link/index.js +0 -134
  89. package/dist/src/magicLink.d.ts +0 -46
  90. package/dist/src/magicLink.js +0 -131
  91. package/dist/src/nested.d.ts +0 -47
  92. package/dist/src/nested.js +0 -92
  93. package/dist/src/nowiki/base.d.ts +0 -38
  94. package/dist/src/nowiki/base.js +0 -31
  95. package/dist/src/nowiki/comment.d.ts +0 -42
  96. package/dist/src/nowiki/comment.js +0 -64
  97. package/dist/src/nowiki/dd.d.ts +0 -22
  98. package/dist/src/nowiki/dd.js +0 -46
  99. package/dist/src/nowiki/doubleUnderscore.d.ts +0 -35
  100. package/dist/src/nowiki/doubleUnderscore.js +0 -48
  101. package/dist/src/nowiki/hr.d.ts +0 -30
  102. package/dist/src/nowiki/hr.js +0 -36
  103. package/dist/src/nowiki/index.d.ts +0 -19
  104. package/dist/src/nowiki/index.js +0 -23
  105. package/dist/src/nowiki/list.d.ts +0 -16
  106. package/dist/src/nowiki/list.js +0 -13
  107. package/dist/src/nowiki/noinclude.d.ts +0 -21
  108. package/dist/src/nowiki/noinclude.js +0 -24
  109. package/dist/src/nowiki/quote.d.ts +0 -27
  110. package/dist/src/nowiki/quote.js +0 -58
  111. package/dist/src/onlyinclude.d.ts +0 -38
  112. package/dist/src/onlyinclude.js +0 -66
  113. package/dist/src/paramTag/index.d.ts +0 -50
  114. package/dist/src/paramTag/index.js +0 -78
  115. package/dist/src/paramTag/inputbox.d.ts +0 -7
  116. package/dist/src/paramTag/inputbox.js +0 -21
  117. package/dist/src/parameter.d.ts +0 -95
  118. package/dist/src/parameter.js +0 -204
  119. package/dist/src/pre.d.ts +0 -27
  120. package/dist/src/pre.js +0 -44
  121. package/dist/src/syntax.d.ts +0 -22
  122. package/dist/src/syntax.js +0 -67
  123. package/dist/src/table/base.d.ts +0 -60
  124. package/dist/src/table/base.js +0 -80
  125. package/dist/src/table/index.d.ts +0 -247
  126. package/dist/src/table/index.js +0 -783
  127. package/dist/src/table/td.d.ts +0 -119
  128. package/dist/src/table/td.js +0 -268
  129. package/dist/src/table/tr.d.ts +0 -31
  130. package/dist/src/table/tr.js +0 -50
  131. package/dist/src/table/trBase.d.ts +0 -62
  132. package/dist/src/table/trBase.js +0 -157
  133. package/dist/src/tagPair/ext.d.ts +0 -54
  134. package/dist/src/tagPair/ext.js +0 -150
  135. package/dist/src/tagPair/include.d.ts +0 -43
  136. package/dist/src/tagPair/include.js +0 -43
  137. package/dist/src/tagPair/index.d.ts +0 -57
  138. package/dist/src/tagPair/index.js +0 -113
  139. package/dist/src/transclude.d.ts +0 -200
  140. package/dist/src/transclude.js +0 -732
  141. package/dist/util/debug.js +0 -42
  142. package/dist/util/diff.js +0 -71
  143. package/dist/util/lint.js +0 -38
  144. package/dist/util/string.js +0 -74
  145. package/errors/README +0 -1
  146. package/printed/README +0 -1
@@ -1,113 +0,0 @@
1
- import { Token } from '.';
2
- import type { LintError } from '../index';
3
- import type { AttributesToken } from '../internal';
4
- declare const HtmlToken_base: (abstract new (...args: any[]) => {
5
- /**
6
- * HTML标签
7
- * @classdesc `{childNodes: [AttributesToken]}`
8
- */
9
- childNodes: import("../index").AstNodes[];
10
- readonly "__#4@#attributesChild": AttributesToken;
11
- readonly attributes: Record<string, string | true>;
12
- className: string;
13
- readonly classList: Set<string>;
14
- id: string;
15
- hasAttr(key: string): boolean;
16
- getAttr(key: string): string | true | undefined;
17
- getAttrNames(): Set<string>;
18
- hasAttrs(): boolean;
19
- getAttrs(): Record<string, string | true>;
20
- setAttr(key: string, value: string | boolean): void;
21
- removeAttr(key: string): void;
22
- toggleAttr(key: string, force?: boolean | undefined): void;
23
- length: number;
24
- toString(selector?: string | undefined, separator?: string | undefined): string;
25
- text(separator?: string | undefined): string;
26
- insertAt(token: unknown, i?: number | undefined): unknown;
27
- }) & ((abstract new (...args: any[]) => {
28
- removeAt(): never;
29
- insertAt(token: string, i?: number | undefined): import("../index").AstText;
30
- insertAt<T extends import("../index").AstNodes>(token: T, i?: number | undefined): T;
31
- length: number;
32
- toString(selector?: string | undefined, separator?: string | undefined): string;
33
- text(separator?: string | undefined): string;
34
- }) & {
35
- readonly fixed: true;
36
- }) & typeof Token;
37
- /**
38
- * HTML标签
39
- * @classdesc `{childNodes: [AttributesToken]}`
40
- */
41
- export declare abstract class HtmlToken extends HtmlToken_base {
42
- #private;
43
- /** @browser */
44
- readonly type = "html";
45
- name: string;
46
- childNodes: [AttributesToken];
47
- abstract get children(): [AttributesToken];
48
- abstract get firstChild(): AttributesToken;
49
- abstract get firstElementChild(): AttributesToken;
50
- abstract get lastChild(): AttributesToken;
51
- abstract get lastElementChild(): AttributesToken;
52
- /**
53
- * 是否是闭合标签
54
- * @browser
55
- */
56
- get closing(): boolean;
57
- /** @throws `Error` 自封闭标签或空标签 */
58
- set closing(value: boolean);
59
- /** 是否自封闭 */
60
- get selfClosing(): boolean;
61
- /** @throws `Error` 闭合标签或无效自封闭标签 */
62
- set selfClosing(value: boolean);
63
- /**
64
- * @browser
65
- * @param name 标签名
66
- * @param attr 标签属性
67
- * @param closing 是否闭合
68
- * @param selfClosing 是否自封闭
69
- */
70
- constructor(name: string, attr: AttributesToken, closing: boolean, selfClosing: boolean, config?: import("../index").Config, accum?: Token[]);
71
- /**
72
- * @override
73
- * @browser
74
- */
75
- toString(selector?: string): string;
76
- /**
77
- * @override
78
- * @browser
79
- */
80
- text(): string;
81
- /**
82
- * @override
83
- * @browser
84
- */
85
- print(): string;
86
- /**
87
- * @override
88
- * @browser
89
- */
90
- lint(start?: number): LintError[];
91
- /**
92
- * 搜索匹配的标签
93
- * @browser
94
- * @throws `SyntaxError` 同时闭合和自封闭的标签
95
- * @throws `SyntaxError` 无效自封闭标签
96
- * @throws `SyntaxError` 未闭合的标签
97
- */
98
- findMatchingTag(): this | undefined;
99
- /** @override */
100
- cloneNode(): this;
101
- /**
102
- * 更换标签名
103
- * @param tag 标签名
104
- * @throws `RangeError` 非法的HTML标签
105
- */
106
- replaceTag(tag: string): void;
107
- /**
108
- * 修复无效自封闭标签
109
- * @throws `Error` 无法修复无效自封闭标签
110
- */
111
- fix(): void;
112
- }
113
- export {};
package/dist/src/html.js DELETED
@@ -1,245 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.HtmlToken = void 0;
4
- const lint_1 = require("../util/lint");
5
- const string_1 = require("../util/string");
6
- const fixed_1 = require("../mixin/fixed");
7
- const attributesParent_1 = require("../mixin/attributesParent");
8
- const index_1 = require("../index");
9
- const _1 = require(".");
10
- const magicWords = new Set(['if', 'ifeq', 'ifexpr', 'ifexist', 'iferror', 'switch']);
11
- /**
12
- * HTML标签
13
- * @classdesc `{childNodes: [AttributesToken]}`
14
- */
15
- class HtmlToken extends (0, attributesParent_1.attributesParent)((0, fixed_1.fixed)(_1.Token)) {
16
- /** @browser */
17
- type = 'html';
18
- /** @browser */
19
- #closing;
20
- /** @browser */
21
- #selfClosing;
22
- /** @browser */
23
- #tag;
24
- /**
25
- * 是否是闭合标签
26
- * @browser
27
- */
28
- get closing() {
29
- return this.#closing;
30
- }
31
- /** @throws `Error` 自封闭标签或空标签 */
32
- set closing(value) {
33
- if (!value) {
34
- this.#closing = false;
35
- return;
36
- }
37
- else if (this.#selfClosing) {
38
- throw new Error('这是一个自封闭标签!');
39
- }
40
- const { html: [, , tags] } = this.getAttribute('config');
41
- if (tags.includes(this.name)) {
42
- throw new Error('这是一个空标签!');
43
- }
44
- this.#closing = true;
45
- }
46
- /** 是否自封闭 */
47
- get selfClosing() {
48
- return this.#selfClosing;
49
- }
50
- /** @throws `Error` 闭合标签或无效自封闭标签 */
51
- set selfClosing(value) {
52
- if (!value) {
53
- this.#selfClosing = false;
54
- return;
55
- }
56
- else if (this.#closing) {
57
- throw new Error('这是一个闭合标签!');
58
- }
59
- const { html: [tags] } = this.getAttribute('config');
60
- if (tags.includes(this.name)) {
61
- throw new Error(`<${this.name}>标签自封闭无效!`);
62
- }
63
- this.#selfClosing = true;
64
- }
65
- /**
66
- * @browser
67
- * @param name 标签名
68
- * @param attr 标签属性
69
- * @param closing 是否闭合
70
- * @param selfClosing 是否自封闭
71
- */
72
- constructor(name, attr, closing, selfClosing, config = index_1.default.getConfig(), accum = []) {
73
- super(undefined, config, true, accum);
74
- this.insertAt(attr);
75
- this.setAttribute('name', name.toLowerCase());
76
- this.#closing = closing;
77
- this.#selfClosing = selfClosing;
78
- this.#tag = name;
79
- }
80
- /**
81
- * @override
82
- * @browser
83
- */
84
- toString(selector) {
85
- return selector && this.matches(selector)
86
- ? ''
87
- : `<${this.#closing ? '/' : ''}${this.#tag}${super.toString(selector)}${this.#selfClosing ? '/' : ''}>`;
88
- }
89
- /**
90
- * @override
91
- * @browser
92
- */
93
- text() {
94
- return `<${this.#closing ? '/' : ''}${this.#tag}${this.#closing ? '' : super.text()}${this.#selfClosing ? '/' : ''}>`;
95
- }
96
- /** @private */
97
- getPadding() {
98
- return this.#tag.length + (this.#closing ? 2 : 1);
99
- }
100
- /**
101
- * @override
102
- * @browser
103
- */
104
- print() {
105
- return super.print({
106
- pre: `&lt;${this.#closing ? '/' : ''}${this.#tag}`,
107
- post: `${this.#selfClosing ? '/' : ''}&gt;`,
108
- });
109
- }
110
- /**
111
- * @override
112
- * @browser
113
- */
114
- lint(start = this.getAbsoluteIndex()) {
115
- const errors = super.lint(start);
116
- let wikitext, refError;
117
- if (this.name === 'h1' && !this.#closing) {
118
- wikitext = String(this.getRootNode());
119
- refError = (0, lint_1.generateForSelf)(this, { start }, '<h1>');
120
- errors.push({ ...refError, excerpt: wikitext.slice(start, start + 50) });
121
- }
122
- if (this.closest('table-attrs')) {
123
- wikitext ??= String(this.getRootNode());
124
- refError ??= (0, lint_1.generateForSelf)(this, { start }, '');
125
- const excerpt = wikitext.slice(Math.max(0, start - 25), start + 25);
126
- errors.push({ ...refError, message: index_1.default.msg('HTML tag in table attributes'), excerpt });
127
- }
128
- try {
129
- this.findMatchingTag();
130
- }
131
- catch (e) {
132
- if (e instanceof SyntaxError) {
133
- const { message: errorMsg } = e;
134
- wikitext ??= String(this.getRootNode());
135
- refError ??= (0, lint_1.generateForSelf)(this, { start }, '');
136
- const [msg] = errorMsg.split(':'), error = { ...refError, message: index_1.default.msg(msg) };
137
- if (msg === 'unclosed tag') {
138
- error.severity = 'warning';
139
- error.excerpt = wikitext.slice(start, start + 50);
140
- }
141
- else if (msg === 'unmatched closing tag') {
142
- const end = start + String(this).length, ancestor = this.closest('magic-word');
143
- error.excerpt = wikitext.slice(Math.max(0, end - 50), end);
144
- if (ancestor && magicWords.has(ancestor.name)) {
145
- error.severity = 'warning';
146
- }
147
- }
148
- errors.push(error);
149
- }
150
- }
151
- return errors;
152
- }
153
- /**
154
- * 搜索匹配的标签
155
- * @browser
156
- * @throws `SyntaxError` 同时闭合和自封闭的标签
157
- * @throws `SyntaxError` 无效自封闭标签
158
- * @throws `SyntaxError` 未闭合的标签
159
- */
160
- findMatchingTag() {
161
- const { html } = this.getAttribute('config'), { name: tagName, parentNode } = this, string = (0, string_1.noWrap)(String(this));
162
- if (this.#closing && (this.#selfClosing || html[2].includes(tagName))) {
163
- throw new SyntaxError(`tag that is both closing and self-closing: ${string}`);
164
- }
165
- else if (html[2].includes(tagName) || this.#selfClosing && html[1].includes(tagName)) { // 自封闭标签
166
- return this;
167
- }
168
- else if (this.#selfClosing && html[0].includes(tagName)) {
169
- throw new SyntaxError(`invalid self-closing tag: ${string}`);
170
- }
171
- else if (!parentNode) {
172
- return undefined;
173
- }
174
- const { childNodes } = parentNode, i = childNodes.indexOf(this), siblings = this.#closing
175
- ? childNodes.slice(0, i).reverse().filter(({ type, name }) => type === 'html' && name === tagName)
176
- : childNodes.slice(i + 1).filter(({ type, name }) => type === 'html' && name === tagName);
177
- let imbalance = this.#closing ? -1 : 1;
178
- for (const token of siblings) {
179
- if (token.closing) {
180
- imbalance--;
181
- }
182
- else {
183
- imbalance++;
184
- }
185
- if (imbalance === 0) {
186
- return token;
187
- }
188
- }
189
- throw new SyntaxError(`${this.#closing ? 'unmatched closing' : 'unclosed'} tag: ${string}`);
190
- }
191
- /** @override */
192
- cloneNode() {
193
- const [attr] = this.cloneChildNodes(), config = this.getAttribute('config');
194
- // @ts-expect-error abstract class
195
- return index_1.default.run(() => new HtmlToken(this.#tag, attr, this.#closing, this.#selfClosing, config));
196
- }
197
- /** @private */
198
- getAttribute(key) {
199
- return key === 'tag' ? this.#tag : super.getAttribute(key);
200
- }
201
- /**
202
- * 更换标签名
203
- * @param tag 标签名
204
- * @throws `RangeError` 非法的HTML标签
205
- */
206
- replaceTag(tag) {
207
- const name = tag.toLowerCase();
208
- if (!this.getAttribute('config').html.flat().includes(name)) {
209
- throw new RangeError(`非法的HTML标签:${tag}`);
210
- }
211
- this.setAttribute('name', name).#tag = tag;
212
- }
213
- /** 局部闭合 */
214
- #localMatch() {
215
- this.#selfClosing = false;
216
- const root = index_1.default.parse(`</${this.name}>`, false, 3, this.getAttribute('config'));
217
- this.after(root.firstChild);
218
- }
219
- /**
220
- * 修复无效自封闭标签
221
- * @throws `Error` 无法修复无效自封闭标签
222
- */
223
- fix() {
224
- const config = this.getAttribute('config'), { parentNode, name: tagName, firstChild } = this;
225
- if (!parentNode || !this.#selfClosing || !config.html[0].includes(tagName)) {
226
- return;
227
- }
228
- else if (firstChild.text().trim()) {
229
- this.#localMatch();
230
- return;
231
- }
232
- const { childNodes } = parentNode, i = childNodes.indexOf(this), prevSiblings = childNodes.slice(0, i)
233
- .filter(({ type, name }) => type === 'html' && name === tagName), imbalance = prevSiblings.reduce((acc, { closing }) => acc + (closing ? 1 : -1), 0);
234
- if (imbalance < 0) {
235
- this.#selfClosing = false;
236
- this.#closing = true;
237
- }
238
- else {
239
- index_1.default.warn('无法修复无效自封闭标签', (0, string_1.noWrap)(String(this)));
240
- throw new Error(`无法修复无效自封闭标签:前文共有 ${imbalance} 个未匹配的闭合标签`);
241
- }
242
- }
243
- }
244
- exports.HtmlToken = HtmlToken;
245
- index_1.default.classes['HtmlToken'] = __filename;
@@ -1,82 +0,0 @@
1
- import { Token } from '.';
2
- import type { LintError, Config } from '../index';
3
- import type { Title } from '../lib/title';
4
- import type { AstNodes, AstText, AtomToken, FileToken } from '../internal';
5
- /** 图片参数 */
6
- export declare abstract class ImageParameterToken extends Token {
7
- #private;
8
- /** @browser */
9
- readonly type = "image-parameter";
10
- name: string;
11
- abstract get parentNode(): FileToken;
12
- abstract get parentElement(): FileToken;
13
- abstract get nextSibling(): this | undefined;
14
- abstract get nextElementSibling(): this | undefined;
15
- abstract get previousSibling(): AtomToken | this;
16
- abstract get previousElementSibling(): AtomToken | this;
17
- /**
18
- * 图片链接
19
- * @browser
20
- */
21
- get link(): string | Title | undefined;
22
- set link(value: string | Title | undefined);
23
- /** getValue()的getter */
24
- get value(): string | true;
25
- set value(value: string | true);
26
- /** 图片大小 */
27
- get size(): {
28
- width: string;
29
- height: string;
30
- } | undefined;
31
- /** 图片宽度 */
32
- get width(): string | undefined;
33
- set width(width: string | undefined);
34
- /** 图片高度 */
35
- get height(): string | undefined;
36
- set height(height: string | undefined);
37
- /**
38
- * @browser
39
- * @param str 图片参数
40
- */
41
- constructor(str: string, config?: Config, accum?: Token[]);
42
- /**
43
- * @override
44
- * @browser
45
- */
46
- toString(selector?: string): string;
47
- /**
48
- * @override
49
- * @browser
50
- */
51
- text(): string;
52
- /**
53
- * @override
54
- * @browser
55
- */
56
- lint(start?: number): LintError[];
57
- /**
58
- * @override
59
- * @browser
60
- */
61
- print(): string;
62
- /** @override */
63
- cloneNode(): this;
64
- /**
65
- * @override
66
- * @param token 待插入的子节点
67
- * @param i 插入位置
68
- * @throws `Error` 不接受自定义输入的图片参数
69
- */
70
- insertAt(token: string, i?: number): AstText;
71
- /** @ignore */
72
- insertAt<T extends AstNodes>(token: T, i?: number): T;
73
- /** 获取参数值 */
74
- getValue(): string | true;
75
- /**
76
- * 设置参数值
77
- * @param value 参数值
78
- * @throws `Error` 无效参数
79
- * @throws SyntaxError` 非法的参数值
80
- */
81
- setValue(value: string | boolean): void;
82
- }
@@ -1,256 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ImageParameterToken = void 0;
4
- const string_1 = require("../util/string");
5
- const lint_1 = require("../util/lint");
6
- const index_1 = require("../index");
7
- const _1 = require(".");
8
- const params = new Set(['alt', 'link', 'lang', 'page', 'caption']);
9
- /** @ignore */
10
- function validate(key, val, config = index_1.default.getConfig(), halfParsed = false) {
11
- const trimmedVal = val.trim();
12
- let value = trimmedVal.replace(/\0\d+t\x7F/gu, '').trim();
13
- switch (key) {
14
- case 'width':
15
- return /^(?:\d+x?|\d*x\d+)$/u.test(value);
16
- case 'link': {
17
- if (!value) {
18
- return trimmedVal;
19
- }
20
- const regex = new RegExp(`^(?:(?:${config.protocol}|//)${string_1.extUrlCharFirst}|\0\\d+m\x7F)${string_1.extUrlChar}$`, 'iu');
21
- if (regex.test(value)) {
22
- return trimmedVal;
23
- }
24
- else if (value.startsWith('[[') && value.endsWith(']]')) {
25
- value = value.slice(2, -2);
26
- }
27
- const title = index_1.default.normalizeTitle(value, 0, false, config, halfParsed, true, true);
28
- return title.valid && title;
29
- }
30
- case 'lang':
31
- return config.variants.includes(value);
32
- case 'alt':
33
- case 'class':
34
- case 'manualthumb':
35
- return true;
36
- default:
37
- // @ts-expect-error isNaN
38
- return !isNaN(value);
39
- }
40
- }
41
- /** 图片参数 */
42
- class ImageParameterToken extends _1.Token {
43
- /** @browser */
44
- type = 'image-parameter';
45
- /** @browser */
46
- #syntax = '';
47
- /**
48
- * 图片链接
49
- * @browser
50
- */
51
- get link() {
52
- return this.name === 'link' ? validate('link', super.text(), this.getAttribute('config')) : undefined;
53
- }
54
- set link(value) {
55
- if (this.name === 'link') {
56
- this.setValue(String(value));
57
- }
58
- }
59
- /** getValue()的getter */
60
- get value() {
61
- return this.getValue();
62
- }
63
- set value(value) {
64
- this.setValue(value);
65
- }
66
- /** 图片大小 */
67
- get size() {
68
- if (this.name === 'width') {
69
- const size = this.getValue().trim();
70
- if (!size.includes('{{')) {
71
- const [width, height = ''] = size.split('x');
72
- return { width, height };
73
- }
74
- const token = index_1.default.parse(size, false, 2, this.getAttribute('config')), i = token.childNodes.findIndex(child => child.type === 'text' && child.data.includes('x')), str = token.childNodes[i];
75
- if (i === -1) {
76
- return { width: size, height: '' };
77
- }
78
- str.splitText(str.data.indexOf('x'));
79
- str.nextSibling.splitText(1);
80
- return { width: (0, string_1.text)(token.childNodes.slice(0, i + 1)), height: (0, string_1.text)(token.childNodes.slice(i + 2)) };
81
- }
82
- return undefined;
83
- }
84
- /** 图片宽度 */
85
- get width() {
86
- return this.size?.width;
87
- }
88
- set width(width) {
89
- if (this.name === 'width') {
90
- const { height } = this;
91
- this.setValue(`${width || ''}${height && 'x'}${height}`);
92
- }
93
- }
94
- /** 图片高度 */
95
- get height() {
96
- return this.size?.height;
97
- }
98
- set height(height) {
99
- if (this.name === 'width') {
100
- this.setValue(`${this.width}${height ? `x${height}` : ''}`);
101
- }
102
- }
103
- /**
104
- * @browser
105
- * @param str 图片参数
106
- */
107
- constructor(str, config = index_1.default.getConfig(), accum = []) {
108
- let mt;
109
- const regexes = Object.entries(config.img).map(([syntax, param]) => [
110
- syntax,
111
- param,
112
- new RegExp(`^(\\s*)${syntax.replace('$1', '(.*)')}(\\s*)$`, 'u'),
113
- ]), param = regexes.find(([, key, regex]) => {
114
- mt = regex.exec(str);
115
- return mt
116
- && (mt.length !== 4 || validate(key, mt[2], config, true) !== false);
117
- });
118
- // @ts-expect-error mt already assigned
119
- if (param && mt) {
120
- if (mt.length === 3) {
121
- super(undefined, config, true, accum);
122
- this.#syntax = str;
123
- }
124
- else {
125
- super(mt[2], config, true, accum, {
126
- 'Stage-2': ':', '!HeadingToken': ':',
127
- });
128
- this.#syntax = `${mt[1]}${param[0]}${mt[3]}`;
129
- }
130
- this.setAttribute('name', param[1]);
131
- return;
132
- }
133
- super(str, { ...config, excludes: [...config.excludes ?? [], 'list'] }, true, accum);
134
- this.setAttribute('name', 'caption').setAttribute('stage', 7);
135
- }
136
- /** @private */
137
- afterBuild() {
138
- if (this.parentNode.type === 'gallery-image' && !params.has(this.name)) {
139
- this.setAttribute('name', 'invalid');
140
- }
141
- }
142
- /** @private */
143
- isPlain() {
144
- return this.name === 'caption';
145
- }
146
- /**
147
- * @override
148
- * @browser
149
- */
150
- toString(selector) {
151
- return this.#syntax && !(selector && this.matches(selector))
152
- ? this.#syntax.replace('$1', super.toString(selector))
153
- : super.toString(selector);
154
- }
155
- /**
156
- * @override
157
- * @browser
158
- */
159
- text() {
160
- return this.#syntax ? this.#syntax.replace('$1', super.text()).trim() : super.text().trim();
161
- }
162
- /** @private */
163
- getPadding() {
164
- return Math.max(0, this.#syntax.indexOf('$1'));
165
- }
166
- /**
167
- * @override
168
- * @browser
169
- */
170
- lint(start = this.getAbsoluteIndex()) {
171
- const errors = super.lint(start), { link } = this;
172
- if (this.name === 'invalid') {
173
- errors.push((0, lint_1.generateForSelf)(this, { start }, 'invalid gallery image parameter'));
174
- }
175
- else if (typeof link === 'object' && link.encoded) {
176
- errors.push((0, lint_1.generateForSelf)(this, { start }, 'unnecessary URL encoding in an internal link'));
177
- }
178
- return errors;
179
- }
180
- /**
181
- * @override
182
- * @browser
183
- */
184
- print() {
185
- return this.#syntax
186
- ? `<span class="wpb-image-parameter">${this.#syntax.replace('$1', `<span class="wpb-image-caption">${(0, string_1.print)(this.childNodes)}</span>`)}</span>`
187
- : super.print({ class: 'image-caption' });
188
- }
189
- /** @override */
190
- cloneNode() {
191
- const cloned = this.cloneChildNodes(), config = this.getAttribute('config');
192
- return index_1.default.run(() => {
193
- // @ts-expect-error abstract class
194
- const token = new ImageParameterToken(this.#syntax.replace('$1', ''), config);
195
- token.replaceChildren(...cloned);
196
- return token;
197
- });
198
- }
199
- /** @private */
200
- getAttribute(key) {
201
- return key === 'syntax' ? this.#syntax : super.getAttribute(key);
202
- }
203
- /** @private */
204
- hasAttribute(key) {
205
- return key === 'syntax' || super.hasAttribute(key);
206
- }
207
- /** 是否是不可变参数 */
208
- #isVoid() {
209
- return this.#syntax && !this.#syntax.includes('$1');
210
- }
211
- /** @ignore */
212
- insertAt(token, i = this.length) {
213
- if (!index_1.default.running && this.#isVoid()) {
214
- throw new Error(`图片参数 ${this.name} 不接受自定义输入!`);
215
- }
216
- return super.insertAt(token, i);
217
- }
218
- /** 获取参数值 */
219
- getValue() {
220
- return this.name === 'invalid' ? this.text() : this.#isVoid() || super.text();
221
- }
222
- /**
223
- * 设置参数值
224
- * @param value 参数值
225
- * @throws `Error` 无效参数
226
- * @throws SyntaxError` 非法的参数值
227
- */
228
- setValue(value) {
229
- if (this.name === 'invalid') {
230
- throw new Error('无效的图片参数!');
231
- }
232
- else if (this.#isVoid()) {
233
- if (typeof value !== 'boolean') {
234
- this.typeError('setValue', 'Boolean');
235
- }
236
- else if (!value) {
237
- this.remove();
238
- }
239
- return;
240
- }
241
- else if (typeof value !== 'string') {
242
- this.typeError('setValue', 'String');
243
- }
244
- const root = index_1.default.parse(`[[File:F|${this.#syntax ? this.#syntax.replace('$1', value) : value}]]`, this.getAttribute('include'), 6, this.getAttribute('config')), { length, firstChild: file } = root;
245
- if (length !== 1 || file.type !== 'file' || file.length !== 2) {
246
- throw new SyntaxError(`非法的 ${this.name} 参数:${(0, string_1.noWrap)(value)}`);
247
- }
248
- const { lastChild: imageParameter, name } = file;
249
- if (name !== 'File:F' || imageParameter.name !== this.name) {
250
- throw new SyntaxError(`非法的 ${this.name} 参数:${(0, string_1.noWrap)(value)}`);
251
- }
252
- this.replaceChildren(...imageParameter.childNodes);
253
- }
254
- }
255
- exports.ImageParameterToken = ImageParameterToken;
256
- index_1.default.classes['ImageParameterToken'] = __filename;