wikiparser-node 1.9.3 → 1.10.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.
- package/config/.schema.json +5 -0
- package/config/enwiki.json +2 -1
- package/config/llwiki.json +2 -1
- package/config/moegirl.json +2 -1
- package/config/zhwiki.json +2 -1
- package/dist/addon/token.js +282 -198
- package/dist/addon/transclude.js +7 -7
- package/dist/base.d.ts +3 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +4 -4
- package/dist/lib/element.js +2 -2
- package/dist/lib/node.d.ts +6 -1
- package/dist/lib/node.js +10 -4
- package/dist/lib/text.d.ts +5 -2
- package/dist/lib/text.js +15 -5
- package/dist/lib/title.d.ts +2 -0
- package/dist/lib/title.js +8 -0
- package/dist/mixin/attributesParent.js +0 -3
- package/dist/mixin/hidden.d.ts +1 -0
- package/dist/mixin/hidden.js +5 -2
- package/dist/mixin/singleLine.js +2 -4
- package/dist/mixin/sol.d.ts +1 -0
- package/dist/mixin/sol.js +7 -7
- package/dist/mixin/syntax.js +0 -2
- package/dist/parser/list.js +8 -6
- package/dist/parser/selector.js +2 -1
- package/dist/parser/table.js +2 -2
- package/dist/src/arg.js +3 -3
- package/dist/src/attribute.js +25 -28
- package/dist/src/attributes.d.ts +0 -1
- package/dist/src/attributes.js +34 -7
- package/dist/src/converter.d.ts +2 -2
- package/dist/src/converter.js +13 -3
- package/dist/src/converterFlags.js +2 -2
- package/dist/src/converterRule.js +17 -13
- package/dist/src/extLink.js +7 -3
- package/dist/src/gallery.js +2 -2
- package/dist/src/heading.js +9 -4
- package/dist/src/hidden.js +1 -1
- package/dist/src/html.js +10 -2
- package/dist/src/imageParameter.js +2 -2
- package/dist/src/imagemap.js +2 -2
- package/dist/src/index.d.ts +11 -1
- package/dist/src/index.js +61 -12
- package/dist/src/link/base.d.ts +9 -0
- package/dist/src/link/base.js +48 -11
- package/dist/src/link/file.js +1 -1
- package/dist/src/link/index.d.ts +0 -12
- package/dist/src/link/index.js +8 -45
- package/dist/src/link/redirectTarget.d.ts +3 -12
- package/dist/src/link/redirectTarget.js +5 -31
- package/dist/src/magicLink.d.ts +3 -2
- package/dist/src/magicLink.js +45 -57
- package/dist/src/nowiki/base.js +1 -1
- package/dist/src/nowiki/comment.js +3 -3
- package/dist/src/nowiki/dd.js +64 -18
- package/dist/src/nowiki/doubleUnderscore.js +1 -1
- package/dist/src/nowiki/hr.js +6 -1
- package/dist/src/nowiki/list.d.ts +0 -11
- package/dist/src/nowiki/list.js +2 -48
- package/dist/src/nowiki/listBase.d.ts +12 -0
- package/dist/src/nowiki/listBase.js +67 -53
- package/dist/src/nowiki/noinclude.js +5 -1
- package/dist/src/nowiki/quote.js +5 -0
- package/dist/src/onlyinclude.js +2 -2
- package/dist/src/paramTag/index.js +2 -2
- package/dist/src/parameter.js +20 -13
- package/dist/src/redirect.js +7 -3
- package/dist/src/syntax.d.ts +1 -1
- package/dist/src/syntax.js +2 -2
- package/dist/src/table/index.js +11 -1
- package/dist/src/table/td.js +8 -2
- package/dist/src/table/trBase.js +15 -7
- package/dist/src/tagPair/ext.js +16 -0
- package/dist/src/tagPair/include.js +5 -1
- package/dist/src/tagPair/index.js +3 -3
- package/dist/src/transclude.js +20 -15
- package/dist/util/lint.js +1 -1
- package/dist/util/string.js +25 -1
- package/errors/README +2 -0
- package/package.json +1 -1
- package/printed/README +2 -0
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -13,12 +13,11 @@ const diff_1 = require("./util/diff");
|
|
|
13
13
|
* @param file 文件名
|
|
14
14
|
* @param dir 子路径
|
|
15
15
|
*/
|
|
16
|
-
const rootRequire = (file, dir) => require(
|
|
16
|
+
const rootRequire = (file, dir) => require(path.isAbsolute(file) ? file : path.join('..', file.includes('/') ? '' : dir, file));
|
|
17
17
|
/* NOT FOR BROWSER */
|
|
18
18
|
const promises = [Promise.resolve()];
|
|
19
19
|
let viewOnly = false;
|
|
20
20
|
/* NOT FOR BROWSER END */
|
|
21
|
-
// eslint-disable-next-line @typescript-eslint/no-redeclare
|
|
22
21
|
const Parser = {
|
|
23
22
|
config: 'default',
|
|
24
23
|
i18n: undefined,
|
|
@@ -36,13 +35,14 @@ const Parser = {
|
|
|
36
35
|
},
|
|
37
36
|
conversionTable: new Map(),
|
|
38
37
|
redirects: new Map(),
|
|
38
|
+
templates: new Map(),
|
|
39
39
|
warning: true,
|
|
40
40
|
debugging: false,
|
|
41
41
|
/* NOT FOR BROWSER END */
|
|
42
42
|
/** @implements */
|
|
43
43
|
getConfig() {
|
|
44
44
|
if (typeof this.config === 'string') {
|
|
45
|
-
this.config = rootRequire(this.config, 'config
|
|
45
|
+
this.config = rootRequire(this.config, 'config');
|
|
46
46
|
/* NOT FOR BROWSER */
|
|
47
47
|
const { config: { conversionTable, redirects } } = this;
|
|
48
48
|
if (conversionTable) {
|
|
@@ -62,7 +62,7 @@ const Parser = {
|
|
|
62
62
|
/** @implements */
|
|
63
63
|
msg(msg, arg = '') {
|
|
64
64
|
if (typeof this.i18n === 'string') {
|
|
65
|
-
this.i18n = rootRequire(this.i18n, 'i18n
|
|
65
|
+
this.i18n = rootRequire(this.i18n, 'i18n');
|
|
66
66
|
return this.msg(msg, arg);
|
|
67
67
|
}
|
|
68
68
|
return msg && (this.i18n?.[msg] ?? msg).replace('$1', this.msg(arg));
|
package/dist/lib/element.js
CHANGED
|
@@ -254,8 +254,8 @@ class AstElement extends node_1.AstNode {
|
|
|
254
254
|
throw new RangeError(`The child node at position ${i} is ${oldText.constructor.name}!`);
|
|
255
255
|
}
|
|
256
256
|
/** @private */
|
|
257
|
-
toString(separator = '') {
|
|
258
|
-
return this.childNodes.map(
|
|
257
|
+
toString(skip, separator = '') {
|
|
258
|
+
return this.childNodes.map(child => child.toString(skip)).join(separator);
|
|
259
259
|
}
|
|
260
260
|
/** @private */
|
|
261
261
|
lint(start = this.getAbsoluteIndex(), re) {
|
package/dist/lib/node.d.ts
CHANGED
|
@@ -18,9 +18,9 @@ export declare abstract class AstNode implements AstNodeBase {
|
|
|
18
18
|
#private;
|
|
19
19
|
data?: string | undefined;
|
|
20
20
|
readonly childNodes: readonly AstNodes[];
|
|
21
|
-
/** 节点类型 */
|
|
22
21
|
abstract get type(): TokenTypes | 'text';
|
|
23
22
|
abstract set type(value: TokenTypes | 'text');
|
|
23
|
+
/** 可见部分 */
|
|
24
24
|
text(): string;
|
|
25
25
|
lint(): LintError[];
|
|
26
26
|
print(): string;
|
|
@@ -82,6 +82,11 @@ export declare abstract class AstNode implements AstNodeBase {
|
|
|
82
82
|
getRelativeIndex(j?: number): number;
|
|
83
83
|
/** 获取当前节点的绝对位置 */
|
|
84
84
|
getAbsoluteIndex(): number;
|
|
85
|
+
/**
|
|
86
|
+
* 是否是某种类型的节点
|
|
87
|
+
* @param type 节点类型
|
|
88
|
+
*/
|
|
89
|
+
is<T extends Token>(type: string): this is T;
|
|
85
90
|
/**
|
|
86
91
|
* 是否是全同节点
|
|
87
92
|
* @param node 待比较的节点
|
package/dist/lib/node.js
CHANGED
|
@@ -4,7 +4,6 @@ exports.AstNode = void 0;
|
|
|
4
4
|
const assert = require("assert/strict");
|
|
5
5
|
const EventEmitter = require("events");
|
|
6
6
|
const constants_1 = require("../util/constants");
|
|
7
|
-
const debug_1 = require("../util/debug");
|
|
8
7
|
/**
|
|
9
8
|
* 计算字符串的行列数
|
|
10
9
|
* @param str 字符串
|
|
@@ -134,11 +133,11 @@ class AstNode {
|
|
|
134
133
|
if (!parentNode || acceptable && !('QuoteToken' in acceptable)) {
|
|
135
134
|
return { bold: false, italic: false };
|
|
136
135
|
}
|
|
137
|
-
const { childNodes, type } = parentNode
|
|
136
|
+
const { childNodes, type } = parentNode;
|
|
138
137
|
let { bold = false, italic = false } = type === 'ext-link-text' && parentNode.parentNode || {};
|
|
139
138
|
for (let i = childNodes.indexOf(this) - 1; i >= 0; i--) {
|
|
140
139
|
const child = childNodes[i];
|
|
141
|
-
if (
|
|
140
|
+
if (child.is('quote')) {
|
|
142
141
|
bold = child.bold !== bold;
|
|
143
142
|
italic = child.italic !== italic;
|
|
144
143
|
}
|
|
@@ -171,7 +170,7 @@ class AstNode {
|
|
|
171
170
|
this.#parentNode = value;
|
|
172
171
|
/* NOT FOR BROWSER */
|
|
173
172
|
}
|
|
174
|
-
else if (Object.
|
|
173
|
+
else if (Object.hasOwn(this, key)) {
|
|
175
174
|
const descriptor = Object.getOwnPropertyDescriptor(this, key);
|
|
176
175
|
if (this.#optional.has(key)) {
|
|
177
176
|
descriptor.enumerable = Boolean(value);
|
|
@@ -249,6 +248,13 @@ class AstNode {
|
|
|
249
248
|
writable: false,
|
|
250
249
|
});
|
|
251
250
|
}
|
|
251
|
+
/**
|
|
252
|
+
* 是否是某种类型的节点
|
|
253
|
+
* @param type 节点类型
|
|
254
|
+
*/
|
|
255
|
+
is(type) {
|
|
256
|
+
return this.type === type;
|
|
257
|
+
}
|
|
252
258
|
/* NOT FOR BROWSER */
|
|
253
259
|
/** @private */
|
|
254
260
|
typeError(method, ...types) {
|
package/dist/lib/text.d.ts
CHANGED
|
@@ -11,8 +11,6 @@ export declare class AstText extends AstNode {
|
|
|
11
11
|
set length(n: number);
|
|
12
12
|
/** @param text 包含文本 */
|
|
13
13
|
constructor(text: string);
|
|
14
|
-
/** 可见部分 */
|
|
15
|
-
text(): string;
|
|
16
14
|
/**
|
|
17
15
|
* 替换字符串
|
|
18
16
|
* @param text 替换的字符串
|
|
@@ -52,4 +50,9 @@ export declare class AstText extends AstNode {
|
|
|
52
50
|
splitText(offset: number): AstText;
|
|
53
51
|
/** 转义 `=` */
|
|
54
52
|
escape(): void;
|
|
53
|
+
/**
|
|
54
|
+
* 生成HTML
|
|
55
|
+
* @param nowrap 是否不换行
|
|
56
|
+
*/
|
|
57
|
+
toHtml(nowrap?: boolean): string;
|
|
55
58
|
}
|
package/dist/lib/text.js
CHANGED
|
@@ -107,12 +107,15 @@ class AstText extends node_1.AstNode {
|
|
|
107
107
|
toString() {
|
|
108
108
|
return this.data;
|
|
109
109
|
}
|
|
110
|
-
/**
|
|
110
|
+
/** @private */
|
|
111
111
|
text() {
|
|
112
112
|
return this.data;
|
|
113
113
|
}
|
|
114
114
|
/** @private */
|
|
115
115
|
lint(start = this.getAbsoluteIndex(), errorRegex) {
|
|
116
|
+
if (errorRegex === false) {
|
|
117
|
+
return [];
|
|
118
|
+
}
|
|
116
119
|
const { data, parentNode, nextSibling, previousSibling } = this;
|
|
117
120
|
if (!parentNode) {
|
|
118
121
|
throw new Error('An isolated text node cannot be linted!');
|
|
@@ -152,9 +155,7 @@ class AstText extends node_1.AstNode {
|
|
|
152
155
|
|| char === '['
|
|
153
156
|
&& type === 'ext-link-text'
|
|
154
157
|
&& (/&(?:rbrack|#93|#x5[Dd];);/u.test(data.slice(index + 1))
|
|
155
|
-
||
|
|
156
|
-
&& nextName === 'nowiki'
|
|
157
|
-
&& nextSibling.innerText?.includes(']'))) {
|
|
158
|
+
|| nextSibling?.is('ext') && nextName === 'nowiki' && nextSibling.innerText?.includes(']'))) {
|
|
158
159
|
continue;
|
|
159
160
|
}
|
|
160
161
|
else if (char === ']' && (index || length > 1)) {
|
|
@@ -341,11 +342,20 @@ class AstText extends node_1.AstNode {
|
|
|
341
342
|
if (i < this.length - 1) {
|
|
342
343
|
this.splitText(i + 1);
|
|
343
344
|
}
|
|
345
|
+
this.after(debug_1.Shadow.run(
|
|
344
346
|
// @ts-expect-error abstract class
|
|
345
|
-
|
|
347
|
+
() => new TranscludeToken('=', [], this.parentNode.getAttribute('config'))));
|
|
346
348
|
this.#setData(this.data.slice(0, i));
|
|
347
349
|
}
|
|
348
350
|
}
|
|
351
|
+
/**
|
|
352
|
+
* 生成HTML
|
|
353
|
+
* @param nowrap 是否不换行
|
|
354
|
+
*/
|
|
355
|
+
toHtml(nowrap) {
|
|
356
|
+
const { data } = this;
|
|
357
|
+
return (0, string_1.font)(this, (0, string_1.sanitize)(nowrap ? data.replace(/\n/gu, ' ') : data));
|
|
358
|
+
}
|
|
349
359
|
}
|
|
350
360
|
exports.AstText = AstText;
|
|
351
361
|
constants_1.classes['AstText'] = __filename;
|
package/dist/lib/title.d.ts
CHANGED
package/dist/lib/title.js
CHANGED
|
@@ -21,6 +21,7 @@ class Title {
|
|
|
21
21
|
encoded = false;
|
|
22
22
|
/* NOT FOR BROWSER */
|
|
23
23
|
#fragment;
|
|
24
|
+
#path;
|
|
24
25
|
/** @private */
|
|
25
26
|
conversionTable = new Map();
|
|
26
27
|
/** @private */
|
|
@@ -138,6 +139,7 @@ class Title {
|
|
|
138
139
|
redirects: { enumerable: false },
|
|
139
140
|
});
|
|
140
141
|
this.#namespaces = config.namespaces;
|
|
142
|
+
this.#path = config.articlePath || '/wiki/$1';
|
|
141
143
|
}
|
|
142
144
|
/** @private */
|
|
143
145
|
toString() {
|
|
@@ -192,6 +194,12 @@ class Title {
|
|
|
192
194
|
toRootPage() {
|
|
193
195
|
this.main = this.main.replace(/\/.*/u, '');
|
|
194
196
|
}
|
|
197
|
+
/** 生成URL */
|
|
198
|
+
getUrl() {
|
|
199
|
+
return this.#path.replace('$1', `${encodeURIComponent(this.title)}${this.fragment === undefined && this.#fragment === undefined
|
|
200
|
+
? ''
|
|
201
|
+
: `#${encodeURIComponent(this.fragment ?? this.#fragment)}`}`);
|
|
202
|
+
}
|
|
195
203
|
}
|
|
196
204
|
exports.Title = Title;
|
|
197
205
|
constants_1.classes['Title'] = __filename;
|
|
@@ -35,9 +35,6 @@ const attributesParent = (i = 0) => (constructor, _) => {
|
|
|
35
35
|
get classList() {
|
|
36
36
|
return this.#attributesChild.classList;
|
|
37
37
|
}
|
|
38
|
-
set classList(classList) {
|
|
39
|
-
this.#attributesChild.classList = classList;
|
|
40
|
-
}
|
|
41
38
|
/** @implements */
|
|
42
39
|
get id() {
|
|
43
40
|
return this.#attributesChild.id;
|
package/dist/mixin/hidden.d.ts
CHANGED
package/dist/mixin/hidden.js
CHANGED
|
@@ -6,17 +6,17 @@ const constants_1 = require("../util/constants");
|
|
|
6
6
|
/**
|
|
7
7
|
* 解析后不可见的类
|
|
8
8
|
* @param linter 是否覆写 lint 方法
|
|
9
|
+
* @param html 是否覆写 toHtml 方法
|
|
9
10
|
* @param constructor 基类
|
|
10
11
|
* @param _ context
|
|
11
12
|
*/
|
|
12
|
-
const hiddenToken = (linter) => (constructor, _) => {
|
|
13
|
+
const hiddenToken = (linter = true, html = true) => (constructor, _) => {
|
|
13
14
|
/** 解析后不可见的类 */
|
|
14
15
|
class AnyHiddenToken extends constructor {
|
|
15
16
|
/** 没有可见部分 */
|
|
16
17
|
text() {
|
|
17
18
|
return '';
|
|
18
19
|
}
|
|
19
|
-
/** @private */
|
|
20
20
|
lint(start) {
|
|
21
21
|
// @ts-expect-error private argument
|
|
22
22
|
return linter ? [] : super.lint(start);
|
|
@@ -26,6 +26,9 @@ const hiddenToken = (linter) => (constructor, _) => {
|
|
|
26
26
|
dispatchEvent() {
|
|
27
27
|
//
|
|
28
28
|
}
|
|
29
|
+
toHtml(nowrap) {
|
|
30
|
+
return html ? '' : super.toHtml(nowrap);
|
|
31
|
+
}
|
|
29
32
|
}
|
|
30
33
|
(0, debug_1.mixin)(AnyHiddenToken, constructor);
|
|
31
34
|
return AnyHiddenToken;
|
package/dist/mixin/singleLine.js
CHANGED
|
@@ -11,11 +11,9 @@ const constants_1 = require("../util/constants");
|
|
|
11
11
|
const singleLine = (constructor, _) => {
|
|
12
12
|
/** 不可包含换行符的类 */
|
|
13
13
|
class SingleLineToken extends constructor {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
return super.toString().replace(/\n/gu, ' ');
|
|
14
|
+
toString(skip) {
|
|
15
|
+
return super.toString(skip).replace(/\n/gu, ' ');
|
|
17
16
|
}
|
|
18
|
-
/** @private */
|
|
19
17
|
text() {
|
|
20
18
|
return super.text().replace(/\n/gu, ' ');
|
|
21
19
|
}
|
package/dist/mixin/sol.d.ts
CHANGED
package/dist/mixin/sol.js
CHANGED
|
@@ -5,34 +5,34 @@ const debug_1 = require("../util/debug");
|
|
|
5
5
|
const constants_1 = require("../util/constants");
|
|
6
6
|
/**
|
|
7
7
|
* 只能位于行首的类
|
|
8
|
+
* @param self 是否允许同类节点相邻
|
|
8
9
|
* @param constructor 基类
|
|
9
10
|
* @param _ context
|
|
10
11
|
*/
|
|
11
|
-
const sol = (constructor, _) => {
|
|
12
|
+
const sol = (self) => (constructor, _) => {
|
|
12
13
|
/** 只能位于行首的类 */
|
|
13
14
|
class SolToken extends constructor {
|
|
14
15
|
/** @implements */
|
|
15
16
|
#prependNewLine() {
|
|
16
17
|
const { previousVisibleSibling, parentNode, type } = this;
|
|
17
18
|
if (previousVisibleSibling) {
|
|
18
|
-
return previousVisibleSibling.toString().endsWith('\n')
|
|
19
|
+
return self && previousVisibleSibling.type === type || previousVisibleSibling.toString().endsWith('\n')
|
|
20
|
+
? ''
|
|
21
|
+
: '\n';
|
|
19
22
|
}
|
|
20
23
|
return parentNode?.type === 'root'
|
|
21
24
|
|| type !== 'heading' && parentNode?.type === 'ext-inner' && parentNode.name === 'poem'
|
|
22
25
|
? ''
|
|
23
26
|
: '\n';
|
|
24
27
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return this.#prependNewLine() + super.toString();
|
|
28
|
+
toString(skip) {
|
|
29
|
+
return this.#prependNewLine() + super.toString(skip);
|
|
28
30
|
}
|
|
29
|
-
/** @private */
|
|
30
31
|
getAttribute(key) {
|
|
31
32
|
return key === 'padding'
|
|
32
33
|
? this.#prependNewLine().length + super.getAttribute('padding')
|
|
33
34
|
: super.getAttribute(key);
|
|
34
35
|
}
|
|
35
|
-
/** @private */
|
|
36
36
|
text() {
|
|
37
37
|
return this.#prependNewLine() + super.text();
|
|
38
38
|
}
|
package/dist/mixin/syntax.js
CHANGED
|
@@ -21,7 +21,6 @@ const syntax = (pattern) => (constructor, _) => {
|
|
|
21
21
|
}
|
|
22
22
|
this.seal('pattern', true);
|
|
23
23
|
}
|
|
24
|
-
/** @private */
|
|
25
24
|
afterBuild() {
|
|
26
25
|
super.afterBuild();
|
|
27
26
|
const /** @implements */ syntaxListener = (e, data) => {
|
|
@@ -32,7 +31,6 @@ const syntax = (pattern) => (constructor, _) => {
|
|
|
32
31
|
};
|
|
33
32
|
this.addEventListener(['remove', 'insert', 'replace', 'text'], syntaxListener);
|
|
34
33
|
}
|
|
35
|
-
/** @private */
|
|
36
34
|
replaceChildren(...elements) {
|
|
37
35
|
if (debug_1.Shadow.running || this.pattern.test((0, string_1.text)(elements))) {
|
|
38
36
|
debug_1.Shadow.run(() => {
|
package/dist/parser/list.js
CHANGED
|
@@ -11,18 +11,20 @@ const dd_1 = require("../src/nowiki/dd");
|
|
|
11
11
|
* @param accum
|
|
12
12
|
*/
|
|
13
13
|
const parseList = (wikitext, config, accum) => {
|
|
14
|
-
const mt = /^((?:\0\d+c\x7F)*)([;:*#]
|
|
14
|
+
const mt = /^((?:\0\d+c\x7F)*)([;:*#]+\s*)/u.exec(wikitext);
|
|
15
15
|
if (!mt) {
|
|
16
16
|
return wikitext;
|
|
17
17
|
}
|
|
18
|
-
const [total, comment, prefix] = mt;
|
|
19
|
-
let text =
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
const [total, comment, prefix] = mt, parts = prefix.split(/(?=;)/u);
|
|
19
|
+
let text = comment + parts.map((_, i) => `\0${accum.length + i}d\x7F`).join('') + wikitext.slice(total.length), dt = parts.length - (parts[0].startsWith(';') ? 0 : 1);
|
|
20
|
+
for (const part of parts) {
|
|
21
|
+
// @ts-expect-error abstract class
|
|
22
|
+
new list_1.ListToken(part, config, accum);
|
|
23
|
+
}
|
|
22
24
|
if (!dt) {
|
|
23
25
|
return text;
|
|
24
26
|
}
|
|
25
|
-
const { html: [normalTags] } = config, fullRegex =
|
|
27
|
+
const { html: [normalTags] } = config, fullRegex = /:+\s*|-\{|\0\d+[xq]\x7F/gu;
|
|
26
28
|
let regex = fullRegex, ex = regex.exec(text), lt = 0, lb = false, li = false, lc = 0;
|
|
27
29
|
/**
|
|
28
30
|
* 创建`DdToken`
|
package/dist/parser/selector.js
CHANGED
|
@@ -128,6 +128,7 @@ const matches = (token, step) => {
|
|
|
128
128
|
return token.text().trim() === '';
|
|
129
129
|
case ':any-link':
|
|
130
130
|
return type === 'link'
|
|
131
|
+
|| type === 'redirect-target'
|
|
131
132
|
|| type === 'free-ext-link'
|
|
132
133
|
|| type === 'magic-link'
|
|
133
134
|
|| type === 'ext-link'
|
|
@@ -320,7 +321,7 @@ const checkToken = (selector) => (token) => {
|
|
|
320
321
|
}
|
|
321
322
|
}
|
|
322
323
|
}
|
|
323
|
-
step.push(...pieces.filter(piece => piece.startsWith('#')).map(
|
|
324
|
+
step.push(...pieces.filter(piece => piece.startsWith('#')).map(desanitize));
|
|
324
325
|
};
|
|
325
326
|
/**
|
|
326
327
|
* 检查是否需要通用选择器
|
package/dist/parser/table.js
CHANGED
|
@@ -68,8 +68,8 @@ const parseTable = ({ firstChild: { data }, type, name }, config, accum) => {
|
|
|
68
68
|
out += `\n${outLine}`;
|
|
69
69
|
continue;
|
|
70
70
|
}
|
|
71
|
-
// eslint-disable-
|
|
72
|
-
|
|
71
|
+
const matches = // eslint-disable-line @stylistic/operator-linebreak
|
|
72
|
+
/^(?:(\|\}|\0\d+!\x7F\}|\0\d+\}\x7F)|(\|-+|\0\d+!\x7F-+|\0\d+-\x7F-*)(?!-)|(!|(?:\||\0\d+!\x7F)\+?))(.*)$/u
|
|
73
73
|
.exec(line);
|
|
74
74
|
if (!matches) {
|
|
75
75
|
push(`\n${outLine}`, top);
|
package/dist/src/arg.js
CHANGED
|
@@ -55,8 +55,8 @@ class ArgToken extends index_2.Token {
|
|
|
55
55
|
this.protectChildren(0);
|
|
56
56
|
}
|
|
57
57
|
/** @private */
|
|
58
|
-
toString() {
|
|
59
|
-
return `{{{${super.toString('|')}}}}`;
|
|
58
|
+
toString(skip) {
|
|
59
|
+
return `{{{${super.toString(skip, '|')}}}}`;
|
|
60
60
|
}
|
|
61
61
|
/** @private */
|
|
62
62
|
text() {
|
|
@@ -133,7 +133,7 @@ class ArgToken extends index_2.Token {
|
|
|
133
133
|
}
|
|
134
134
|
/** 设置name */
|
|
135
135
|
#setName() {
|
|
136
|
-
this.setAttribute('name', this.firstChild.
|
|
136
|
+
this.setAttribute('name', this.firstChild.toString(true).trim());
|
|
137
137
|
}
|
|
138
138
|
/** @private */
|
|
139
139
|
afterBuild() {
|
package/dist/src/attribute.js
CHANGED
|
@@ -99,7 +99,6 @@ const commonHtmlAttrs = new Set([
|
|
|
99
99
|
img: new Set(['alt', 'src', 'width', 'height', 'srcset']),
|
|
100
100
|
font: new Set(['size', 'color', 'face']),
|
|
101
101
|
hr: widthAttrs,
|
|
102
|
-
rt: new Set(['rbspan']),
|
|
103
102
|
data: new Set(['value']),
|
|
104
103
|
time: new Set(['datetime']),
|
|
105
104
|
meta: new Set(['itemprop', 'content']),
|
|
@@ -262,9 +261,7 @@ let AttributeToken = (() => {
|
|
|
262
261
|
* @param quotes 引号
|
|
263
262
|
*/
|
|
264
263
|
constructor(type, tag, key, equal = '', value, quotes = [], config = index_1.default.getConfig(), accum = []) {
|
|
265
|
-
const keyToken = new atom_1.AtomToken(key, 'attr-key', config, accum, {
|
|
266
|
-
[type === 'ext-attr' ? 'AstText' : 'Stage-1']: ':', ArgToken: ':', TranscludeToken: ':',
|
|
267
|
-
});
|
|
264
|
+
const keyToken = new atom_1.AtomToken(key, 'attr-key', config, accum, type === 'ext-attr' ? { AstText: ':' } : { 'Stage-2': ':', '!ExtToken': '', '!HeadingToken': '' });
|
|
268
265
|
let valueToken;
|
|
269
266
|
if (key === 'title' || tag === 'img' && key === 'alt') {
|
|
270
267
|
valueToken = new index_2.Token(value, config, accum, {
|
|
@@ -273,23 +270,14 @@ let AttributeToken = (() => {
|
|
|
273
270
|
valueToken.type = 'attr-value';
|
|
274
271
|
valueToken.setAttribute('stage', constants_1.MAX_STAGE - 1);
|
|
275
272
|
}
|
|
276
|
-
else if (tag === 'gallery' && key === 'caption'
|
|
277
|
-
|
|
278
|
-
...config,
|
|
279
|
-
excludes: [...config.excludes, 'quote', 'extLink', 'magicLink', 'list'],
|
|
280
|
-
};
|
|
281
|
-
valueToken = new index_2.Token(value, newConfig, accum, {
|
|
282
|
-
AstText: ':', LinkToken: ':', FileToken: ':', CategoryToken: ':', ConverterToken: ':',
|
|
283
|
-
});
|
|
284
|
-
valueToken.type = 'attr-value';
|
|
285
|
-
valueToken.setAttribute('stage', 5);
|
|
286
|
-
}
|
|
287
|
-
else if (tag === 'choose' && (key === 'before' || key === 'after')) {
|
|
273
|
+
else if (tag === 'gallery' && key === 'caption'
|
|
274
|
+
|| tag === 'choose' && (key === 'before' || key === 'after')) {
|
|
288
275
|
const newConfig = {
|
|
289
276
|
...config,
|
|
290
277
|
excludes: [...config.excludes, 'heading', 'html', 'table', 'hr', 'list'],
|
|
291
278
|
};
|
|
292
279
|
valueToken = new index_2.Token(value, newConfig, accum, {
|
|
280
|
+
AstText: ':',
|
|
293
281
|
ArgToken: ':',
|
|
294
282
|
TranscludeToken: ':',
|
|
295
283
|
LinkToken: ':',
|
|
@@ -324,13 +312,13 @@ let AttributeToken = (() => {
|
|
|
324
312
|
if (this.parentNode) {
|
|
325
313
|
this.#tag = this.parentNode.name;
|
|
326
314
|
}
|
|
327
|
-
this.setAttribute('name', this.firstChild.
|
|
315
|
+
this.setAttribute('name', this.firstChild.toString(true).trim().toLowerCase());
|
|
328
316
|
super.afterBuild();
|
|
329
317
|
}
|
|
330
318
|
/** @private */
|
|
331
|
-
toString() {
|
|
319
|
+
toString(skip) {
|
|
332
320
|
const [quoteStart = '', quoteEnd = ''] = this.#quotes;
|
|
333
|
-
return this.#equal ? super.toString(this.#equal + quoteStart) + quoteEnd : this.firstChild.toString();
|
|
321
|
+
return this.#equal ? super.toString(skip, this.#equal + quoteStart) + quoteEnd : this.firstChild.toString(skip);
|
|
334
322
|
}
|
|
335
323
|
/** @private */
|
|
336
324
|
text() {
|
|
@@ -378,7 +366,7 @@ let AttributeToken = (() => {
|
|
|
378
366
|
else if (name === 'style' && typeof value === 'string' && insecureStyle.test(value)) {
|
|
379
367
|
errors.push((0, lint_1.generateForChild)(lastChild, rect, 'insecure-style', 'insecure style'));
|
|
380
368
|
}
|
|
381
|
-
else if (name === 'tabindex' && typeof value === 'string' && value
|
|
369
|
+
else if (name === 'tabindex' && typeof value === 'string' && value !== '0') {
|
|
382
370
|
const e = (0, lint_1.generateForChild)(lastChild, rect, 'illegal-attr', 'nonzero tabindex');
|
|
383
371
|
e.suggestions = [
|
|
384
372
|
{
|
|
@@ -398,14 +386,7 @@ let AttributeToken = (() => {
|
|
|
398
386
|
}
|
|
399
387
|
/** 获取属性值 */
|
|
400
388
|
getValue() {
|
|
401
|
-
|
|
402
|
-
const value = this.lastChild.text();
|
|
403
|
-
if (this.#quotes[1]) {
|
|
404
|
-
return value;
|
|
405
|
-
}
|
|
406
|
-
return value[this.#quotes[0] ? 'trimEnd' : 'trim']();
|
|
407
|
-
}
|
|
408
|
-
return this.type === 'ext-attr' || '';
|
|
389
|
+
return this.#equal ? this.lastChild.text().trim() : this.type === 'ext-attr' || '';
|
|
409
390
|
}
|
|
410
391
|
/** @private */
|
|
411
392
|
print() {
|
|
@@ -479,6 +460,22 @@ let AttributeToken = (() => {
|
|
|
479
460
|
const config = this.getAttribute('config'), { childNodes } = index_1.default.parse(key, this.getAttribute('include'), stages[this.type] + 1, config);
|
|
480
461
|
this.firstChild.replaceChildren(...childNodes);
|
|
481
462
|
}
|
|
463
|
+
/** @private */
|
|
464
|
+
toHtml() {
|
|
465
|
+
const { type, name, tag, lastChild } = this;
|
|
466
|
+
if (type === 'ext-attr' && !(tag in htmlAttrs)
|
|
467
|
+
|| !htmlAttrs[tag]?.has(name) && (tag === 'meta' || tag === 'link' || !commonHtmlAttrs.has(name))) {
|
|
468
|
+
return '';
|
|
469
|
+
}
|
|
470
|
+
let value = lastChild.toHtml().trim();
|
|
471
|
+
if (name === 'style' && insecureStyle.test(value) || name === 'tabindex' && value !== '0') {
|
|
472
|
+
return '';
|
|
473
|
+
}
|
|
474
|
+
else if (name === 'id') {
|
|
475
|
+
value = value.replace(/\s+/gu, '_');
|
|
476
|
+
}
|
|
477
|
+
return `${name}="${value.replace(/["\n]/gu, p => p === '"' ? '"' : ' ')}"`;
|
|
478
|
+
}
|
|
482
479
|
};
|
|
483
480
|
return AttributeToken = _classThis;
|
|
484
481
|
})();
|
package/dist/src/attributes.d.ts
CHANGED
package/dist/src/attributes.js
CHANGED
|
@@ -30,6 +30,7 @@ const toDirty = (type) => `${toAttributeType(type)}-dirty`;
|
|
|
30
30
|
*/
|
|
31
31
|
class AttributesToken extends index_2.Token {
|
|
32
32
|
#type;
|
|
33
|
+
#classList;
|
|
33
34
|
/* NOT FOR BROWSER END */
|
|
34
35
|
get type() {
|
|
35
36
|
return this.#type;
|
|
@@ -53,10 +54,26 @@ class AttributesToken extends index_2.Token {
|
|
|
53
54
|
}
|
|
54
55
|
/** 以Set表示的class属性 */
|
|
55
56
|
get classList() {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
if (!this.#classList) {
|
|
58
|
+
this.#classList = new Set(this.className.split(/\s/u));
|
|
59
|
+
/**
|
|
60
|
+
* 更新classList
|
|
61
|
+
* @param prop 方法名
|
|
62
|
+
*/
|
|
63
|
+
const factory = (prop) => ({
|
|
64
|
+
value: /** @ignore */ (...args) => {
|
|
65
|
+
const result = Set.prototype[prop].apply(this.#classList, args);
|
|
66
|
+
this.setAttr('class', [...this.#classList].join(' '));
|
|
67
|
+
return result;
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
Object.defineProperties(this.#classList, {
|
|
71
|
+
add: factory('add'),
|
|
72
|
+
delete: factory('delete'),
|
|
73
|
+
clear: factory('clear'),
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return this.#classList;
|
|
60
77
|
}
|
|
61
78
|
/** id属性 */
|
|
62
79
|
get id() {
|
|
@@ -175,7 +192,7 @@ class AttributesToken extends index_2.Token {
|
|
|
175
192
|
duplicated.add(name);
|
|
176
193
|
attrs.get(name).push(attr);
|
|
177
194
|
}
|
|
178
|
-
else
|
|
195
|
+
else {
|
|
179
196
|
attrs.set(name, [attr]);
|
|
180
197
|
}
|
|
181
198
|
}
|
|
@@ -329,11 +346,11 @@ class AttributesToken extends index_2.Token {
|
|
|
329
346
|
return str && type !== 'table-attrs' && !leadingRegex[type].test(str) ? ' ' : '';
|
|
330
347
|
}
|
|
331
348
|
/** @private */
|
|
332
|
-
toString() {
|
|
349
|
+
toString(skip) {
|
|
333
350
|
if (this.type === 'table-attrs') {
|
|
334
351
|
(0, string_1.normalizeSpace)(this);
|
|
335
352
|
}
|
|
336
|
-
const str = super.toString();
|
|
353
|
+
const str = super.toString(skip);
|
|
337
354
|
return this.#leadingSpace(str) + str;
|
|
338
355
|
}
|
|
339
356
|
/** @private */
|
|
@@ -350,6 +367,16 @@ class AttributesToken extends index_2.Token {
|
|
|
350
367
|
const str = (0, string_1.text)(this.childNodes.filter(child => child instanceof attribute_1.AttributeToken), ' ');
|
|
351
368
|
return this.#leadingSpace(str) + str;
|
|
352
369
|
}
|
|
370
|
+
/** @private */
|
|
371
|
+
toHtml() {
|
|
372
|
+
const map = new Map();
|
|
373
|
+
for (const child of this.childNodes) {
|
|
374
|
+
if (child instanceof attribute_1.AttributeToken) {
|
|
375
|
+
map.set(child.name, child);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
return ` ${(0, string_1.html)([...map.values()], ' ')}`;
|
|
379
|
+
}
|
|
353
380
|
}
|
|
354
381
|
exports.AttributesToken = AttributesToken;
|
|
355
382
|
constants_1.classes['AttributesToken'] = __filename;
|
package/dist/src/converter.d.ts
CHANGED
|
@@ -10,10 +10,10 @@ export interface ConverterToken extends FlagsParentBase {
|
|
|
10
10
|
* @classdesc `{childNodes: [ConverterFlagsToken, ...ConverterRuleToken]}`
|
|
11
11
|
*/
|
|
12
12
|
export declare abstract class ConverterToken extends Token {
|
|
13
|
-
readonly childNodes: readonly [ConverterFlagsToken, ...ConverterRuleToken[]];
|
|
13
|
+
readonly childNodes: readonly [ConverterFlagsToken, ConverterRuleToken, ...ConverterRuleToken[]];
|
|
14
14
|
abstract get firstChild(): ConverterFlagsToken;
|
|
15
15
|
abstract get lastChild(): ConverterFlagsToken | ConverterRuleToken;
|
|
16
|
-
abstract get children(): [ConverterFlagsToken, ...ConverterRuleToken[]];
|
|
16
|
+
abstract get children(): [ConverterFlagsToken, ConverterRuleToken, ...ConverterRuleToken[]];
|
|
17
17
|
abstract get firstElementChild(): ConverterFlagsToken;
|
|
18
18
|
abstract get lastElementChild(): ConverterFlagsToken | ConverterRuleToken;
|
|
19
19
|
get type(): 'converter';
|