wikiparser-node 0.4.0 → 0.6.2-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.
- package/bundle/bundle.min.js +34 -0
- package/package.json +12 -5
- package/.eslintrc.json +0 -714
- package/README.md +0 -39
- package/config/default.json +0 -769
- package/config/llwiki.json +0 -630
- package/config/moegirl.json +0 -727
- package/config/zhwiki.json +0 -1269
- package/errors/README +0 -1
- package/index.js +0 -245
- package/jsconfig.json +0 -7
- package/lib/element.js +0 -755
- package/lib/node.js +0 -585
- package/lib/ranges.js +0 -131
- package/lib/text.js +0 -146
- package/lib/title.js +0 -69
- package/mixin/attributeParent.js +0 -113
- package/mixin/fixedToken.js +0 -40
- package/mixin/hidden.js +0 -19
- package/mixin/sol.js +0 -59
- package/parser/brackets.js +0 -112
- package/parser/commentAndExt.js +0 -63
- package/parser/converter.js +0 -45
- package/parser/externalLinks.js +0 -31
- package/parser/hrAndDoubleUnderscore.js +0 -35
- package/parser/html.js +0 -42
- package/parser/links.js +0 -98
- package/parser/list.js +0 -59
- package/parser/magicLinks.js +0 -41
- package/parser/quotes.js +0 -64
- package/parser/selector.js +0 -175
- package/parser/table.js +0 -112
- package/printed/README +0 -1
- package/printed/example.json +0 -120
- package/src/arg.js +0 -169
- package/src/atom/hidden.js +0 -13
- package/src/atom/index.js +0 -41
- package/src/attribute.js +0 -422
- package/src/converter.js +0 -157
- package/src/converterFlags.js +0 -232
- package/src/converterRule.js +0 -253
- package/src/extLink.js +0 -167
- package/src/gallery.js +0 -91
- package/src/heading.js +0 -100
- package/src/html.js +0 -202
- package/src/imageParameter.js +0 -254
- package/src/index.js +0 -737
- package/src/link/category.js +0 -53
- package/src/link/file.js +0 -265
- package/src/link/galleryImage.js +0 -61
- package/src/link/index.js +0 -322
- package/src/magicLink.js +0 -108
- package/src/nowiki/comment.js +0 -57
- package/src/nowiki/dd.js +0 -59
- package/src/nowiki/doubleUnderscore.js +0 -51
- package/src/nowiki/hr.js +0 -41
- package/src/nowiki/index.js +0 -44
- package/src/nowiki/list.js +0 -16
- package/src/nowiki/noinclude.js +0 -28
- package/src/nowiki/quote.js +0 -36
- package/src/onlyinclude.js +0 -54
- package/src/parameter.js +0 -187
- package/src/syntax.js +0 -83
- package/src/table/index.js +0 -967
- package/src/table/td.js +0 -308
- package/src/table/tr.js +0 -282
- package/src/tagPair/ext.js +0 -105
- package/src/tagPair/include.js +0 -50
- package/src/tagPair/index.js +0 -117
- package/src/transclude.js +0 -703
- package/test/api.js +0 -83
- package/test/real.js +0 -133
- package/test/test.js +0 -28
- package/test/util.js +0 -80
- package/tool/index.js +0 -918
- package/typings/api.d.ts +0 -13
- package/typings/array.d.ts +0 -28
- package/typings/event.d.ts +0 -24
- package/typings/index.d.ts +0 -94
- package/typings/node.d.ts +0 -29
- package/typings/parser.d.ts +0 -16
- package/typings/table.d.ts +0 -14
- package/typings/token.d.ts +0 -22
- package/typings/tool.d.ts +0 -11
- package/util/debug.js +0 -73
- package/util/string.js +0 -88
package/src/attribute.js
DELETED
|
@@ -1,422 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const {externalUse} = require('../util/debug'),
|
|
4
|
-
{toCase, removeComment, normalizeSpace} = require('../util/string'),
|
|
5
|
-
Parser = require('..'),
|
|
6
|
-
Token = require('.');
|
|
7
|
-
|
|
8
|
-
const stages = {'ext-attr': 0, 'html-attr': 2, 'table-attr': 3};
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* 扩展和HTML标签属性
|
|
12
|
-
* @classdesc `{childNodes: [AstText]|(AstText|ArgToken|TranscludeToken)[]}`
|
|
13
|
-
*/
|
|
14
|
-
class AttributeToken extends Token {
|
|
15
|
-
/** @type {Map<string, string|true>} */ #attr = new Map();
|
|
16
|
-
#sanitized = true;
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* @override
|
|
20
|
-
* @param {string} key 属性键
|
|
21
|
-
* @param {string|undefined} equal 属性规则运算符,`equal`存在时`val`和`i`也一定存在
|
|
22
|
-
* @param {string|undefined} val 属性值
|
|
23
|
-
* @param {string|undefined} i 是否对大小写不敏感
|
|
24
|
-
*/
|
|
25
|
-
#matchesAttr = (key, equal, val, i) => {
|
|
26
|
-
if (!equal) {
|
|
27
|
-
return this.hasAttr(key);
|
|
28
|
-
} else if (!this.hasAttr(key)) {
|
|
29
|
-
return equal === '!=';
|
|
30
|
-
}
|
|
31
|
-
val = toCase(val, i);
|
|
32
|
-
const attr = this.getAttr(key),
|
|
33
|
-
thisVal = toCase(attr === true ? '' : attr, i);
|
|
34
|
-
switch (equal) {
|
|
35
|
-
case '~=':
|
|
36
|
-
return attr !== true && thisVal.split(/\s/u).includes(val);
|
|
37
|
-
case '|=': // 允许`val === ''`
|
|
38
|
-
return thisVal === val || thisVal.startsWith(`${val}-`);
|
|
39
|
-
case '^=':
|
|
40
|
-
return attr !== true && thisVal.startsWith(val);
|
|
41
|
-
case '$=':
|
|
42
|
-
return attr !== true && thisVal.endsWith(val);
|
|
43
|
-
case '*=':
|
|
44
|
-
return attr !== true && thisVal.includes(val);
|
|
45
|
-
case '!=':
|
|
46
|
-
return thisVal !== val;
|
|
47
|
-
default: // `=`
|
|
48
|
-
return thisVal === val;
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* getAttr()方法的getter写法
|
|
54
|
-
* @returns {Record<string, string|true>}
|
|
55
|
-
*/
|
|
56
|
-
get attributes() {
|
|
57
|
-
return this.getAttr();
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/** 以字符串表示的class属性 */
|
|
61
|
-
get className() {
|
|
62
|
-
const attr = this.getAttr('class');
|
|
63
|
-
return typeof attr === 'string' ? attr : '';
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
set className(className) {
|
|
67
|
-
this.setAttr('class', className);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/** 以Set表示的class属性 */
|
|
71
|
-
get classList() {
|
|
72
|
-
return new Set(this.className.split(/\s/u));
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/** id属性 */
|
|
76
|
-
get id() {
|
|
77
|
-
const attr = this.getAttr('id');
|
|
78
|
-
return typeof attr === 'string' ? attr : '';
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
set id(id) {
|
|
82
|
-
this.setAttr('id', id);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* 从`this.#attr`更新`childNodes`
|
|
87
|
-
* @complexity `n`
|
|
88
|
-
*/
|
|
89
|
-
#updateFromAttr() {
|
|
90
|
-
let equal = '=';
|
|
91
|
-
const ParameterToken = require('./parameter');
|
|
92
|
-
const parent = this.closest('ext, parameter');
|
|
93
|
-
if (parent instanceof ParameterToken && parent.anon
|
|
94
|
-
&& parent.parentNode?.matches('template, magic-word#invoke')
|
|
95
|
-
) {
|
|
96
|
-
equal = '{{=}}';
|
|
97
|
-
}
|
|
98
|
-
return [...this.#attr].map(([k, v]) => {
|
|
99
|
-
if (v === true) {
|
|
100
|
-
return k;
|
|
101
|
-
}
|
|
102
|
-
const quote = v.includes('"') ? "'" : '"';
|
|
103
|
-
return `${k}${equal}${quote}${v}${quote}`;
|
|
104
|
-
}).join(' ');
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* 清理标签属性
|
|
109
|
-
* @complexity `n`
|
|
110
|
-
*/
|
|
111
|
-
sanitize() {
|
|
112
|
-
if (!Parser.running && !this.#sanitized) {
|
|
113
|
-
Parser.warn(`${this.constructor.name}.sanitize 方法将清理无效属性!`);
|
|
114
|
-
}
|
|
115
|
-
const token = Parser.parse(this.#updateFromAttr(), false, stages[this.type], this.getAttribute('config'));
|
|
116
|
-
Parser.run(() => {
|
|
117
|
-
this.replaceChildren(...token.childNodes, true);
|
|
118
|
-
});
|
|
119
|
-
this.#sanitized = true;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* 从`childNodes`更新`this.#attr`
|
|
124
|
-
* @complexity `n`
|
|
125
|
-
*/
|
|
126
|
-
#parseAttr() {
|
|
127
|
-
this.#attr.clear();
|
|
128
|
-
let string = this.toString('comment, include, noinclude, heading, html'),
|
|
129
|
-
token;
|
|
130
|
-
if (this.type !== 'ext-attr' && !Parser.running) {
|
|
131
|
-
const config = this.getAttribute('config'),
|
|
132
|
-
include = this.getAttribute('include');
|
|
133
|
-
token = Parser.run(() => {
|
|
134
|
-
const newToken = new Token(string, config),
|
|
135
|
-
parseOnce = newToken.getAttribute('parseOnce');
|
|
136
|
-
parseOnce(0, include);
|
|
137
|
-
return parseOnce();
|
|
138
|
-
});
|
|
139
|
-
string = String(token);
|
|
140
|
-
}
|
|
141
|
-
string = removeComment(string).replaceAll(/\0\d+~\x7F/gu, '=');
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* 解析并重建标签属性
|
|
145
|
-
* @param {string|boolean} str 半解析的标签属性文本
|
|
146
|
-
*/
|
|
147
|
-
const build = str =>
|
|
148
|
-
typeof str === 'boolean' || !token ? str : token.getAttribute('buildFromStr')(str).map(String).join('');
|
|
149
|
-
for (const [, key,, quoted, unquoted] of string
|
|
150
|
-
.matchAll(/([^\s/][^\s/=]*)(?:\s*=\s*(?:(["'])(.*?)(?:\2|$)|(\S*)))?/gsu)
|
|
151
|
-
) {
|
|
152
|
-
if (!this.setAttr(build(key), build(quoted ?? unquoted ?? true), true)) {
|
|
153
|
-
this.#sanitized = false;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* @param {string} attr 标签属性
|
|
160
|
-
* @param {'ext-attr'|'html-attr'|'table-attr'} type 标签类型
|
|
161
|
-
* @param {string} name 标签名
|
|
162
|
-
* @param {accum} accum
|
|
163
|
-
*/
|
|
164
|
-
constructor(attr, type, name, config = Parser.getConfig(), accum = []) {
|
|
165
|
-
super(attr, config, true, accum, {[`Stage-${stages[type]}`]: ':'});
|
|
166
|
-
this.type = type;
|
|
167
|
-
this.setAttribute('name', name).#parseAttr();
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/** @override */
|
|
171
|
-
cloneNode() {
|
|
172
|
-
const cloned = this.cloneChildNodes();
|
|
173
|
-
return Parser.run(() => {
|
|
174
|
-
const token = new AttributeToken(undefined, this.type, this.name, this.getAttribute('config'));
|
|
175
|
-
token.append(...cloned);
|
|
176
|
-
return token.afterBuild();
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* @override
|
|
182
|
-
* @template {string} T
|
|
183
|
-
* @param {T} key 属性键
|
|
184
|
-
* @returns {TokenAttribute<T>}
|
|
185
|
-
*/
|
|
186
|
-
getAttribute(key) {
|
|
187
|
-
if (key === 'matchesAttr') {
|
|
188
|
-
return this.#matchesAttr;
|
|
189
|
-
}
|
|
190
|
-
return key === 'attr' ? new Map(this.#attr) : super.getAttribute(key);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/** @override */
|
|
194
|
-
afterBuild() {
|
|
195
|
-
if (this.type !== 'ext-attr') {
|
|
196
|
-
const buildFromStr = this.getAttribute('buildFromStr');
|
|
197
|
-
for (let [key, text] of this.#attr) {
|
|
198
|
-
let built = false;
|
|
199
|
-
if (key.includes('\0')) {
|
|
200
|
-
this.#attr.delete(key);
|
|
201
|
-
key = buildFromStr(key).map(String).join('');
|
|
202
|
-
built = true;
|
|
203
|
-
}
|
|
204
|
-
if (typeof text === 'string' && text.includes('\0')) {
|
|
205
|
-
text = buildFromStr(text).map(String).join('');
|
|
206
|
-
built = true;
|
|
207
|
-
}
|
|
208
|
-
if (built) {
|
|
209
|
-
this.#attr.set(key, text);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
const /** @type {AstListener} */ attributeListener = ({type, target}) => {
|
|
214
|
-
if (type === 'text' || target !== this) {
|
|
215
|
-
this.#parseAttr();
|
|
216
|
-
}
|
|
217
|
-
};
|
|
218
|
-
this.addEventListener(['remove', 'insert', 'replace', 'text'], attributeListener);
|
|
219
|
-
return this;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* 标签是否具有某属性
|
|
224
|
-
* @param {string} key 属性键
|
|
225
|
-
*/
|
|
226
|
-
hasAttr(key) {
|
|
227
|
-
return typeof key === 'string' ? this.#attr.has(key.toLowerCase().trim()) : this.typeError('hasAttr', 'String');
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* 获取标签属性
|
|
232
|
-
* @template {string|undefined} T
|
|
233
|
-
* @param {T} key 属性键
|
|
234
|
-
* @returns {T extends string ? string|true : Record<string, string|true>}
|
|
235
|
-
*/
|
|
236
|
-
getAttr(key) {
|
|
237
|
-
if (key === undefined) {
|
|
238
|
-
return Object.fromEntries(this.#attr);
|
|
239
|
-
}
|
|
240
|
-
return typeof key === 'string' ? this.#attr.get(key.toLowerCase().trim()) : this.typeError('getAttr', 'String');
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
/** 获取全部的标签属性名 */
|
|
244
|
-
getAttrNames() {
|
|
245
|
-
return [...this.#attr.keys()];
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
/** 标签是否具有任意属性 */
|
|
249
|
-
hasAttrs() {
|
|
250
|
-
return this.getAttrNames().length > 0;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
/**
|
|
254
|
-
* 设置标签属性
|
|
255
|
-
* @param {string} key 属性键
|
|
256
|
-
* @param {string|boolean} value 属性值
|
|
257
|
-
* @param {boolean} init 是否是初次解析
|
|
258
|
-
* @complexity `n`
|
|
259
|
-
* @throws `RangeError` 扩展标签属性不能包含">"
|
|
260
|
-
* @throws `RangeError` 无效的属性名
|
|
261
|
-
*/
|
|
262
|
-
setAttr(key, value, init) {
|
|
263
|
-
init &&= !externalUse('setAttr');
|
|
264
|
-
if (typeof key !== 'string' || typeof value !== 'string' && typeof value !== 'boolean') {
|
|
265
|
-
this.typeError('setAttr', 'String', 'Boolean');
|
|
266
|
-
} else if (!init && this.type === 'ext-attr' && typeof value === 'string' && value.includes('>')) {
|
|
267
|
-
throw new RangeError('扩展标签属性不能包含 ">"!');
|
|
268
|
-
}
|
|
269
|
-
key = key.toLowerCase().trim();
|
|
270
|
-
const config = this.getAttribute('config'),
|
|
271
|
-
include = this.getAttribute('include'),
|
|
272
|
-
parsedKey = this.type === 'ext-attr' || init
|
|
273
|
-
? key
|
|
274
|
-
: Parser.run(() => {
|
|
275
|
-
const token = new Token(key, config),
|
|
276
|
-
parseOnce = token.getAttribute('parseOnce');
|
|
277
|
-
parseOnce(0, include);
|
|
278
|
-
return String(parseOnce());
|
|
279
|
-
});
|
|
280
|
-
if (!/^(?:[\w:]|\0\d+[t!~{}+-]\x7F)(?:[\w:.-]|\0\d+[t!~{}+-]\x7F)*$/u.test(parsedKey)) {
|
|
281
|
-
if (init) {
|
|
282
|
-
return false;
|
|
283
|
-
}
|
|
284
|
-
throw new RangeError(`无效的属性名:${key}!`);
|
|
285
|
-
} else if (value === false) {
|
|
286
|
-
this.#attr.delete(key);
|
|
287
|
-
} else {
|
|
288
|
-
this.#attr.set(key, value === true ? true : value.replaceAll(/\s/gu, ' ').trim());
|
|
289
|
-
}
|
|
290
|
-
if (!init) {
|
|
291
|
-
this.sanitize();
|
|
292
|
-
}
|
|
293
|
-
return true;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
/**
|
|
297
|
-
* 移除标签属性
|
|
298
|
-
* @param {string} key 属性键
|
|
299
|
-
* @complexity `n`
|
|
300
|
-
*/
|
|
301
|
-
removeAttr(key) {
|
|
302
|
-
if (typeof key !== 'string') {
|
|
303
|
-
this.typeError('removeAttr', 'String');
|
|
304
|
-
}
|
|
305
|
-
key = key.toLowerCase().trim();
|
|
306
|
-
if (this.#attr.delete(key)) {
|
|
307
|
-
this.sanitize();
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
/**
|
|
312
|
-
* 开关标签属性
|
|
313
|
-
* @param {string} key 属性键
|
|
314
|
-
* @param {boolean|undefined} force 强制开启或关闭
|
|
315
|
-
* @complexity `n`
|
|
316
|
-
* @throws `RangeError` 不为Boolean类型的属性值
|
|
317
|
-
*/
|
|
318
|
-
toggleAttr(key, force) {
|
|
319
|
-
if (typeof key !== 'string') {
|
|
320
|
-
this.typeError('toggleAttr', 'String');
|
|
321
|
-
} else if (force !== undefined) {
|
|
322
|
-
force = Boolean(force);
|
|
323
|
-
}
|
|
324
|
-
key = key.toLowerCase().trim();
|
|
325
|
-
const value = this.#attr.has(key) ? this.#attr.get(key) : false;
|
|
326
|
-
if (typeof value !== 'boolean') {
|
|
327
|
-
throw new RangeError(`${key} 属性的值不为 Boolean!`);
|
|
328
|
-
}
|
|
329
|
-
this.setAttr(key, force === true || force === undefined && value === false);
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
/**
|
|
333
|
-
* 生成引导空格
|
|
334
|
-
* @param {string} str 属性字符串
|
|
335
|
-
*/
|
|
336
|
-
#leadingSpace(str = super.toString()) {
|
|
337
|
-
return this.type !== 'table-attr' && str && str.trimStart() === str ? ' ' : '';
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
/**
|
|
341
|
-
* @override
|
|
342
|
-
* @this {AttributeToken & Token}
|
|
343
|
-
* @param {string} selector
|
|
344
|
-
*/
|
|
345
|
-
toString(selector) {
|
|
346
|
-
if (this.type === 'table-attr') {
|
|
347
|
-
normalizeSpace(this);
|
|
348
|
-
}
|
|
349
|
-
const str = super.toString(selector);
|
|
350
|
-
return `${this.#leadingSpace(str)}${str}`;
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
/** @override */
|
|
354
|
-
getPadding() {
|
|
355
|
-
return this.#leadingSpace().length;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
/** @override */
|
|
359
|
-
text() {
|
|
360
|
-
if (this.type === 'table-attr') {
|
|
361
|
-
normalizeSpace(this);
|
|
362
|
-
}
|
|
363
|
-
const str = this.#updateFromAttr();
|
|
364
|
-
return `${this.#leadingSpace(str)}${str}`;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
/**
|
|
368
|
-
* @override
|
|
369
|
-
* @param {number} i 移除位置
|
|
370
|
-
* @param {boolean} done 是否已解析过改变后的标签属性
|
|
371
|
-
* @complexity `n`
|
|
372
|
-
*/
|
|
373
|
-
removeAt(i, done) {
|
|
374
|
-
done &&= !externalUse('removeAt');
|
|
375
|
-
done ||= Parser.running;
|
|
376
|
-
const token = super.removeAt(i);
|
|
377
|
-
if (!done) {
|
|
378
|
-
this.#parseAttr();
|
|
379
|
-
}
|
|
380
|
-
return token;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
/**
|
|
384
|
-
* @override
|
|
385
|
-
* @template {Token} T
|
|
386
|
-
* @param {T} token 待插入的节点
|
|
387
|
-
* @param {number} i 插入位置
|
|
388
|
-
* @param {boolean} done 是否已解析过改变后的标签属性
|
|
389
|
-
* @complexity `n`
|
|
390
|
-
*/
|
|
391
|
-
insertAt(token, i = this.childNodes.length, done = false) {
|
|
392
|
-
done &&= !externalUse('insertAt');
|
|
393
|
-
done ||= Parser.running;
|
|
394
|
-
super.insertAt(token, i);
|
|
395
|
-
if (!done) {
|
|
396
|
-
this.#parseAttr();
|
|
397
|
-
}
|
|
398
|
-
return token;
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
/**
|
|
402
|
-
* @override
|
|
403
|
-
* @param {...Token} elements 待替换的子节点
|
|
404
|
-
* @complexity `n²`
|
|
405
|
-
*/
|
|
406
|
-
replaceChildren(...elements) {
|
|
407
|
-
let done = false;
|
|
408
|
-
if (typeof elements.at(-1) === 'boolean') {
|
|
409
|
-
done = elements.pop();
|
|
410
|
-
}
|
|
411
|
-
done &&= !externalUse('replaceChildren');
|
|
412
|
-
for (let i = this.childNodes.length - 1; i >= 0; i--) {
|
|
413
|
-
this.removeAt(i, done);
|
|
414
|
-
}
|
|
415
|
-
for (const element of elements) {
|
|
416
|
-
this.insertAt(element, undefined, done);
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
Parser.classes.AttributeToken = __filename;
|
|
422
|
-
module.exports = AttributeToken;
|
package/src/converter.js
DELETED
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const {text} = require('../util/string'),
|
|
4
|
-
Parser = require('..'),
|
|
5
|
-
Token = require('.'),
|
|
6
|
-
ConverterFlagsToken = require('./converterFlags'),
|
|
7
|
-
ConverterRuleToken = require('./converterRule');
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* 转换
|
|
11
|
-
* @classdesc `{childNodes: [ConverterFlagsToken, ...ConverterRuleToken]}`
|
|
12
|
-
*/
|
|
13
|
-
class ConverterToken extends Token {
|
|
14
|
-
type = 'converter';
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* 是否无转换
|
|
18
|
-
* @this {ConverterToken & {lastChild: ConverterRuleToken}}
|
|
19
|
-
*/
|
|
20
|
-
get noConvert() {
|
|
21
|
-
return this.hasFlag('R') || this.childNodes.length === 2 && !this.lastChild.variant;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* @param {string[]} flags 转换类型标记
|
|
26
|
-
* @param {string[]} rules 转换规则
|
|
27
|
-
* @param {accum} accum
|
|
28
|
-
*/
|
|
29
|
-
constructor(flags, rules, config = Parser.getConfig(), accum = []) {
|
|
30
|
-
super(undefined, config, true, accum);
|
|
31
|
-
this.append(new ConverterFlagsToken(flags, config, accum));
|
|
32
|
-
const [firstRule] = rules,
|
|
33
|
-
hasColon = firstRule.includes(':'),
|
|
34
|
-
firstRuleToken = new ConverterRuleToken(firstRule, hasColon, config, accum);
|
|
35
|
-
if (hasColon && firstRuleToken.childNodes.length === 1) {
|
|
36
|
-
this.appendChild(new ConverterRuleToken(rules.join(';'), false, config, accum));
|
|
37
|
-
} else {
|
|
38
|
-
this.append(
|
|
39
|
-
firstRuleToken,
|
|
40
|
-
...rules.slice(1).map(rule => new ConverterRuleToken(rule, true, config, accum)),
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
this.getAttribute('protectChildren')(0);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/** @override */
|
|
47
|
-
cloneNode() {
|
|
48
|
-
const [flags, ...rules] = this.cloneChildNodes(),
|
|
49
|
-
token = Parser.run(() => new ConverterToken([], [], this.getAttribute('config')));
|
|
50
|
-
token.firstElementChild.safeReplaceWith(flags);
|
|
51
|
-
token.append(...rules);
|
|
52
|
-
return token;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* @override
|
|
57
|
-
* @param {string} selector
|
|
58
|
-
*/
|
|
59
|
-
toString(selector) {
|
|
60
|
-
const {children: [flags, ...rules]} = this;
|
|
61
|
-
return selector && this.matches(selector)
|
|
62
|
-
? ''
|
|
63
|
-
: `-{${flags.toString(selector)}${flags.childNodes.length > 0 ? '|' : ''}${rules.map(String).join(';')}}-`;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/** @override */
|
|
67
|
-
getPadding() {
|
|
68
|
-
return 2;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* /** @override
|
|
73
|
-
* @param {number} i 子节点位置
|
|
74
|
-
*/
|
|
75
|
-
getGaps(i = 0) {
|
|
76
|
-
i = i < 0 ? i + this.childNodes.length : i;
|
|
77
|
-
return i || this.firstElementChild.childNodes.length > 0 ? 1 : 0;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/** @override */
|
|
81
|
-
text() {
|
|
82
|
-
const {children: [flags, ...rules]} = this;
|
|
83
|
-
return `-{${flags.text()}|${text(rules, ';')}}-`;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* 获取所有转换类型标记
|
|
88
|
-
* @this {{firstChild: ConverterFlagsToken}}
|
|
89
|
-
*/
|
|
90
|
-
getAllFlags() {
|
|
91
|
-
return this.firstChild.getAllFlags();
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* 获取有效的转换类型标记
|
|
96
|
-
* @this {{firstChild: ConverterFlagsToken}}
|
|
97
|
-
*/
|
|
98
|
-
getEffectiveFlags() {
|
|
99
|
-
return this.firstChild.getEffectiveFlags();
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* 获取未知的转换类型标记
|
|
104
|
-
* @this {{firstChild: ConverterFlagsToken}}
|
|
105
|
-
*/
|
|
106
|
-
getUnknownFlags() {
|
|
107
|
-
return this.firstChild.getUnknownFlags();
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* 是否具有某转换类型标记
|
|
112
|
-
* @this {{firstChild: ConverterFlagsToken}}
|
|
113
|
-
* @param {string} flag 转换类型标记
|
|
114
|
-
*/
|
|
115
|
-
hasFlag(flag) {
|
|
116
|
-
return this.firstChild.hasFlag(flag);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* 是否具有某有效的转换类型标记
|
|
121
|
-
* @this {{firstChild: ConverterFlagsToken}}
|
|
122
|
-
* @param {string} flag 转换类型标记
|
|
123
|
-
*/
|
|
124
|
-
hasEffectiveFlag(flag) {
|
|
125
|
-
return this.firstChild.hasEffectiveFlag(flag);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* 移除转换类型标记
|
|
130
|
-
* @this {{firstChild: ConverterFlagsToken}}
|
|
131
|
-
* @param {string} flag 转换类型标记
|
|
132
|
-
*/
|
|
133
|
-
removeFlag(flag) {
|
|
134
|
-
this.firstChild.removeFlag(flag);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* 设置转换类型标记
|
|
139
|
-
* @this {{firstChild: ConverterFlagsToken}}
|
|
140
|
-
* @param {string} flag 转换类型标记
|
|
141
|
-
*/
|
|
142
|
-
setFlag(flag) {
|
|
143
|
-
this.firstChild.setFlag(flag);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* 开关某转换类型标记
|
|
148
|
-
* @this {{firstChild: ConverterFlagsToken}}
|
|
149
|
-
* @param {string} flag 转换类型标记
|
|
150
|
-
*/
|
|
151
|
-
toggleFlag(flag) {
|
|
152
|
-
this.firstChild.toggleFlag(flag);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
Parser.classes.ConverterToken = __filename;
|
|
157
|
-
module.exports = ConverterToken;
|