wikiparser-node 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/.eslintrc.json +229 -0
  2. package/LICENSE +674 -0
  3. package/README.md +1896 -0
  4. package/config/default.json +766 -0
  5. package/config/llwiki.json +686 -0
  6. package/config/moegirl.json +721 -0
  7. package/index.js +159 -0
  8. package/jsconfig.json +7 -0
  9. package/lib/element.js +690 -0
  10. package/lib/node.js +357 -0
  11. package/lib/ranges.js +122 -0
  12. package/lib/title.js +57 -0
  13. package/mixin/attributeParent.js +67 -0
  14. package/mixin/fixedToken.js +32 -0
  15. package/mixin/hidden.js +22 -0
  16. package/package.json +30 -0
  17. package/parser/brackets.js +107 -0
  18. package/parser/commentAndExt.js +61 -0
  19. package/parser/externalLinks.js +30 -0
  20. package/parser/hrAndDoubleUnderscore.js +26 -0
  21. package/parser/html.js +41 -0
  22. package/parser/links.js +92 -0
  23. package/parser/magicLinks.js +40 -0
  24. package/parser/quotes.js +63 -0
  25. package/parser/table.js +97 -0
  26. package/src/arg.js +150 -0
  27. package/src/atom/hidden.js +10 -0
  28. package/src/atom/index.js +33 -0
  29. package/src/attribute.js +342 -0
  30. package/src/extLink.js +116 -0
  31. package/src/heading.js +91 -0
  32. package/src/html.js +144 -0
  33. package/src/imageParameter.js +172 -0
  34. package/src/index.js +602 -0
  35. package/src/link/category.js +88 -0
  36. package/src/link/file.js +201 -0
  37. package/src/link/index.js +214 -0
  38. package/src/listToken.js +47 -0
  39. package/src/magicLink.js +66 -0
  40. package/src/nowiki/comment.js +45 -0
  41. package/src/nowiki/doubleUnderscore.js +42 -0
  42. package/src/nowiki/hr.js +41 -0
  43. package/src/nowiki/index.js +37 -0
  44. package/src/nowiki/noinclude.js +24 -0
  45. package/src/nowiki/quote.js +37 -0
  46. package/src/onlyinclude.js +42 -0
  47. package/src/parameter.js +165 -0
  48. package/src/syntax.js +80 -0
  49. package/src/table/index.js +867 -0
  50. package/src/table/td.js +259 -0
  51. package/src/table/tr.js +244 -0
  52. package/src/tagPair/ext.js +85 -0
  53. package/src/tagPair/include.js +45 -0
  54. package/src/tagPair/index.js +91 -0
  55. package/src/transclude.js +627 -0
  56. package/tool/index.js +898 -0
  57. package/typings/element.d.ts +28 -0
  58. package/typings/index.d.ts +49 -0
  59. package/typings/node.d.ts +23 -0
  60. package/typings/parser.d.ts +9 -0
  61. package/typings/table.d.ts +14 -0
  62. package/typings/token.d.ts +21 -0
  63. package/typings/tool.d.ts +10 -0
  64. package/util/debug.js +70 -0
  65. package/util/string.js +60 -0
package/README.md ADDED
@@ -0,0 +1,1896 @@
1
+ # 目录
2
+ <details>
3
+ <summary>展开</summary>
4
+
5
+ 1. [Parser](#parser)
6
+ 1. [方法](#parser.methods)
7
+ 1. [parse](#parser.parse)
8
+ 2. [isInterwiki](#parser.isinterwiki)
9
+ 3. [normalizeTitle](#parser.normalizetitle)
10
+ 4. [getTool](#parser.gettool)
11
+ 2. [属性](#parser.properties)
12
+ 1. [config](#parser.config)
13
+ 2. [AstElement](#astelement)
14
+ 1. [原型方法](#astelement.prototype.methods)
15
+ 2. [实例属性](#astelement.instance.properties)
16
+ 3. [原型属性](#astelement.prototype.properties)
17
+ 3. [Token](#token)
18
+ 1. [原型方法](#token.prototype.methods)
19
+ 1. [destroy](#token.destroy)
20
+ 2. [getAncestors](#token.getancestors)
21
+ 3. [isPlain](#token.isplain)
22
+ 4. [toString](#token.tostring)
23
+ 5. [text](#token.text)
24
+ 6. [safeReplaceWith](#token.safereplacewith)
25
+ 7. [setText](#token.settext)
26
+ 8. [sections](#token.sections)
27
+ 9. [section](#token.section)
28
+ 10. [findEnclosingHtml](#token.findenclosinghtml)
29
+ 11. [getCategories](#token.getcategories)
30
+ 12. [redoQuotes](#token.redoquotes)
31
+ 2. [实例属性](#token.instance.properties)
32
+ 1. [type](#token.type)
33
+ 3. [原型属性](#token.prototype.properties)
34
+ 4. [CommentToken](#commenttoken)
35
+ 1. [实例属性](#commenttoken.instance.properties)
36
+ 1. [closed](#commenttoken.closed)
37
+ 5. [ExtToken](#exttoken)
38
+ 1. [实例属性](#exttoken.instance.properties)
39
+ 1. [selfClosing](#exttoken.selfclosing)
40
+ 2. [name](#exttoken.name)
41
+ 6. [AttributeToken](#attributetoken)
42
+ 1. [原型方法](#attributetoken.prototype.methods)
43
+ 1. [hasAttr](#attributetoken.hasattr)
44
+ 2. [getAttr](#attributetoken.getattr)
45
+ 3. [getAttrNames](#attributetoken.getattrnames)
46
+ 4. [hasAttrs](#attributetoken.hasattrs)
47
+ 5. [setAttr](#attributetoken.setattr)
48
+ 6. [removeAttr](#attributetoken.removeattr)
49
+ 7. [toggleAttr](#attributetoken.toggleattr)
50
+ 8. [sanitize](#attributetoken.sanitize)
51
+ 2. [实例属性](#attributetoken.instance.properties)
52
+ 1. [name](#attributetoken.name)
53
+ 7. [HeadingToken](#headingtoken)
54
+ 1. [原型方法](#headingtoken.prototype.methods)
55
+ 1. [setLevel](#headingtoken.setlevel)
56
+ 2. [实例属性](#headingtoken.instance.properties)
57
+ 1. [name](#headingtoken.name)
58
+ 8. [ArgToken](#argtoken)
59
+ 1. [原型方法](#argtoken.prototype.methods)
60
+ 1. [setName](argtoken.setname)
61
+ 2. [setDefault](argtoken.setdefault)
62
+ 2. [实例属性](argtoken.instance.properties)
63
+ 1. [name](argtoken.name)
64
+ 9. [TranscludeToken](#transcludetoken)
65
+ 1. [原型方法](#transcludetoken.prototype.methods)
66
+ 1. [subst](#transcludetoken.subst)
67
+ 2. [safesubst](#transcludetoken.safesubst)
68
+ 3. [getAllArgs](#transcludetoken.getallargs)
69
+ 4. [getAnonArgs](#transcludetoken.getanonargs)
70
+ 5. [getArgs](#transcludetoken.getargs)
71
+ 6. [hasArg](#transcludetoken.hasarg)
72
+ 7. [getArg](#transcludetoken.getarg)
73
+ 8. [removeArg](#transcludetoken.removearg)
74
+ 9. [getKeys](#transcludetoken.getkeys)
75
+ 10. [getValues](#transcludetoken.getvalues)
76
+ 11. [getValue](#transcludetoken.getvalue)
77
+ 12. [newAnonArg](#transcludetoken.newanonarg)
78
+ 13. [setValue](#transcludetoken.setvalue)
79
+ 14. [anonToNamed](#transcludetoken.anontonamed)
80
+ 15. [replaceTemplate](#transcludetoken.replacetemplate)
81
+ 16. [hasDuplicatedArgs](#transcludetoken.hasduplicatedargs)
82
+ 17. [getDuplicatedArgs](#transcludetoken.getduplicatedargs)
83
+ 18. [fixDuplication](#transcludetoken.fixduplication)
84
+ 19. [escapeTables](#transcludetoken.escapetables)
85
+ 2. [实例属性](#transcludetoken.instance.properties)
86
+ 1. [name](#transcludetoken.name)
87
+ 2. [modifier](#transcludetoken.modifier)
88
+ 10. [ParameterToken](#parametertoken)
89
+ 1. [原型方法](#parametertoken.prototype.methods)
90
+ 1. [getValue](#parametertoken.getvalue)
91
+ 2. [setValue](#parametertoken.setvalue)
92
+ 3. [rename](#parametertoken.rename)
93
+ 2. [实例属性](#parametertoken.instance.properties)
94
+ 1. [name](#parametertoken.name)
95
+ 2. [anon](#parametertoken.anon)
96
+ 11. [HtmlToken](#htmltoken)
97
+ 1. [原型方法](#htmltoken.prototype.methods)
98
+ 1. [replaceTag](#htmltoken.replacetag)
99
+ 2. [findMatchingTag](#htmltoken.findmatchingtag)
100
+ 3. [fix](#htmltoken.fix)
101
+ 2. [实例属性](#htmltoken.instance.properties)
102
+ 1. [name](#htmltoken.name)
103
+ 2. [closing](#htmltoken.closing)
104
+ 3. [selfClosing](#htmltoken.selfclosing)
105
+ 12. [TableToken](#tabletoken)
106
+ 1. [原型方法](#tabletoken.prototype.methods)
107
+ 1. [getRowCount](#tabletoken.getrowcount)
108
+ 2. [getNthRow](#tabletoken.getnthrow)
109
+ 3. [getNthCell](#tabletoken.getnthcell)
110
+ 4. [getFullRow](#tabletoken.getfullrow)
111
+ 5. [getFullCol](#tabletoken.getfullcol)
112
+ 6. [formatTableRow](#tabletoken.formattablerow)
113
+ 7. [formatTableCol](#tabletoken.formattablecol)
114
+ 8. [insertTableRow](#tabletoken.inserttablerow)
115
+ 9. [insertTableCol](#tabletoken.inserttablecol)
116
+ 10. [insertTableCell](#tabletoken.inserttablecell)
117
+ 11. [removeTableRow](#tabletoken.removetablerow)
118
+ 12. [removeTableCol](#tabletoken.removetablecol)
119
+ 13. [mergeCells](#tabletoken.mergecells)
120
+ 14. [splitIntoRows](#tabletoken.splitintorows)
121
+ 15. [splitIntoCols](#tabletoken.splitintocols)
122
+ 16. [splitIntoCells](#tabletoken.splitintocells)
123
+ 17. [replicateTableRow](#tabletoken.replicatetablerow)
124
+ 18. [replicateTableCol](#tabletoken.replicatetablecol)
125
+ 19. [moveTableRowBefore](#tabletoken.movetablerowbefore)
126
+ 20. [moveTableRowAfter](#tabletoken.movetablerowafter)
127
+ 21. [moveTableColBefore](#tabletoken.movetablecolbefore)
128
+ 22. [moveTableColAfter](#tabletoken.movetablecolafter)
129
+ 13. [TdToken](#tdtoken)
130
+ 1. [原型属性](#tdtoken.prototype.properties)
131
+ 1. [subtype](#tdtoken.subtype)
132
+ 2. [rowspan](#tdtoken.rowspan)
133
+ 3. [colspan](#tdtoken.colspan)
134
+ 14. [DoubleUnderscoreToken](#doubleunderscoretoken)
135
+ 1. [实例属性](#doubleunderscoretoken.instance.properties)
136
+ 1. [name](#doubleunderscoretoken.name)
137
+ 15. [LinkToken](#linktoken)
138
+ 1. [原型方法](#linktoken.prototype.methods)
139
+ 1. [setTarget](#linktoken.settarget)
140
+ 2. [setFragment](#linktoken.setfragment)
141
+ 3. [asSelfLink](#linktoken.asselflink)
142
+ 4. [setLinkText](#linktoken.setlinktext)
143
+ 5. [pipeTrick](#linktoken.pipetrick)
144
+ 2. [实例属性](#linktoken.instance.properties)
145
+ 1. [name](#linktoken.name)
146
+ 2. [selfLink](#linktoken.selflink)
147
+ 3. [fragment](#linktoken.fragment)
148
+ 4. [interwiki](#linktoken.interwiki)
149
+ 16. [CategoryToken](#categorytoken)
150
+ 1. [原型方法](#categorytoken.prototype.methods)
151
+ 1. [setSortkey](#categorytoken.setsortkey)
152
+ 2. [实例属性](#categorytoken.instance.properties)
153
+ 1. [sortkey](#categorytoken.sortkey)
154
+ 17. [FileToken](#filetoken)
155
+ 1. [原型方法](#filetoken.prototype.methods)
156
+ 1. [getAllArgs](#filetoken.getallargs)
157
+ 2. [getArgs](#filetoken.getargs)
158
+ 3. [hasArg](#filetoken.hasarg)
159
+ 4. [getArg](#filetoken.getarg)
160
+ 5. [removeArg](#filetoken.removearg)
161
+ 6. [getKeys](#filetoken.getkeys)
162
+ 7. [getValue](#filetoken.getvalue)
163
+ 8. [setValue](#filetoken.setvalue)
164
+ 18. [ImageParameterToken](#imageparametertoken)
165
+ 1. [原型方法](#imageparametertoken.prototype.methods)
166
+ 1. [getValue](#imageparametertoken.getvalue)
167
+ 2. [setValue](#imageparametertoken.setvalue)
168
+ 19. [ExtLinkToken](#extlinktoken)
169
+ 1. [原型方法](#extlinktoken.prototype.methods)
170
+ 1. [getUrl](#extlinktoken.geturl)
171
+ 2. [setTarget](#extlinktoken.settarget)
172
+ 3. [setLinkText](#extlinktoken.setlinktext)
173
+ 2. [原型属性](#extlinktoken.prototype.properties)
174
+ 1. [protocol](#extlinktoken.protocol)
175
+ 20. [MagicLinkToken](#magiclinktoken)
176
+ 1. [原型方法](#magiclinktoken.prototype.methods)
177
+ 1. [getUrl](#magiclinktoken.geturl)
178
+ 2. [setTarget](#magiclinktoken.settarget)
179
+ 2. [原型属性](#magiclinktoken.prototype.properties)
180
+ 1. [protocol](#magiclinktoken.protocol)
181
+ 21. [选择器](#选择器)
182
+ 1. [type](#selector.type)
183
+ 2. [name](#selector.name)
184
+ 3. [属性](#selector.attribute)
185
+ 4. [伪选择器](#selector.pseudo)
186
+ 22. [$ (TokenCollection)](#-tokencollection)
187
+ </details>
188
+
189
+ # Parser
190
+ 这是解析工具的入口。
191
+
192
+ ```js
193
+ var Parser = require('wikiparser-node');
194
+ ```
195
+
196
+ ## 方法<a id="parser.methods"></a>
197
+
198
+ **parse**(wikitext: string, include?: boolean = false): [Token](#token)<a id="parser.parse"></a>
199
+ - 解析维基文本。
200
+
201
+ ```js
202
+ var wikitext = '<includeonly>include</includeonly><noinclude>noinclude</noinclude>',
203
+ include = Parser.parse(wikitext, true),
204
+ noinclude = Parser.parse(wikitext);
205
+ assert(include.text() === 'include'); // Token.text()方法只保留有效部分,详见后文Token章节
206
+ assert(noinclude.text() === 'noinclude');
207
+ ```
208
+
209
+ **isInterwiki**(title: string): RegExpMatchArray<a id="parser.isinterwiki"></a>
210
+ - 指定的标题是否是跨维基。
211
+
212
+ ```js
213
+ assert(Boolean(Parser.isInterwiki('zhwiki:首页')));
214
+ ```
215
+
216
+ **normalizeTitle**(title: string, defaultNs?: number = 0): string<a id="parser.normalizetitle"></a>
217
+ - 规范化页面标题。
218
+
219
+ ```js
220
+ assert(Parser.normalizeTitle('lj', 10) === 'Template:Lj');
221
+ ```
222
+
223
+ **getTool**(): typeof [$](#-tokencollection)<a id="parser.gettool"></a>
224
+ - 加载[批量操作工具](#-tokencollection)。
225
+
226
+ ## 属性<a id="parser.properties"></a>
227
+
228
+ **config**: string<a id="parser.config"></a>
229
+ - 指定解析设置JSON文件的相对或绝对路径。
230
+
231
+ ```js
232
+ assert(Parser.config === './config/default'); // 这是默认设置的相对路径
233
+ ```
234
+
235
+ [返回目录](#目录)
236
+
237
+ # AstElement
238
+ 语法树的节点均为字符串或一个仿 HTMLElement 的类 AstElement,这里仅列举这些方法和属性。
239
+
240
+ ## 原型方法<a id="astelement.prototype.methods"></a>
241
+ <details>
242
+ <summary>展开</summary>
243
+
244
+ **isEqualNode**(node: this): boolean
245
+ **cloneNode**(): this
246
+ **hasAttribute**(key: PropertyKey): boolean
247
+ **getAttribute**(key: PropertyKey): string\|undefined
248
+ **getAttributeNames**(): string[]
249
+ **hasAttributes**(): boolean
250
+ **setAttribte**(key: PropertyKey, value: any): this
251
+ **removeAttribute**(key: PropertyKey): void
252
+ **toggleAttribute**(key: PropertyKey, force?: boolean): void
253
+ **hasChildNodes**(): boolean
254
+ **contains**(node: this): boolean
255
+ **removeChild**(node: this): this
256
+ **appendChild**(node: string\|this): string\|this
257
+ **append**(...elements: string\|this): void
258
+ **insertBefore**(node: string\|this, reference: this): string\|this
259
+ **prepend**(...elements: string\|this): void
260
+ **replaceChild**(newChild: string\|this, oldChild: this): this
261
+ **replaceChildren**(...elements: string\|this): void
262
+ **after**(...element: string\|this): void
263
+ **before**(...element: string\|this): void
264
+ **remove**(): void
265
+ **replaceWith**(...elements: string\|this): void
266
+ **normalize**(): void
267
+ **getRootNode**(): this
268
+ **addEventListener**(type: string, listener: (e: event, data: any) => void, options?: {once: boolean}): void
269
+ **removeEventListener**(type: string, listener: (e: event, data: any) => void): void
270
+ **dispatchEvent**(e: event, data: any): void
271
+ **matches**(selector: string): boolean
272
+ **comparePosition**(other: this): number
273
+ **closest**(selector: string): this\|undefined
274
+ **querySelector**(selector: string): this\|undefined
275
+ **querySelectorAll**(selector: string): this[]
276
+ **getBoundingClientRect**(): {height: number, width: number, top: number, left: number}
277
+ **splitText**(i: number, offset: number): string
278
+ </details>
279
+
280
+ ## 实例属性<a id="astelement.instance.properties"></a>
281
+ <details>
282
+ <summary>展开</summary>
283
+
284
+ **childNodes**: (string\|this)[]
285
+ </details>
286
+
287
+ ## 原型属性<a id="astelement.prototype.properties"></a>
288
+ <details>
289
+ <summary>展开</summary>
290
+
291
+ **children**: this[]
292
+ **firstChild**: string\|this\|undefined
293
+ **firstElementChild**: this\|undefined
294
+ **lastChild** string\|this\|undefined
295
+ **lastElementChild**: this\|undefined
296
+ **isConnected**: boolean
297
+ **parentNode**: this\|undefined
298
+ **parentElement**: this\|undefined
299
+ **nextSibling**: string\|this\|undefined
300
+ **nextElementSibling**: this\|undefined
301
+ **previousSibling**: string\|this\|undefined
302
+ **previousElementSibling**: this\|undefined
303
+ **hidden**: boolean
304
+ **offsetHeight**: number
305
+ **offsetWidth**: number
306
+ **offsetTop**: number
307
+ **offsetLeft**: number
308
+ **style**: {top: number, left: number, height: number, width: number, padding: number}
309
+ </details>
310
+
311
+ [返回目录](#目录)
312
+
313
+ # Token
314
+ 这是所有解析后的维基文本的基础类。
315
+
316
+ ## 原型方法<a id="token.prototype.methods"></a>
317
+ <details>
318
+ <summary>展开</summary>
319
+
320
+ **destroy**(): void<a id="token.destroy"></a>
321
+ - 销毁节点,只能对根节点使用。
322
+
323
+ **getAncestors**(): Token[]<a id="token.getancestors"></a>
324
+ - 获取所有祖先节点。
325
+
326
+ ```js
327
+ var root = Parser.parse('<ref/>'),
328
+ attr = root.querySelector('ext-attr');
329
+ assert.deepStrictEqual(attr.getAncestors(), [attr.parentElement, root]);
330
+ ```
331
+
332
+ **isPlain**(): boolean<a id="token.isplain"></a>
333
+ - 是否是基础类(即未拓展的 Token)。
334
+
335
+ ```js
336
+ var root = Parser.parse(wikitext);
337
+ assert(root.isPlain() === true); // 根节点总是基础类
338
+ ```
339
+
340
+ **toString**(): string<a id="token.tostring"></a>
341
+ - 还原为完整的维基文本。
342
+
343
+ ```js
344
+ var root = Parser.parse(wikitext);
345
+ assert(root.toString() === wikitext); // 解析是可逆的
346
+ ```
347
+
348
+ **text**(): string<a id="token.text"></a>
349
+ - 移除不可见的维基文本,包括 HTML 注释、仅用于嵌入的文字(即 `<includeonly>` 或 `<onlyinclude>` 标签内部)、无效的标签属性等。
350
+
351
+ ```js
352
+ var root = Parser.parse('<!-- a -->{{{||b}}}<br */>');
353
+ assert(root.text() === '{{{|}}}<br/>');
354
+ ```
355
+
356
+ **setText**(text: string, i: number): void<a id="token.settext"></a>
357
+ - 只能通过这个方法修改指定位置上的纯字符串节点。
358
+
359
+ ```js
360
+ var root = Parser.parse('');
361
+ root.setText('string', 0);
362
+ assert(root.toString() === 'string');
363
+ ```
364
+
365
+ **safeReplaceWith**(token: Token): void<a id="token.safereplacewith"></a>
366
+ - 将节点替换为一个同类节点,相当于[replaceWith](#astelement.prototype.methods),但适用于父节点有规定的子节点顺序时。
367
+
368
+ **sections**(): Token\[\]\[\]<a id="token.sections"></a>
369
+ - 将页面分割为章节,每个章节对应一个 Token 数组。
370
+
371
+ ```js
372
+ var root = Parser.parse('a\n==b==\nc\n===d===\n'),
373
+ {childNodes} = root,
374
+ sections = root.sections();
375
+ assert.deepStrictEqual(sections, [childNodes.slice(0, 1), childNodes.slice(1), childNodes.slice(3)]);
376
+ ```
377
+
378
+ **section**(n: number): Token\[\]<a id="token.section"></a>
379
+ - 仅获取指定章节。
380
+
381
+ ```js
382
+ var root = Parser.parse('a\n==b==\nc\n===d===\n'),
383
+ section = root.section(0); // 序言对应的编号为 0
384
+ assert.deepStrictEqual(section, [root.firstChild]);
385
+ ```
386
+
387
+ **findEnclosingHtml**(tag?: string): [Token, Token]<a id="token.findenclosinghtml"></a>
388
+ - 搜索包裹当前Token的HTML标签对,不指定`tag`参数时会搜索任意HTML标签。
389
+
390
+ ```js
391
+ var root = Parser.parse('<p>{{a}}</p>'),
392
+ template = root.querySelector('template');
393
+ assert.deepStrictEqual(template.findEnclosingHtml('p'), [root.firstChild, root.lastChild]);
394
+ ```
395
+
396
+ **getCategories**(): [string, string][]<a id="token.getcategories"></a>
397
+ - 获取所有分类和对应的排序关键字。
398
+
399
+ ```js
400
+ var root = Parser.parse('[[category:a|*]]');
401
+ assert.deepStrictEqual(root.getCategories(), [['Category:A', '*']]);
402
+ ```
403
+
404
+ **redoQuotes**(): void<a id="token.redoquotes"></a>
405
+ - 经过一系列编辑操作后,重新局部解析`'`。注意这个方法会忽略所有 Token,只解析当前节点的直接纯文本子节点。
406
+
407
+ ```js
408
+ var root = Parser.parse("'''a'''");
409
+ root.lastElementChild.setText("''");
410
+ assert(root.toString() === "'''a''");
411
+ root.redoQuotes();
412
+ assert.deepStrictEqual(root.childNodes, ["'", root.firstElementChild, "a", root.lastElementChild]);
413
+ ```
414
+ </details>
415
+
416
+ ## 实例属性<a id="token.instance.properties"></a>
417
+ <details>
418
+ <summary>展开</summary>
419
+
420
+ **type**: string<a id="token.type"></a>
421
+ - 根节点的值为 `root`,其他的基础类节点一般为 `plain`。
422
+
423
+ ```js
424
+ var root = Parser.parse(wikitext);
425
+ assert(root.type === 'root');
426
+ ```
427
+ </details>
428
+
429
+ ## 原型属性<a id="token.prototype.properties"></a>
430
+ <details>
431
+ <summary>展开</summary>
432
+
433
+ **previousVisibleSibling**: string\|Token\|undefined
434
+ **nextVisibleSibling**: string\|Token\|undefined
435
+ </details>
436
+
437
+ [返回目录](#目录)
438
+
439
+ # CommentToken
440
+ HTML 注释。
441
+
442
+ ## 实例属性<a id="commenttoken.instance.properties"></a>
443
+ <details>
444
+ <summary>展开</summary>
445
+
446
+ **closed**: boolean<a id="commenttoken.closed"></a>
447
+ - 是否闭合。
448
+
449
+ ```js
450
+ var root = Parser.parse('<!-- text'),
451
+ comment = root.firstChild;
452
+ assert(comment.closed === false);
453
+ ```
454
+ </details>
455
+
456
+ [返回目录](#目录)
457
+
458
+ # ExtToken
459
+ 扩展标签。这个类同时混合了 [AttributeToken](#attributetoken) 类的方法。
460
+
461
+ ## 实例属性<a id="exttoken.instance.properties"></a>
462
+ <details>
463
+ <summary>展开</summary>
464
+
465
+ **selfClosing**: boolean<a id="exttoken.selfclosing"></a>
466
+ - 是否自封闭。
467
+
468
+ ```js
469
+ var root = Parser.parse('<ref/>'),
470
+ ref = root.firstChild;
471
+ assert(ref.selfClosing === true);
472
+ ```
473
+
474
+ **name**: string<a id="exttoken.name"></a>
475
+ - 小写的标签名。
476
+
477
+ ```js
478
+ var root = Parser.parse('<REF/>'),
479
+ ref = root.firstChild;
480
+ assert(ref.name === 'ref');
481
+ ```
482
+ </details>
483
+
484
+ [返回目录](#目录)
485
+
486
+ # AttributeToken
487
+ 扩展和 HTML 标签及表格的属性。
488
+
489
+ ## 原型方法<a id="attributetoken.prototype.methods"></a>
490
+ <details>
491
+ <summary>展开</summary>
492
+
493
+ **hasAttr**(key: string): boolean<a id="attributetoken.hasattr"></a>
494
+ - 是否带有指定属性。
495
+
496
+ ```js
497
+ var root = Parser.parse('<choose uncached before="a"></choose>'),
498
+ attr = root.querySelector('ext-attr'); // 扩展标签属性的 type 值为 'ext-attr'
499
+ assert(attr.hasAttr('uncached') === true);
500
+ assert(attr.hasAttr('before') === true);
501
+ ```
502
+
503
+ **getAttr**(key: string): string\|boolean<a id="attributetoken.getattr"></a>
504
+ - 获取指定属性。
505
+
506
+ ```js
507
+ var root = Parser.parse('<choose uncached before="a"></choose>'),
508
+ attr = root.querySelector('ext-attr');
509
+ assert(attr.getAttr('uncached') === true);
510
+ assert(attr.getAttr('before') === 'a');
511
+ ```
512
+
513
+ **getAttrNames**(): string\[\]<a id="attributetoken.getattrnames"></a>
514
+ - 获取属性名列表。
515
+
516
+ ```js
517
+ var root = Parser.parse('<ref name="a"/>'),
518
+ attr = root.querySelector('ext-attr');
519
+ assert.deepStrictEqual(attr.getAttrNames(), ['name']);
520
+ ```
521
+
522
+ **hasAttrs**(): boolean<a id="attributetoken.hasattrs"></a>
523
+ - 是否带有至少一条属性。
524
+
525
+ ```js
526
+ var root = Parser.parse('<ref/>'),
527
+ attr = root.querySelector('ext-attr');
528
+ assert(attr.hasAttrs() === false);
529
+ ```
530
+
531
+ **setAttr**(key: string, value: string\|boolean): boolean<a id="attributetoken.setattr"></a>
532
+ - 设置属性。
533
+
534
+ ```js
535
+ var root = Parser.parse('<choose></choose>'),
536
+ attr = root.querySelector('ext-attr');
537
+ assert(attr.setAttr('before', 'a') === true);
538
+ assert(attr.setAttr('uncached', true) === true);
539
+ assert(root.toString() === '<choose before="a" uncached></choose>');
540
+ ```
541
+
542
+ **removeAttr**(key: string): void<a id="attributetoken.removeattr"></a>
543
+ - 移除指定属性。
544
+
545
+ ```js
546
+ var root = Parser.parse('<ref name="a"/>'),
547
+ attr = root.querySelector('ext-attr');
548
+ attr.removeAttr('name');
549
+ assert(root.toString() === '<ref/>');
550
+ ```
551
+
552
+ **toggleAttr**(key: string): void<a id="attributetoken.toggleattr"></a>
553
+ - 切换某 Boolean 属性。
554
+
555
+ ```js
556
+ var root = Parser.parse('<choose uncached></choose>'),
557
+ attr = root.querySelector('ext-attr');
558
+ attr.toggleAttr('uncached');
559
+ assert(root.toString() === '<choose></choose>');
560
+ attr.toggleAttr('uncached');
561
+ assert(root.toString() === '<choose uncached></choose>');
562
+ ```
563
+
564
+ **sanitize**(): void<a id="attributetoken.sanitize"></a>
565
+ - 清理无效属性。
566
+
567
+ ```js
568
+ var root = Parser.parse('<p ">'),
569
+ attr = root.querySelector('html-attr');
570
+ attr.sanitize();
571
+ assert(root.toString() === '<p>');
572
+ ```
573
+ </details>
574
+
575
+ ## 实例属性<a id="attributetoken.instance.properties"></a>
576
+ <details>
577
+ <summary>展开</summary>
578
+
579
+ **name**: string<a id="attributetoken.name"></a>
580
+ - 小写的标签名。
581
+
582
+ ```js
583
+ var root = Parser.parse('<REF/>'),
584
+ attr = root.querySelector('ext-attr'); // 即使没有设置属性,扩展和 HTML 标签的第一个子节点也总是 AttributeToken
585
+ assert(attr.name === 'ref');
586
+ ```
587
+ </details>
588
+
589
+ [返回目录](#目录)
590
+
591
+ # HeadingToken
592
+ 章节标题。
593
+
594
+ ## 原型方法<a id="headingtoken.prototype.methods"></a>
595
+ <details>
596
+ <summary>展开</summary>
597
+
598
+ **setLevel**(n: number): void<a id="headingtoken.setlevel"></a>
599
+ - 修改标题层级。
600
+
601
+ ```js
602
+ var root = Parser.parse('==a=='),
603
+ header = root.firstChild;
604
+ header.setLevel(3);
605
+ assert(root.toString() === '===a===');
606
+ ```
607
+ </details>
608
+
609
+ ## 实例属性<a id="headingtoken.instance.properties"></a>
610
+ <details>
611
+ <summary>展开</summary>
612
+
613
+ **name**: string<a id="headingtoken.name"></a>
614
+ - 字符串格式的标题层级。
615
+
616
+ ```js
617
+ var root = Parser.parse('==a=='),
618
+ header = root.firstChild;
619
+ assert(header.name === '2');
620
+ ```
621
+ </details>
622
+
623
+ [返回目录](#目录)
624
+
625
+ # ArgToken
626
+ 被 `{{{}}}` 包裹的模板参数。
627
+
628
+ ## 原型方法<a id="argtoken.prototype.methods"></a>
629
+ <details>
630
+ <summary>展开</summary>
631
+
632
+ **setName**(name: any): void<a id="argtoken.setname"></a>
633
+ - 修改参数名。
634
+
635
+ ```js
636
+ var root = Parser.parse('{{{a}}}'),
637
+ arg = root.firstChild;
638
+ arg.setName('b');
639
+ assert(root.toString() === '{{{b}}}');
640
+ ```
641
+
642
+ **setDefault**(value: any): void<a id="argtoken.setdefault"></a>
643
+ - 设置或修改参数预设值。
644
+
645
+ ```js
646
+ var root = Parser.parse('{{{a}}}'),
647
+ arg = root.firstChild;
648
+ arg.setDefault('b');
649
+ assert(root.toString() === '{{{a|b}}}');
650
+ ```
651
+ </details>
652
+
653
+ ## 实例属性<a id="argtoken.instance.properties"></a>
654
+ <details>
655
+ <summary>展开</summary>
656
+
657
+ **name**: string<a id="argtoken.name"></a>
658
+ - 参数名。
659
+
660
+ ```js
661
+ var root = Parser.parse('{{{a}}}'),
662
+ arg = root.firstChild;
663
+ assert(arg.name === 'a');
664
+ ```
665
+ </details>
666
+
667
+ [返回目录](#目录)
668
+
669
+ # TranscludeToken
670
+ 模板或魔术字。
671
+
672
+ ## 原型方法<a id="transcludetoken.prototype.methods"></a>
673
+ <details>
674
+ <summary>展开</summary>
675
+
676
+ **subst**(): void<a id="transcludetoken.subst"></a>
677
+ **safesubst**(): void<a id="transcludetoken.safesubst"></a>
678
+ - 将引用方式修改为替换引用。
679
+
680
+ ```js
681
+ var root = Parser.parse('{{a}}{{!}}'),
682
+ template = root.firstChild,
683
+ magicWord = root.lastChild;
684
+ template.subst();
685
+ magicWord.safesubst();
686
+ assert(root.toString() === '{{subst:a}}{{safesubst:!}}');
687
+ ```
688
+
689
+ **getAllArgs**(): [ParameterToken](#parametertoken)[]<a id="transcludetoken.getallargs"></a>
690
+ - 获取所有参数。
691
+
692
+ ```js
693
+ var root = Parser.parse('{{a|b|c=1}}{{#invoke:d|e|f|g=1}}'),
694
+ template = root.firstChild,
695
+ invoke = root.lastChild;
696
+ assert.deepStrictEqual(template.getAllArgs(), template.children.slice(1));
697
+ assert.deepStrictEqual(invoke.getAllArgs(), invoke.children.slice(3));
698
+ ```
699
+
700
+ **getAnonArgs**(): [ParameterToken](#parametertoken)[]<a id="transcludetoken.getanonargs"></a>
701
+ - 获取所有匿名参数。
702
+
703
+ ```js
704
+ var root = Parser.parse('{{a|b|c=1}}{{#invoke:d|e|f|g=1}}{{#if:x|y|z}}'),
705
+ [template, invoke, magicWord] = root.children;
706
+ assert.deepStrictEqual(template.getAnonArgs(), template.children.slice(1, 2));
707
+ assert.deepStrictEqual(invoke.getAnonArgs(), invoke.children.slice(3, 4));
708
+ assert.deepStrictEqual(magicWord.getAnonArgs(), magicWord.children.slice(1)); // 除#invoke外的魔术字的参数总是视为匿名参数
709
+ ```
710
+
711
+ **getArgs**(key: string\|number): Set\<[ParameterToken](#parametertoken)><a id="transcludetoken.getargs"></a>
712
+ - 获取指定名称的参数(含重复),注意顺序可能不固定。
713
+
714
+ ```js
715
+ var root = Parser.parse('{{a|b|1=c}}{{#invoke:d|e|f|1=g}}'),
716
+ template = root.firstChild,
717
+ invoke = root.lastChild;
718
+ assert.deepStrictEqual(template.getArgs(1), new Set(template.children.slice(1)));
719
+ assert.deepStrictEqual(invoke.getArgs(1), new Set(invoke.children.slice(3)));
720
+ ```
721
+
722
+ **hasArg**(key: string\|number): boolean<a id="transcludetoken.hasarg"></a>
723
+ - 是否带有指定参数。
724
+
725
+ ```js
726
+ var root = Parser.parse('{{a|b|c=1}}{{#invoke:d|e|f|g=1}}'),
727
+ template = root.firstChild,
728
+ invoke = root.lastChild;
729
+ assert(template.hasArg(1) === true);
730
+ assert(template.hasArg('c') === true);
731
+ assert(invoke.hasArg(1) === true);
732
+ assert(invoke.hasArg('g') === true);
733
+ ```
734
+
735
+ **getArg**(key: string\|number): [ParameterToken](#parametertoken)<a id="transcludetoken.getarg"></a>
736
+ - 获取指定名称的有效参数(即最后一个)。
737
+
738
+ ```js
739
+ var root = Parser.parse('{{a|b|1=c}}{{#invoke:d|e|1=f|g}}'),
740
+ template = root.firstChild,
741
+ invoke = root.lastChild;
742
+ assert(template.getArg(1) === template.lastChild);
743
+ assert(invoke.getArg(1) === invoke.lastChild);
744
+ ```
745
+
746
+ **removeArg**(key: string\|number): void<a id="transcludetoken.removearg"></a>
747
+ - 移除指定名称的参数(含重复)。
748
+
749
+ ```js
750
+ var root = Parser.parse('{{a|b|1=c}}{{#invoke:d|e|f|1=g}}'),
751
+ template = root.firstChild,
752
+ invoke = root.lastChild;
753
+ template.removeArg(1);
754
+ invoke.removeArg(1);
755
+ assert(root.toString() === '{{a}}{{#invoke:d|e}}');
756
+ ```
757
+
758
+ **getKeys**(): string[]<a id="transcludetoken.getkeys"></a>
759
+ - 获取所有参数名。
760
+
761
+ ```js
762
+ var root = Parser.parse('{{a|b=1|c=2}}{{#invoke:d|e|f=1|g=2}}'),
763
+ template = root.firstChild,
764
+ invoke = root.lastChild;
765
+ assert.deepStrictEqual(template.getKeys(), ['b', 'c']);
766
+ assert.deepStrictEqual(invoke.getKeys(), ['f', 'g']);
767
+ ```
768
+
769
+ **getValues**(key: string\|number): string[]<a id="transcludetoken.getvalues"></a>
770
+ - 获取指定名称的参数值(含重复)。
771
+
772
+ ```js
773
+ var root = Parser.parse('{{a|b|1=c}}{{#invoke:d|e|f|1=g}}'),
774
+ template = root.firstChild,
775
+ invoke = root.lastChild;
776
+ assert.deepStrictEqual(template.getValues(1), ['b', 'c']);
777
+ assert.deepStrictEqual(invoke.getValues(1), ['f', 'g']);
778
+ ```
779
+
780
+ **getValue**(key: string\|number): string<a id="transcludetoken.getvalue"></a>
781
+ - 获取指定名称的有效参数值(即最后一个)。
782
+
783
+ ```js
784
+ var root = Parser.parse('{{a|b|1= c }}{{#invoke:d|e|1=f| g }}'),
785
+ template = root.firstChild,
786
+ invoke = root.lastChild;
787
+ assert(template.getValue(1) === 'c'); // 模板的命名参数不保留首尾的空白字符
788
+ assert(invoke.getValue(1) === ' g '); // #invoke魔术字保留匿名参数首位的空白字符
789
+ ```
790
+
791
+ **newAnonArg**(val: any): void<a id="transcludetoken.newanonarg"></a>
792
+ - 在末尾添加新的匿名参数。
793
+
794
+ ```js
795
+ var root = Parser.parse('{{a|b}}{{#invoke:d|e}}'),
796
+ template = root.firstChild,
797
+ invoke = root.lastChild;
798
+ template.newAnonArg(' c ');
799
+ invoke.newAnonArg(' f ');
800
+ assert(root.toString() === '{{a|b| c }}{{#invoke:d|e| f }}');
801
+ ```
802
+
803
+ **setValue**(key: string, value: any): void<a id="transcludetoken.setvalue"></a>
804
+ - 修改或新增参数。
805
+
806
+ ```js
807
+ var root = Parser.parse('{{a|b}}{{#invoke:e|f|g=3}}'),
808
+ template = root.firstChild,
809
+ invoke = root.lastChild;
810
+ template.setValue('1', ' c ');
811
+ template.setValue('d', ' 2 ');
812
+ invoke.setValue('g', ' 4 ');
813
+ assert(root.toString() === '{{a| c |d= 2 }}{{#invoke:e|f|g= 4 }}');
814
+ ```
815
+
816
+ **anonToNamed**(): void<a id="transcludetoken.anontonamed"></a>
817
+ - 将所有匿名参数修改为对应的命名参数。
818
+
819
+ ```js
820
+ var root = Parser.parse('{{a| b | c }}{{#invoke:d|e| f }}'),
821
+ template = root.firstChild,
822
+ invoke = root.lastChild;
823
+ template.anonToNamed();
824
+ invoke.anonToNamed();
825
+ assert(root.toString() === '{{a|1= b |2= c }}{{#invoke:d|e|1= f }}'); // 注意改成命名参数后会参数值的首尾空白字符失效
826
+ ```
827
+
828
+ **replaceTemplate**(title: string): void<a id="transcludetoken.replacetemplate"></a>
829
+ - 更换模板,但保留参数。
830
+
831
+ ```js
832
+ var root = Parser.parse('{{a|b|c=1}}'),
833
+ template = root.firstChild;
834
+ template.replaceTemplate('aa');
835
+ assert(root.toString() === '{{aa|b|c=1}}');
836
+ ```
837
+
838
+ **hasDuplicatedArgs**(): number<a id="transcludetoken.hasduplicatedargs"></a>
839
+ - 重复参数计数。
840
+
841
+ ```js
842
+ var root = Parser.parse('{{a||1=}}'),
843
+ template = root.firstChild;
844
+ assert(template.hasDuplicatedArgs() === 1);
845
+ ```
846
+
847
+ **getDuplicatedArgs**(): \[string, Set\<[ParameterToken](#parametertoken)>][]<a id="transcludetoken.getduplicatedargs"></a>
848
+ - 获取全部重复参数,注意顺序可能不固定。
849
+
850
+ ```js
851
+ var root = Parser.parse('{{a||1=}}'),
852
+ template = root.firstChild;
853
+ assert.deepStrictEqual(template.getDuplicatedArgs(), [['1', new Set(template.getAllArgs())]]);
854
+ ```
855
+
856
+ **fixDuplication**(): string[]<a id="transcludetoken.fixduplication"></a>
857
+ - 尝试修复重复参数,返回值为无法修复的参数名列表。
858
+
859
+ ```js
860
+ var root = Parser.parse('{{a|b|1=|1=c}}'),
861
+ template = root.firstChild;
862
+ assert.deepStrictEqual(template.fixDuplication(), ['1']);
863
+ assert(root.toString() === '{{a|b|1=c}}');
864
+ ```
865
+
866
+ **escapeTables**(): this<a id="transcludetoken.escapetables"></a>
867
+ - 如果内部包含疑似未转义的表格语法且因此造成了重复参数,则对这些表格进行转义。
868
+
869
+ ```js
870
+ var root = Parser.parse('{{a|b=c\n{|\n|rowspan=2|d\n|rowspan=2|e\n|}}}'),
871
+ template = root.firstChild;
872
+ template.escapeTables();
873
+ assert(root.toString() === '{{a|b=c\n{{(!}}\n{{!}}rowspan=2{{!}}d\n{{!}}rowspan=2{{!}}e\n{{!}}}}}');
874
+ ```
875
+ </details>
876
+
877
+ ## 实例属性<a id="transcludetoken.instance.properties"></a>
878
+ <details>
879
+ <summary>展开</summary>
880
+
881
+ **name**: string<a id="transcludetoken.name"></a>
882
+ - 模板名(含名字空间)或魔术字。
883
+
884
+ ```js
885
+ var root = Parser.parse('{{a}}{{!}}'),
886
+ template = root.firstChild,
887
+ magicWord = root.lastChild;
888
+ assert(template.name === 'Template:A');
889
+ assert(magicWord.name === '!');
890
+ ```
891
+
892
+ **modifier**: string<a id="transcludetoken.modifier"></a>
893
+ - subst 和 safesubst 等。
894
+
895
+ ```js
896
+ var root = Parser.parse('<includeonly>{{subst:REVISIONUSER}}</includeonly>', true),
897
+ magicWord = root.querySelector('magic-word');
898
+ assert(magicWord.modifier === 'subst');
899
+ ```
900
+ </details>
901
+
902
+ [返回目录](#目录)
903
+
904
+ # ParameterToken
905
+ 模板或魔术字的参数。
906
+
907
+ ## 原型方法<a id="parametertoken.prototype.methods"></a>
908
+ <details>
909
+ <summary>展开</summary>
910
+
911
+ **getValue**(): string<a id="parametertoken.getvalue"></a>
912
+ - 获取参数值。
913
+
914
+ ```js
915
+ var root = Parser.parse('{{a| b | c = 1 }}'),
916
+ [anonymous, named] = root.querySelectorAll('parameter');
917
+ assert(anonymous.getValue() === ' b '); // 模板的匿名参数保留首尾的空白字符
918
+ assert(named.getValue() === '1'); // 模板的命名参数不保留首尾的空白字符
919
+ ```
920
+
921
+ **setValue**(value: any): void<a id="parametertoken.setvalue"></a>
922
+ - 设置参数值。
923
+
924
+ ```js
925
+ var root = Parser.parse('{{a|b=1}}'),
926
+ param = root.querySelector('parameter');
927
+ param.setValue(' 2 ');
928
+ assert(root.toString() === '{{a|b= 2 }}'); // setValue方法总是保留空白字符,哪怕是无效的
929
+ ```
930
+
931
+ **rename**(key: string, force: boolean): void<a id="parametertoken.rename"></a>
932
+ - 重命名参数,可选是否在导致重复参数时抛出错误。
933
+
934
+ ```js
935
+ var root = Parser.parse('{{a|b=1|c=2}}'),
936
+ param = root.querySelector('parameter');
937
+ try {
938
+ param.rename('c');
939
+ throw new Error();
940
+ } catch (e) {
941
+ assert(e.message === '参数更名造成重复参数:c');
942
+ }
943
+ ```
944
+ </details>
945
+
946
+ ## 实例属性<a id="parametertoken.instance.properties"></a>
947
+ <details>
948
+ <summary>展开</summary>
949
+
950
+ **name**: string<a id="parametertoken.name"></a>
951
+ - 参数名。
952
+
953
+ ```js
954
+ var root = Parser.parse('{{a|b| c = 1}}'),
955
+ [anonymous, named] = root.querySelectorAll('parameter');
956
+ assert(anonymous.name === '1');
957
+ assert(named.name === 'c');
958
+ ```
959
+
960
+ **anon**: boolean<a id="parametertoken.anon"></a>
961
+ - 是否是匿名参数。
962
+
963
+ ```js
964
+ var root = Parser.parse('{{a|b| c = 1}}'),
965
+ [anonymous, named] = root.querySelectorAll('parameter');
966
+ assert(anonymous.anon === true);
967
+ assert(named.anon === false);
968
+ ```
969
+ </details>
970
+
971
+ [返回目录](#目录)
972
+
973
+ # HtmlToken
974
+ HTML标签,未进行匹配。这个类同时混合了 [AttributeToken](#attributetoken) 类的方法。
975
+
976
+ ## 原型方法<a id="htmltoken.prototype.methods"></a>
977
+ <details>
978
+ <summary>展开</summary>
979
+
980
+ **replaceTag**(tag: string): void<a id="htmltoken.replacetag"></a>
981
+ - 修改标签。
982
+
983
+ ```js
984
+ var root = Parser.parse('<b>'),
985
+ html = root.firstChild;
986
+ html.replaceTag('i');
987
+ assert(root.toString() === '<i>');
988
+ ```
989
+
990
+ **findMatchingTag**(): HtmlToken<a id="htmltoken.findmatchingtag"></a>
991
+ - 搜索匹配的另一个标签,找不到或无效自封闭时会抛出不同错误。
992
+
993
+ ```js
994
+ var root = Parser.parse('<p><b/></i><u></u><br>'),
995
+ [p, b, i, u, u2, br] = root.children;
996
+ try {
997
+ p.findMatchingTag();
998
+ throw new Error();
999
+ } catch (e) {
1000
+ assert(e.message === '未闭合的标签:<p>');
1001
+ }
1002
+ try {
1003
+ b.findMatchingTag();
1004
+ throw new Error();
1005
+ } catch (e) {
1006
+ assert(e.message === '无效自封闭标签:<b/>');
1007
+ }
1008
+ try {
1009
+ i.findMatchingTag();
1010
+ throw new Error();
1011
+ } catch (e) {
1012
+ assert(e.message === '未匹配的闭合标签:</i>');
1013
+ }
1014
+ assert(u.findMatchingTag() === u2);
1015
+ assert(br.findMatchingTag() === br);
1016
+ ```
1017
+
1018
+ **fix**(): void<a id="htmltoken.fix"></a>
1019
+ - 尝试修复无效自封闭标签,无法修复时会抛出错误。
1020
+
1021
+ ```js
1022
+ var root = Parser.parse('<b>a<b/><div style="height:1em"/>');
1023
+ for (const html of root.querySelectorAll('html')) {
1024
+ html.fix();
1025
+ }
1026
+ assert(root.toString() === '<b>a</b><div style="height:1em"></div>');
1027
+ ```
1028
+ </details>
1029
+
1030
+ ## 实例属性<a id="htmltoken.instance.properties"></a>
1031
+ <details>
1032
+ <summary>展开</summary>
1033
+
1034
+ **name**: string<a id="htmltoken.name"></a>
1035
+ - 小写的标签名。
1036
+
1037
+ ```js
1038
+ var root = Parser.parse('<b>'),
1039
+ html = root.firstChild;
1040
+ assert(html.name === 'b');
1041
+ ```
1042
+
1043
+ **closing**: boolean<a id="htmltoken.closing"></a>
1044
+ - 是否是闭合标签。
1045
+
1046
+ ```js
1047
+ var root = Parser.parse('</b>'),
1048
+ html = root.firstChild;
1049
+ assert(html.closing === true);
1050
+ ```
1051
+
1052
+ **selfClosing**: boolean<a id="htmltoken.selfclosing"></a>
1053
+ - 是否是自闭合标签(可能不符合HTML5规范)。
1054
+
1055
+ ```js
1056
+ var root = Parser.parse('<b/>'),
1057
+ html = root.firstChild;
1058
+ assert(html.selfClosing === true);
1059
+ ```
1060
+ </details>
1061
+
1062
+ [返回目录](#目录)
1063
+
1064
+ # TableToken
1065
+ 表格。
1066
+
1067
+ ## 原型方法<a id="tabletoken.prototype.methods"></a>
1068
+ <details>
1069
+ <summary>展开</summary>
1070
+
1071
+ **getRowCount**(): number<a id="tabletoken.getrowcount"></a>
1072
+ - 表格的有效行数。
1073
+
1074
+ ```js
1075
+ var root = Parser.parse('{|\n|\n|-\n|}'),
1076
+ table = root.firstChild;
1077
+ assert(table.getRowCount() === 1); // 表格首行可以直接写在 TableToken 下,没有内容的表格行是无效行。
1078
+ ```
1079
+
1080
+ **getNthRow**(n: number): TrToken<a id="tabletoken.getnthrow"></a>
1081
+ - 第 `n` 个有效行。
1082
+
1083
+ ```js
1084
+ var root = Parser.parse('{|\n|rowspan=2| ||\n|-\n|\n|}'),
1085
+ table = root.firstChild;
1086
+ assert(table.getNthRow(0) === table);
1087
+ assert(table.getNthRow(1) === table.querySelector('tr'));
1088
+ ```
1089
+
1090
+ |表格示意|
1091
+ |:-:|
1092
+ |<table><tr><td rowspan=2>第 0 行</td><td>第 0 行</td></tr><tr><td>第 1 行</td></tr></table>|
1093
+
1094
+ **getNthCell**(coords: {row: number, column: number}\|{x: number, y: number}): [TdToken](#tdtoken)<a id="tabletoken.getnthcell"></a>
1095
+ - 获取指定位置的单元格,指定位置可以基于 raw HTML 或渲染后的表格。
1096
+
1097
+ ```js
1098
+ var root = Parser.parse('{|\n|rowspan=2 colspan=2| ||\n|-\n|\n|-\n| || ||\n|}'),
1099
+ table = root.firstChild,
1100
+ td = table.querySelector('td');
1101
+ assert(table.getNthCell({row: 0, column: 0}) === td);
1102
+ assert(table.getNthCell({x: 1, y: 1}) === td); // 该单元格跨了 2 行 2 列
1103
+ ```
1104
+
1105
+ |(row, column)|(y, x)|
1106
+ |:-:|:-:|
1107
+ |<table><tr><td rowspan=2 colspan=2 align="center">(0, 0)</td><td>(0, 1)</td></tr><tr><td>(1, 0)</td></tr><tr><td>(2, 0)</td><td>(2, 1)</td><td>(2, 2)</td></table>|<table><tr><td rowspan=2 colspan=2 align="center">(0, 0), (0, 1)<br>(1, 0), (1, 1)</td><td>(0, 2)</td></tr><tr><td>(1, 2)</td></tr><tr><td>(2, 0)</td><td>(2, 1)</td><td>(2, 2)</td></tr></table>|
1108
+
1109
+ **getFullRow**(y: number): Map\<[TdToken](#tdtoken), boolean><a id="tabletoken.getfullrow"></a>
1110
+ - 获取一行的所有单元格。
1111
+
1112
+ ```js
1113
+ var root = Parser.parse('{|\n|rowspan=2| ||\n|-\n|\n|}'),
1114
+ table = root.firstChild,
1115
+ [a,, c] = table.querySelectorAll('td');
1116
+ assert.deepStrictEqual(table.getFullRow(1), new Map([[a, false], [c, true]])); // 起始位置位于该行的单元格值为 `true`
1117
+ ```
1118
+
1119
+ |表格|选中第 1 行|
1120
+ |:-:|:-:|
1121
+ |<table><tr><td rowspan=2>&nbsp;</td><td>&nbsp;</td></tr><tr><td>&nbsp;</td></tr></table>|<table><tr><td rowspan=2>`false`</td><td>&nbsp;</td></tr><tr><td>`true`</td></tr></table>|
1122
+
1123
+ **getFullCol**(x: number): Map\<[TdToken](#tdtoken), boolean><a id="tabletoken.getfullcol"></a>
1124
+ - 获取一列的所有单元格。
1125
+
1126
+ ```js
1127
+ var root = Parser.parse('{|\n|colspan=2|\n|-\n| ||\n|}'),
1128
+ table = root.firstChild,
1129
+ [a,, c] = table.querySelectorAll('td');
1130
+ assert.deepStrictEqual(table.getFullCol(1), new Map([[a, false], [c, true]])); // 起始位置位于该列的单元格值为 `true`
1131
+ ```
1132
+
1133
+ |表格|选中第 1 列|
1134
+ |:-:|:-:|
1135
+ |<table><tr><td colspan=2>&nbsp;</td></tr><tr><td>&nbsp;</td><td>&nbsp;</td></tr></table>|<table><tr><td colspan=2 align="center">`false`</td></tr><tr><td>&nbsp;</td><td>`true`</td></tr></table>|
1136
+
1137
+ **formatTableRow**(y: number, attr: string\|Record\<string, string\|boolean>, multiRow?: boolean = false): void<a id="tabletoken.formattablerow"></a>
1138
+ - 批量设置一行单元格的属性。
1139
+
1140
+ ```js
1141
+ var root = Parser.parse('{|\n|rowspan=2| ||\n|-\n|\n|}'),
1142
+ table = root.firstChild;
1143
+ table.formatTableRow(1, 'th'); // `multiRow` 为假时忽略起始位置不在该行的单元格
1144
+ assert(root.toString() === '{|\n|rowspan=2| ||\n|-\n!\n|}');
1145
+ ```
1146
+
1147
+ |原表格|将第 1 行设为`<th>`<br>`multiRow = false`|将第 1 行设为`<th>`<br>`multiRow = true`|
1148
+ |:-:|:-:|:-:|
1149
+ |<table><tr><td rowspan=2 align="center">td</td><td>td</td></tr><tr><td>td</td></tr></table>|<table><tr><td rowspan=2>td</td><td>td</td></tr><tr><th>th</th></tr></table>|<table><tr><th rowspan=2>th</th><td>td</td></tr><tr><th>th</th></tr></table>|
1150
+
1151
+ **formatTableCol**(x: number, attr: string\|Record\<string, string\|boolean>, multiCol?: boolean = false): void<a id="tabletoken.formattablecol"></a>
1152
+ - 批量设置一列单元格的属性。
1153
+
1154
+ ```js
1155
+ var root = Parser.parse('{|\n|colspan=2|\n|-\n| ||\n|}'),
1156
+ table = root.firstChild;
1157
+ table.formatTableCol(1, 'th', true); // `multiCol` 为真时包含起始位置不在该列的单元格
1158
+ assert(root.toString() === '{|\n!colspan=2|\n|-\n| \n!\n|}');
1159
+ ```
1160
+
1161
+ |原表格|将第 1 列设为`<th>`<br>`multiCol = false`|将第 1 列设为`<th>`<br>`multiCol = true`|
1162
+ |:-:|:-:|:-:|
1163
+ |<table><tr><td colspan=2>td</td></tr><tr><td>td</td><td>td</td></tr></table>|<table><tr><td colspan=2>td</td></tr><tr><td>td</td><th>th</th></tr></table>|<table><tr><th colspan=2>th</th></tr><tr><td>td</td><th>th</th></tr></table>|
1164
+
1165
+ **insertTableRow**(row: number, attr: Record\<string, string\|boolean>, inner?: string, subtype?: 'td'\|'th', innerAttr?: Record\<string, string\|boolean>): TrToken<a id="tabletoken.inserttablerow"></a>
1166
+ - 插入空行或一行单元格。
1167
+
1168
+ ```js
1169
+ var root = Parser.parse('{|\n|a||rowspan=2|b||c\n|-\n|d||e\n|}'),
1170
+ table = root.firstChild;
1171
+ table.insertTableRow(1, {class: 'tr'}); // 不填写 `inner` 等后续参数时会插入一个空行,且此时是无效行。
1172
+ table.insertTableRow(1, {}, 'f', 'th', {class: 'th'});
1173
+ assert(root.toString() === '{|\n|a|| rowspan="3"|b||c\n|- class="tr"\n|-\n! class="th"|f\n! class="th"|f\n|-\n|d||e\n|}');
1174
+ ```
1175
+
1176
+ |原表格|插入 1 行|
1177
+ |:-:|:-:|
1178
+ |<table><tr><td>a</td><td rowspan=2>b</td><td>c</td></tr><tr><td>d</td><td>e</td></tr></table>|<table><tr><td>a</td><td rowspan=3>b</td><td>c</td></tr><tr><th>f</th><th>f</th></tr><tr><td>d</td><td>e</td></tr></table>|
1179
+
1180
+ **insertTableCol**(x: number, inner: string, subtype: 'td'\|'th', attr: Record\<string, string\|boolean>): void<a id="tabletoken.inserttablecol"></a>
1181
+ - 插入一列单元格。
1182
+
1183
+ ```js
1184
+ var root = Parser.parse('{|\n|colspan=2|a\n|-\n|b||c\n|}'),
1185
+ table = root.firstChild;
1186
+ table.insertTableCol(1, 'd', 'th', {class: 'th'});
1187
+ assert(root.toString() === '{|\n| colspan="3"|a\n|-\n|b\n! class="th"|d\n|c\n|}');
1188
+ ```
1189
+
1190
+ |原表格|插入 1 列|
1191
+ |:-:|:-:|
1192
+ |<table><tr><td colspan=2 align="center">a</td></tr><tr><td>b</td><td>c</td></tr></table>|<table><tr><td colspan=3 align="center">a</td></tr><tr><td>b</td><th>d</th><td>c</td></tr></table>|
1193
+
1194
+ **insertTableCell**(inner: string, coords: {row: number, column: number}\|{x: number, y: number}, subtype: 'td'\|'th', attr: Record\<string, string\|boolean>): [TdToken](#tdtoken)<a id="tabletoken.inserttablecell"></a>
1195
+ - 插入一个单元格。
1196
+
1197
+ ```js
1198
+ var root = Parser.parse('{|\n|rowspan=2 colspan=2|a||b\n|-\n|c\n|-\n|d||e||f\n|}'),
1199
+ table = root.firstChild;
1200
+ table.insertTableCell('g', {row: 0, column: 2}, 'th');
1201
+ table.insertTableCell('h', {x: 2, y: 1}, 'th', {rowspan: 2});
1202
+ assert(root.toString() === '{|\n|rowspan=2 colspan=2|a||b\n!g\n|-\n! rowspan="2"|h\n|c\n|-\n|d||e||f\n|}');
1203
+ ```
1204
+
1205
+ |原表格|插入 2 格|
1206
+ |:-:|:-:|
1207
+ |<table><tr><td rowspan=2 colspan=2 align="center">a</td><td>b</td></tr><tr><td>c</td></tr><tr><td>d</td><td>e</td><td>f</td></tr></table>|<table><tr><td rowspan=2 colspan=2 align="center">a</td><td>b</td><th>g</th></tr><tr><th rowspan=2>h</th><td>c</td></tr><tr><td>d</td><td>e</td><td>f</td></tr></table>
1208
+
1209
+ **removeTableRow**(y: number): TrToken<a id="tabletoken.removetablerow"></a>
1210
+ - 删除一行。
1211
+
1212
+ ```js
1213
+ var root = Parser.parse('{|\n|rowspan=2|a||b||c\n|-\n!rowspan=2 class="th"|d||e\n|-\n|f||g\n|}'),
1214
+ table = root.firstChild;
1215
+ table.removeTableRow(1);
1216
+ assert(root.toString() === '{|\n|a||b||c\n|-\n|f\n! class="th"|\n|g\n|}'); // 自动调整跨行单元格的 rowspan
1217
+ ```
1218
+
1219
+ |原表格|删除第 1 行|
1220
+ |:-:|:-:|
1221
+ |<table><tr><td rowspan=2>a</td><td>b</td><td>c</td></tr><tr><th rowspan=2>d</th><th>e</th></tr><tr><td>f</td><td>g</td></tr></table>|<table><tr><td>a</td><td>b</td><td>c</td></tr><tr><td>f</td><td></td><td>g</td></tr></table>|
1222
+
1223
+ **removeTableCol**(x: number): void<a id="tabletoken.removetablecol"></a>
1224
+ - 删除一列。
1225
+
1226
+ ```js
1227
+ var root = Parser.parse('{|\n|colspan=2|a||b\n|-\n|c\n!colspan=2 class="th"|d\n|-\n|e\n!f\n|g\n|}'),
1228
+ table = root.firstChild;
1229
+ table.removeTableCol(1);
1230
+ assert(root.toString() === '{|\n|a||b\n|-\n|c\n! class="th"|\n|-\n|e\n|g\n|}'); // 自动调整跨列单元格的 colspan
1231
+ ```
1232
+
1233
+ |原表格|删除第 1 列|
1234
+ |:-:|:-:|
1235
+ |<table><tr><td colspan=2 align="center">a</td><td>b</td></tr><tr><td>c</td><th colspan=2>d</th></tr><tr><td>e</td><th>f</th><td>g</td></tr></table>|<table><tr><td>a</td><td>b</td></tr><tr><th>c</th><th></th></tr><tr><td>e</td><td>g</td></tr></table>|
1236
+
1237
+ **mergeCells**(xlim: [number, number], ylim: [number, number]): [TdToken](#tdtoken)<a id="tabletoken.mergecells"></a>
1238
+ - 合并单元格。
1239
+
1240
+ ```js
1241
+ var root = Parser.parse('{|\n!a\n|b||c\n|-\n|d||e||f\n|-\n|g||h||i\n|}'),
1242
+ table = root.firstChild;
1243
+ table.mergeCells([0, 2], [0, 2]); // 被合并的单元格的属性和内部文本均会丢失
1244
+ assert(root.toString() === '{|\n! rowspan="2" colspan="2"|a\n|c\n|-\n|f\n|-\n|g||h||i\n|}');
1245
+ ```
1246
+
1247
+ |原表格|合并单元格|
1248
+ |:-:|:-:|
1249
+ |<table><tr><th>a</th><td>b</td><td>c</td></tr><tr><td>d</td><td>e</td><td>f</td></tr><tr><td>g</td><td>h</td><td>i</td></tr></table>|<table><tr><th rowspan=2 colspan=2>a</th><td>c</td></tr><tr><td>f</td></tr><tr><td>g</td><td>h</td><td>i</td></tr></table>|
1250
+
1251
+ **splitIntoRows**(coords: {row: number, column: number}\|{x: number, y: number}): void<a id="tabletoken.splitintorows"></a>
1252
+ - 将单元格分裂到不同行。
1253
+
1254
+ ```js
1255
+ var root = Parser.parse('{|\n|a||b\n!rowspan=3|c\n|-\n|d\n|-\n|e||f\n|}'),
1256
+ table = root.firstChild;
1257
+ table.splitIntoRows({x: 2, y: 0});
1258
+ assert(root.toString() === '{|\n|a||b\n!c\n|-\n|d\n|-\n|e||f\n!\n|}'); // 第 1 行由于缺失第 1 列的单元格,分裂后的第 2 列不会保留
1259
+ ```
1260
+
1261
+ |原表格|按行分裂单元格|
1262
+ |:-:|:-:|
1263
+ |<table><tr><td>a</td><td>b</td><th rowspan=3>c</th></tr><tr><td>d</td></tr><tr><td>e</td><td>f</td></tr></table>|<table><tr><td>a</td><td>b</td><th>c</th></tr><tr><td>d</td></tr><tr><td>e</td><td>f</td><th></th></tr></table>|
1264
+
1265
+ **splitIntoCols**(coords: {row: number, column: number}\|{x: number, y: number}): void<a id="tabletoken.splitintocols"></a>
1266
+ - 将单元格分裂到不同列。
1267
+
1268
+ ```js
1269
+ var root = Parser.parse('{|\n!colspan=2 class="th"|a\n|}'),
1270
+ table = root.firstChild;
1271
+ table.splitIntoCols({x: 1, y: 0});
1272
+ assert(root.toString() === '{|\n! class="th"|a\n! class="th"|\n|}'); // 分裂继承属性
1273
+ ```
1274
+
1275
+ |原表格|按列分裂单元格|
1276
+ |:-:|:-:|
1277
+ |<table><tr><th colspan=2>a</th></tr></table>|<table><tr><th>a</th><th>&nbsp;</th></tr></table>|
1278
+
1279
+ **splitIntoCells**(coords: {row: number, column: number}\|{x: number, y: number}): void<a id="tabletoken.splitintocells"></a>
1280
+ - 将单元格分裂成最小单元格。
1281
+
1282
+ ```js
1283
+ var root = Parser.parse('{|\n!rowspan=2 colspan=2|a\n|b\n|-\n|c\n|-\n|d||e||f\n|}'),
1284
+ table = root.firstChild;
1285
+ table.splitIntoCells({x: 0, y: 0});
1286
+ assert(root.toString() === '{|\n!a\n!\n|b\n|-\n!\n!\n|c\n|-\n|d||e||f\n|}');
1287
+ ```
1288
+
1289
+ |原表格|分裂单元格|
1290
+ |:-:|:-:|
1291
+ |<table><tr><th rowspan=2 colspan=2>a</th><td>b</td></tr><tr><td>c</td></tr><tr><td>d</td><td>e</td><td>f</td></tr></table>|<table><tr><th>a</th><th></th><td>b</td></tr><tr><th></th><th></th><td>c</td></tr><tr><td>d</td><td>e</td><td>f</td></tr></table>|
1292
+
1293
+ **replicateTableRow**(row: number): TrToken<a id="tabletoken.replicatetablerow"></a>
1294
+ - 复制一行并插入该行之前
1295
+
1296
+ ```js
1297
+ var root = Parser.parse('{|\n|rowspan=2|a||b||c\n|-\n!rowspan=2|d||e\n|-\n|f||g\n|}'),
1298
+ table = root.firstChild;
1299
+ table.replicateTableRow(1);
1300
+ assert(root.toString() === '{|\n| rowspan="3"|a||b||c\n|-\n!d||e\n|-\n!rowspan=2|d||e\n|-\n|f||g\n|}'); // 复制行内的单元格`rowspan`总是为1
1301
+ ```
1302
+
1303
+ |原表格|复制第 1 行|
1304
+ |:-:|:-:|
1305
+ |<table><tr><td rowspan=2>a</td><td>b</td><td>c</td></tr><tr><th rowspan=2>d</th><th>e</th></tr><tr><td>f</td><td>g</td></tr></table>|<table><tr><td rowspan=3>a</td><td>b</td><td>c</td></tr><tr><th>d</th><th>e</th></tr><tr><th rowspan=2>d</th><th>e</th></tr><tr><td>f</td><td>g</td></tr></table>|
1306
+
1307
+ **replicateTableCol**(x: number): [TdToken](#tdtoken)[]<a id="tabletoken.replicatetablecol"></a>
1308
+ - 复制一列并插入该列之前
1309
+
1310
+ ```js
1311
+ var root = Parser.parse('{|\n|colspan=2|a||b\n|-\n|c\n!colspan=2|d\n|-\n|e\n!f\n|g\n|}'),
1312
+ table = root.firstChild;
1313
+ table.replicateTableCol(1);
1314
+ assert(root.toString() === '{|\n| colspan="3"|a||b\n|-\n|c\n!d\n!colspan=2|d\n|-\n|e\n!f\n!f\n|g\n|}'); // 复制列内的单元格`colspan`总是为1
1315
+ ```
1316
+
1317
+ |原表格|复制第 1 列|
1318
+ |:-:|:-:|
1319
+ |<table><tr><td colspan=2 align="center">a</td><td>b</td></tr><tr><td>c</td><th colspan=2>d</th></tr><tr><td>e</td><th>f</th><td>g</td></tr></table>|<table><tr><td colspan=3 align="center">a</td><td>b</td></tr><tr><td>c</td><th>d</th><th colspan=2>d</th></tr><tr><td>e</td><th>f</th><th>f</th><td>g</td></tr></table>|
1320
+
1321
+ **moveTableRowBefore**(y: number, before: number): TrToken<a id="tabletoken.movetablerowbefore"></a>
1322
+ - 移动表格行。
1323
+
1324
+ ```js
1325
+ var root = Parser.parse('{|\n|rowspan=2|a||b||c||d\n|-\n|colspan=2|e||f\n|-\n|rowspan=2|g||h||i||j\n|-\n!rowspan=2|k||colspan=2|l\n|-\n|m||n||o\n|}'),
1326
+ table = root.firstChild;
1327
+ table.moveTableRowBefore(3, 1);
1328
+ assert(root.toString() === '{|\n| rowspan="3"|a||b||c||d\n|-\n!k||colspan=2|l\n|-\n|colspan=2|e||f\n|-\n|g||h||i||j\n|-\n|m\n!\n|n||o\n|}');
1329
+ ```
1330
+
1331
+ |原表格|移动第 3 行至第 1 行前|
1332
+ |:-:|:-:|
1333
+ |<table><tr><td rowspan=2>a</td><td>b</td><td>c</td><td>d</td></tr><tr><td colspan=2 align="center">e</td><td>f</td></tr><tr><td rowspan=2>g</td><td>h</td><td>i</td><td>j</td></tr><tr><th rowspan=2>k</th><th colspan=2>l</th></tr><tr><td>m</td><td>n</td><td>o</td></tr></table>|<table><tr><td rowspan=3>a</td><td>b</td><td>c</td><td>d</td></tr><tr><th>k</th><th colspan=2>l</th></tr><tr><td colspan=2 align="center">e</td><td>f</td></tr><tr><td>g</td><td>h</td><td>i</td><td>j</td></tr><tr><td>m</td><th></th><td>n</td><td>o</td></tr></table>|
1334
+
1335
+ **moveTableRowAfter**(y: number, after: number): TrToken<a id="tabletoken.movetablerowafter"></a>
1336
+ - 移动表格行。
1337
+
1338
+ ```js
1339
+ var root = Parser.parse('{|\n|rowspan=2|a||colspan=2|b||c\n|-\n|d||e||f\n|-\n|rowspan=2|g||h||i||j\n|-\n!rowspan=2|k||colspan=2|l\n|-\n|m||n||o\n|}'),
1340
+ table = root.firstChild;
1341
+ table.moveTableRowAfter(3, 0);
1342
+ assert(root.toString() === '{|\n| rowspan="3"|a||colspan=2|b||c\n|-\n!k||colspan=2|l\n|-\n|d||e||f\n|-\n|g||h||i||j\n|-\n|m\n!\n|n||o\n|}');
1343
+ ```
1344
+
1345
+ |原表格|移动第 3 行至第 0 行后|
1346
+ |:-:|:-:|
1347
+ |<table><tr><td rowspan=2>a</td><td colspan=2 align="center">b</td><td>c</td></tr><tr><td>d</td><td>e</td><td>f</td></tr><tr><td rowspan=2>g</td><td>h</td><td>i</td><td>j</td></tr><tr><th rowspan=2>k</th><th colspan=2>l</th></tr><tr><td>m</td><td>n</td><td>o</td></tr></table>|<table><tr><td rowspan=3>a</td><td colspan=2 align="center">b</td><td>c</td></tr><tr><th>k</th><th colspan=2>l</th></tr><tr><td>d</td><td>e</td><td>f</td></tr><tr><td>g</td><td>h</td><td>i</td><td>j</td></tr><tr><td>m</td><th></th><td>n</td><td>o</td></tr></table>|
1348
+
1349
+ **moveTableColBefore**(x: number, before: number): void<a id="tabletoken.movetablecolbefore"></a>
1350
+ - 移动表格列。
1351
+
1352
+ ```js
1353
+ var root = Parser.parse('{|\n|colspan=2|a||colspan=2|b||c\n|-\n|d||rowspan=2|e||f\n!colspan=2|g\n|-\n|h||i\n!rowspan=2|j\n|k\n|-\n|l||m||n||o\n|}'),
1354
+ table = root.firstChild;
1355
+ table.moveTableColBefore(3, 1);
1356
+ assert(root.toString() === '{|\n| colspan="3"|a||b||c\n|-\n|d\n!g\n|rowspan=2|e||f\n!\n|-\n|h\n!rowspan=2|j\n|i\n|k\n|-\n|l||m||n||o\n|}');
1357
+ ```
1358
+
1359
+ |原表格|移动第 3 列至第 1 列前|
1360
+ |:-:|:-:|
1361
+ |<table><tr><td colspan=2 align="center">a</td><td colspan=2 align="center">b</td><td>c</td></tr><tr><td>d</td><td rowspan=2>e</td><td>f</td><th colspan=2>g</th></tr><tr><td>h</td><td>i</td><th rowspan=2>j</th><td>k</td></tr><tr><td>l</td><td>m</td><td>n</td><td>o</td></tr></table>|<table><tr><td colspan=3 align="center">a</td><td>b</td><td>c</td></tr><tr><td>d</td><th>g</th><td rowspan=2>e</td><td>f</td><th></th></tr><tr><td>h</td><th rowspan=2>j</th><td>i</td><td>k</td></tr><tr><td>l</td><td>m</td><td>n</td><td>o</td></tr></table>|
1362
+
1363
+ **moveTableColAfter**(x: number, after: number): void<a id="tabletoken.movetablecolafter"></a>
1364
+ - 移动表格列。
1365
+
1366
+ ```js
1367
+ var root = Parser.parse('{|\n|colspan=2|a||colspan=2|b||c\n|-\n|rowspan=2|d||e||f\n!colspan=2|g\n|-\n|h||i\n!rowspan=2|j\n|k\n|-\n|l||m||n||o\n|}'),
1368
+ table = root.firstChild;
1369
+ table.moveTableColAfter(3, 0);
1370
+ assert(root.toString() === '{|\n| colspan="3"|a||b||c\n|-\n|rowspan=2|d\n!g\n|e||f\n!\n|-\n!rowspan=2|j\n|h||i\n|k\n|-\n|l||m||n||o\n|}');
1371
+ ```
1372
+
1373
+ |原表格|移动第 3 列至第 0 列后|
1374
+ |:-:|:-:|
1375
+ |<table><tr><td colspan=2 align="center">a</td><td colspan=2 align="center">b</td><td>c</td></tr><tr><td rowspan=2>d</td><td>e</td><td>f</td><th colspan=2>g</th></tr><tr><td>h</td><td>i</td><th rowspan=2>j</th><td>k</td></tr><tr><td>l</td><td>m</td><td>n</td><td>o</td></tr></table>|<table><tr><td colspan=3 align="center">a</td><td>b</td><td>c</td></tr><tr><td rowspan=2>d</td><th>g</th><td>e</td><td>f</td><th></th></tr><tr><th rowspan=2>j</th><td>h</td><td>i</td><td>k</td></tr><tr><td>l</td><td>m</td><td>n</td><td>o</td></tr></table>|
1376
+ </details>
1377
+
1378
+ [返回目录](#目录)
1379
+
1380
+ # TdToken
1381
+ 表格单元格。
1382
+
1383
+ ## 原型属性<a id="tdtoken.prototype.properties"></a>
1384
+ <details>
1385
+ <summary>展开</summary>
1386
+
1387
+ **subtype**: 'td'\|'th'\|'caption'<a id="tdtoken.subtype"></a>
1388
+
1389
+ ```js
1390
+ var root = Parser.parse('{|\n|+\n!\n|\n|}'),
1391
+ [caption, th, td] = root.querySelectorAll('td');
1392
+ assert(caption.subtype === 'caption');
1393
+ assert(th.subtype === 'th');
1394
+ assert(td.subtype === 'td');
1395
+ ```
1396
+
1397
+ **rowspan**: number<a id="tdtoken.rowspan"></a>
1398
+
1399
+ ```js
1400
+ var root = Parser.parse('{|\n|\n|}'),
1401
+ td = root.querySelector('td');
1402
+ assert(td.rowspan === 1);
1403
+ ```
1404
+
1405
+ **colspan**: number<a id="tdtoken.colspan"></a>
1406
+
1407
+ ```js
1408
+ var root = Parser.parse('{|\n|\n|}'),
1409
+ td = root.querySelector('td');
1410
+ assert(td.colspan === 1);
1411
+ ```
1412
+ </details>
1413
+
1414
+ [返回目录](#目录)
1415
+
1416
+ # DoubleUnderscoreToken
1417
+ 状态开关。
1418
+
1419
+ ## 实例属性<a id="doubleunderscoretoken.instance.properties"></a>
1420
+ <details>
1421
+ <summary>展开</summary>
1422
+
1423
+ **name**: string<a id="doubleunderscoretoken.name"></a>
1424
+ - 小写的状态开关名。
1425
+
1426
+ ```js
1427
+ var root = Parser.parse('__NOTOC__'),
1428
+ doubleUnderscore = root.firstChild;
1429
+ assert(doubleUnderscore.name === 'notoc');
1430
+ ```
1431
+ </details>
1432
+
1433
+ [返回目录](#目录)
1434
+
1435
+ # LinkToken
1436
+ 内链,包括跨维基链接。
1437
+
1438
+ ## 原型方法<a id="linktoken.prototype.methods"></a>
1439
+ <details>
1440
+ <summary>展开</summary>
1441
+
1442
+ **setTarget**(link: string): void<a id="linktoken.settarget"></a>
1443
+ - 修改内链目标。
1444
+
1445
+ ```js
1446
+ var root = Parser.parse('[[a]]'),
1447
+ link = root.firstChild;
1448
+ link.setTarget('b');
1449
+ assert(root.toString() === '[[:b]]'); // 自动在开头添加':'
1450
+ ```
1451
+
1452
+ **setFragment**(fragment: string): void<a id="linktoken.setfragment"></a>
1453
+ - 不改变目标页面,仅修改 fragment。
1454
+
1455
+ ```js
1456
+ var root = Parser.parse('[[:file:a]]'),
1457
+ link = root.firstChild;
1458
+ link.setFragment('b');
1459
+ assert(root.toString() === '[[:File:A#b]]'); // 这个方法会同时规范化页面名
1460
+ ```
1461
+
1462
+ **asSelfLink**(fragment?: string): void<a id="linktoken.asselflink"></a>
1463
+ - 当原链接带有或指定 fragment 时,将内链修改为 selfLink 格式。
1464
+
1465
+ ```js
1466
+ var root = Parser.parse('[[a#b]]'),
1467
+ link = root.firstChild;
1468
+ link.asSelfLink();
1469
+ assert(root.toString() === '[[#b]]');
1470
+ ```
1471
+
1472
+ **setLinkText**(linkText?: string)<a id="linktoken.setlinktext"></a>
1473
+ - 修改链接文本。
1474
+
1475
+ ```js
1476
+ var root = Parser.parse('[[a]]'),
1477
+ link = root.firstChild;
1478
+ link.setLinkText('b');
1479
+ assert(root.toString() === '[[a|b]]');
1480
+ link.removeAt(1); // 若要移除链接文本,直接使用removeAt方法即可
1481
+ assert(root.toString() === '[[a]]');
1482
+ ```
1483
+
1484
+ **pipeTrick**(): void<a id="linktoken.pipetrick"></a>
1485
+ - 模拟解析器预转换的 pipe trick。
1486
+
1487
+ ```js
1488
+ var root = Parser.parse('[[help:a (b)]]'),
1489
+ link = root.firstChild;
1490
+ link.pipeTrick();
1491
+ assert(root.toString() === '[[help:a (b)|a]]');
1492
+ ```
1493
+ </details>
1494
+
1495
+ ## 实例属性<a id="linktoken.instance.properties"></a>
1496
+ <details>
1497
+ <summary>展开</summary>
1498
+
1499
+ **name**: string<a id="linktoken.name"></a>
1500
+ - 规范化的目标页面名称。
1501
+
1502
+ ```js
1503
+ var root = Parser.parse('[[:文件:a]]'),
1504
+ link = root.firstChild;
1505
+ assert(link.name === 'File:A');
1506
+ ```
1507
+
1508
+ **selfLink**: boolean<a id="linktoken.selflink"></a>
1509
+ - 是否是 selfLink。
1510
+
1511
+ ```js
1512
+ var root = Parser.parse('[[#a]]'),
1513
+ link = root.firstChild;
1514
+ assert(link.selfLink === true);
1515
+ ```
1516
+
1517
+ **fragment**: string<a id="linktoken.fragment"></a>
1518
+ - URL 解码后的 fragment。
1519
+
1520
+ ```js
1521
+ var root = Parser.parse('[[#.7B.7D]]'), // 兼容 MediaWiki 式的 fragment 编码
1522
+ link = root.firstChild;
1523
+ assert(link.fragment === '{}');
1524
+ ```
1525
+
1526
+ **interwiki**: string<a id="linktoken.interwiki"></a>
1527
+ - 跨维基前缀。
1528
+
1529
+ ```js
1530
+ var root = Parser.parse('[[zhwiki:a]]'),
1531
+ link = root.firstChild;
1532
+ assert(link.interwiki === 'zhwiki');
1533
+ ```
1534
+ </details>
1535
+
1536
+ [返回目录](#目录)
1537
+
1538
+ # CategoryToken
1539
+ 分类。这个类继承了 [LinkToken](#linktoken) 类。
1540
+
1541
+ ## 原型方法<a id="categorytoken.prototype.methods"></a>
1542
+ <details>
1543
+ <summary>展开</summary>
1544
+
1545
+ **setSortkey**(text: string): void<a id="categorytoken.setsortkey"></a>
1546
+ - 修改分类关键字,实际上就是 [setLinkText](#linktoken.setlinktext) 方法的别名。
1547
+
1548
+ ```js
1549
+ var root = Parser.parse('[[category:a]]'),
1550
+ category = root.firstChild;
1551
+ category.setSortkey('*');
1552
+ assert(root.toString() === '[[category:a|*]]');
1553
+ ````
1554
+ </details>
1555
+
1556
+ ## 实例属性<a id="categorytoken.instance.properties"></a>
1557
+ <details>
1558
+ <summary>展开</summary>
1559
+
1560
+ **sortkey**: string<a id="categorytoken.sortkey"></a>
1561
+ - 分类关键字。
1562
+
1563
+ ```js
1564
+ var root = Parser.parse('[[category:a|*]]'),
1565
+ category = root.firstChild;
1566
+ assert(category.sortkey === '*');
1567
+ ```
1568
+ </details>
1569
+
1570
+ [返回目录](#目录)
1571
+
1572
+ # FileToken
1573
+ 文件。这个类继承了 [LinkToken](#linktoken) 类。
1574
+
1575
+ ## 原型方法<a id="filetoken.prototype.methods"></a>
1576
+ <details>
1577
+ <summary>展开</summary>
1578
+
1579
+ **getAllArgs**(): [ImageParameterToken](#imageparametertoken)[]<a id="filetoken.getallargs"></a>
1580
+ - 获取所有图片参数,类似 [TranscludeToken.getAllArgs](#transcludetoken.getallargs) 方法。
1581
+
1582
+ ```js
1583
+ var root = Parser.parse('[[file:a|thumb|1px|link=b|alt=c|d]]'),
1584
+ file = root.firstChild;
1585
+ assert.deepStrictEqual(file.getAllArgs(), file.children.slice(1));
1586
+ ```
1587
+
1588
+ **getArgs**(key: string): Set\<[ImageParameterToken](#imageparametertoken)><a id="filetoken.getargs"></a>
1589
+ - 获取指定的图片参数,类似 [TranscludeToken.getArgs](#transcludetoken.getargs) 方法。
1590
+
1591
+ ```js
1592
+ var root = Parser.parse('[[file:a|link=b|链接=c]]'), // 这里故意使用一个错误语法的例子,请勿模仿
1593
+ file = root.firstChild;
1594
+ assert.deepStrictEqual(file.getArgs('link'), new Set(file.children.slice(1)));
1595
+ ```
1596
+
1597
+ **hasArg**(key: string): boolean<a id="filetoken.hasarg"></a>
1598
+ - 是否带有指定的图片参数,类似 [TranscludeToken.hasArg](#transcludetoken.hasarg) 方法。
1599
+
1600
+ ```js
1601
+ var root = Parser.parse('[[file:a|b]]'),
1602
+ file = root.firstChild;
1603
+ assert(file.hasArg('caption') === true);
1604
+ ```
1605
+
1606
+ **getArg**(key: string): [ImageParameterToken](#imageparametertoken)<a id="filetoken.getarg"></a>
1607
+ - 获取最后一个指定的图片参数,类似 [TranscludeToken.getArg](#transcludetoken.getarg) 方法。
1608
+
1609
+ ```js
1610
+ var root = Parser.parse('[[file:a|link=b|链接=c]]'), // 这里故意使用一个错误语法的例子,请勿模仿
1611
+ file = root.firstChild;
1612
+ assert(file.getArg('link'), file.lastChild);
1613
+ ```
1614
+
1615
+ **removeArg**(key: string): void<a id="filetoken.removearg"></a>
1616
+ - 移除指定的图片参数,类似 [TranscludeToken.removeArg](#transcludetoken.removearg) 方法。
1617
+
1618
+ ```js
1619
+ var root = Parser.parse('[[file:a|link=b|链接=c]]'), // 这里故意使用一个错误语法的例子,请勿模仿
1620
+ file = root.firstChild;
1621
+ file.removeArg('link');
1622
+ assert(root.toString() === '[[file:a]]');
1623
+ ```
1624
+
1625
+ **getKeys**(): string[]<a id="filetoken.getkeys"></a>
1626
+ - 获取所有图片参数名,类似 [TranscludeToken.getKeys](#transcludetoken.getkeys) 方法。
1627
+
1628
+ ```js
1629
+ var root = Parser.parse('[[file:a|thumb|1px|link=b|alt=c|d]]'),
1630
+ file = root.firstChild;
1631
+ assert.deepStrictEqual(file.getKeys(), ['thumbnail', 'width', 'link', 'alt', 'caption']);
1632
+ ```
1633
+
1634
+ **getValue**(key: string): string\|true<a id="filetoken.getvalue"></a>
1635
+ - 获取指定的图片参数值,类似 [TranscludeToken.getValue](#transcludetoken.getvalue) 方法。
1636
+
1637
+ ```js
1638
+ var root = Parser.parse('[[file:a|thumb|100px]]'),
1639
+ file = root.firstChild;
1640
+ assert(file.getValue('thumbnail') === true);
1641
+ assert(file.getValue('width') === '100');
1642
+ ```
1643
+
1644
+ **setValue**(key: string, value: string\|boolean): void<a id="filetoken.setvalue"></a>
1645
+ - 修改或设置指定的图片参数,类似 [TranscludeToken.setValue](#transcludetoken.setvalue) 方法。
1646
+
1647
+ ```js
1648
+ var root = Parser.parse('[[file:a|thumb]]'),
1649
+ file = root.firstChild;
1650
+ file.setValue('thumbnail', false);
1651
+ file.setValue('width', '100');
1652
+ file.setValue('framed', true);
1653
+ assert(root.toString() === '[[file:a|100px|framed]]');
1654
+ ```
1655
+ </details>
1656
+
1657
+ [返回目录](#目录)
1658
+
1659
+ # ImageParameterToken
1660
+ 图片参数。
1661
+
1662
+ ## 原型方法<a id="imageparametertoken.prototype.methods"></a>
1663
+ <details>
1664
+ <summary>展开</summary>
1665
+
1666
+ **getValue**(): string\|true<a id="imageparametertoken.getvalue"></a>
1667
+ - 获取图片参数值,类似 [ParameterToken.getValue](#parametertoken.getvalue) 方法。
1668
+
1669
+ ```js
1670
+ var root = Parser.parse('[[file:a|thumb|100px]]'),
1671
+ [thumbnail, width] = root.querySelectorAll('image-parameter');
1672
+ assert(thumbnail.getValue() === true);
1673
+ assert(width.getValue() === '100');
1674
+ ```
1675
+
1676
+ **setValue**(value: string\|boolean): void<a id="imageparametertoken.setvalue"></a>
1677
+ - 修改或移除图片参数,类似 [ParameterToken.setValue](#parametertoken.setvalue) 方法。
1678
+
1679
+ ```js
1680
+ var root = Parser.parse('[[file:a|thumb|100px]]'),
1681
+ [thumbnail, width] = root.querySelectorAll('image-parameter');
1682
+ thumbnail.setValue(false);
1683
+ width.setValue('x100');
1684
+ assert(root.toString() === '[[file:a|x100px]]');
1685
+ ```
1686
+ </details>
1687
+
1688
+ [返回目录](#目录)
1689
+
1690
+ # ExtLinkToken
1691
+ `[]`内的外部链接。
1692
+
1693
+ ## 原型方法<a id="extlinktoken.prototype.methods"></a>
1694
+ <details>
1695
+ <summary>展开</summary>
1696
+
1697
+ **getUrl**(): URL<a id="extlinktoken.geturl"></a>
1698
+ - 混合自 [MagicLinkToken.getUrl](#magiclinktoken.geturl)。
1699
+
1700
+ **setTarget**(url: string\|URL): void<a id="extlinktoken.settarget"></a>
1701
+ - 混合自 [MagicLinkToken.setTarget](#magiclinktoken.settarget)。
1702
+
1703
+ **setLinkText**(text: string): void<a id="extlinktoken.setlinktext"></a>
1704
+ - 修改外链文本。
1705
+
1706
+ ```js
1707
+ var root = Parser.parse('[//example.org example]'),
1708
+ extlink = root.firstChild;
1709
+ extlink.setLinkText(''); // 清空外链文本
1710
+ assert(root.toString() === '[//example.org]');
1711
+ ```
1712
+ </details>
1713
+
1714
+ ## 原型属性<a id="extlinktoken.prototype.properties"></a>
1715
+ <details>
1716
+ <summary>展开</summary>
1717
+
1718
+ **protocol**: string<a id="extlinktoken.protocol"></a>
1719
+ - 混合自 [MagicLinkToken.protocol](#magiclinktoken.protocol)。
1720
+ </details>
1721
+
1722
+ [返回目录](#目录)
1723
+
1724
+ # MagicLinkToken
1725
+ 自由外链。
1726
+
1727
+ ## 原型方法<a id="magiclinktoken.prototype.methods"></a>
1728
+ <details>
1729
+ <summary>展开</summary>
1730
+
1731
+ **getUrl**(): URL<a id="magiclinktoken.geturl"></a>
1732
+ - 生成一个 URL 对象,以方便解析和修改外链目标。
1733
+
1734
+ **setTarget**(url: string\|URL): void<a id="magiclinktoken.settarget"></a>
1735
+ - 修改外链目标。可以和 [getUrl](#magiclinktoken.geturl) 方法联合使用(见以下示例)。
1736
+
1737
+ ```js
1738
+ var root = Parser.parse('https://www.mediawiki.org/wiki/Manual:Parser.php'),
1739
+ magiclink = root.firstChild,
1740
+ url = magiclink.getUrl();
1741
+ url.searchParams.set('action', 'info');
1742
+ magiclink.setTarget(url);
1743
+ assert(root.toString() === 'https://www.mediawiki.org/wiki/Manual:Parser.php?action=info');
1744
+ ```
1745
+ </details>
1746
+
1747
+ ## 原型属性<a id="magiclinktoken.prototype.properties"></a>
1748
+ <details>
1749
+ <summary>展开</summary>
1750
+
1751
+ **protocol**: string<a id="magiclinktoken.protocol"></a>
1752
+ - 外链协议。
1753
+
1754
+ ```js
1755
+ var root = Parser.parse('ftp://example.org'),
1756
+ magiclink = root.firstChild;
1757
+ assert(magiclink.protocol === 'ftp://');
1758
+ magiclink.protocol = 'https://';
1759
+ assert(root.toString() === 'https://example.org');
1760
+ ```
1761
+ </details>
1762
+
1763
+ [返回目录](#目录)
1764
+
1765
+ # 选择器
1766
+ Token 选择器的设计仿照了 CSS 和 jQuery 的选择器。
1767
+ <details>
1768
+ <summary>展开</summary>
1769
+
1770
+ **type**<a id="selector.type"></a>
1771
+ - 类比 CSS tag 选择器。
1772
+
1773
+ ```js
1774
+ var root = Parser.parse(wikitext);
1775
+ assert(root.matches('root') === true)
1776
+ ```
1777
+
1778
+ **name**<a id="selector.name"></a>
1779
+ - 类比 CSS id 选择器。
1780
+
1781
+ ```js
1782
+ var root = Parser.parse('<ref/>'),
1783
+ ref = root.firstChild;
1784
+ assert(ref.matches('#ref') === true);
1785
+ ```
1786
+
1787
+ **属性**<a id="selector.attribute"></a>
1788
+ - 类比 CSS 属性选择器。
1789
+
1790
+ ```js
1791
+ var root = Parser.parse('<!-- --><ref name="abc"/>'),
1792
+ comment = root.firstChild,
1793
+ attr = root.querySelector('ext-attr');
1794
+ assert(comment.matches('[closed]') === true); // 非 AttributeToken 的属性选择器对应自身属性
1795
+ assert(attr.matches('[name^=a]') === true); // AttributeToken 的属性选择器对应维基文本中的属性
1796
+ assert(attr.matches('[name$=c]') === true);
1797
+ assert(attr.matches('[name*=b]') === true);
1798
+ assert(attr.matches('[name!=x]') === true);
1799
+ assert(attr.matches('[name=abc]') === true);
1800
+ ```
1801
+
1802
+ **伪选择器**<a id="selector.pseudo"></a>
1803
+ - 类比 CSS 和 jQuery 伪选择器。
1804
+
1805
+ ```js
1806
+ var root = Parser.parse('text <!--'),
1807
+ comment = root.lastChild;
1808
+ assert(root.matches(':root') === true);
1809
+ assert(root.matches(':is(root)') === true);
1810
+ assert(comment.matches(':not(root)') === true);
1811
+ assert(comment.matches(':nth-child(2)') === true);
1812
+ assert(comment.matches(':nth-last-of-type(1)') === true);
1813
+ assert(comment.matches(':last-child') === true);
1814
+ assert(comment.matches(':first-of-type') === true);
1815
+ assert(root.matches(':only-child') === true);
1816
+ assert(comment.matches(':only-of-type') === true);
1817
+ assert(root.matches(':contains(text)') === true);
1818
+ assert(root.matches(':has(comment)') === true);
1819
+ assert(root.matches(':parent') === true);
1820
+ assert(comment.matches(':empty') === true);
1821
+ assert(comment.matches(':hidden') === true);
1822
+ assert(root.matches(':visible') === true);
1823
+ ```
1824
+ </details>
1825
+
1826
+ [返回目录](#目录)
1827
+
1828
+ # $ (TokenCollection)
1829
+ 这是一个仿 jQuery 的批量操作工具,这里仅列举方法和属性。
1830
+ <details>
1831
+ <summary>展开</summary>
1832
+
1833
+ **toArray**(): (string\|Token)[]
1834
+ **get**(num: number): string\|Token
1835
+ **each**(callback: function(this: string\|Token, number, string\|Token): void): this
1836
+ **map**(callback: function(this: string\|Token, number, string\|Token): any): any[]\|TokenCollection
1837
+ **slice**(start: number, end: number): TokenCollection
1838
+ **first**(): TokenCollection
1839
+ **last**(): TokenCollection
1840
+ **eq**(i: number): TokenCollection
1841
+ **toString**(): string
1842
+ **text**(text?: string): string\|this
1843
+ **is**(selector: string): boolean
1844
+ **filter**(selector: string\|function(this: string\|Token, number, string\|Token): boolean): TokenCollection
1845
+ **not**(selector: string\|function(this: string\|Token, number, string\|Token): boolean): TokenCollection
1846
+ **find**(selector: string): TokenCollection
1847
+ **has**(selector: string): boolean
1848
+ **closest**(selector?: string): TokenCollection
1849
+ **index**(): number
1850
+ **add**(elements: string\|Token\|TokenCollection\|(string\|Token)[]): TokenCollection
1851
+ **addBack**(selector?: string): TokenCollection
1852
+ **parent**(selector?: string): TokenCollection
1853
+ **parents**(selector?: string): TokenCollection
1854
+ **parentsUntil**(selector?: string, filter?: string): TokenCollection
1855
+ **next**(selector?: string): TokenCollection
1856
+ **nextAll**(selector?: string): TokenCollection
1857
+ **nextUntil**(selector?: string, filter?: string): TokenCollection
1858
+ **prev**(selector?: string): TokenCollection
1859
+ **prevAll**(selector?: string): TokenCollection
1860
+ **prevUntil**(selector?: string, filter?: string): TokenCollection
1861
+ **siblings**(selector?: string): TokenCollection
1862
+ **children**(selector?: string): TokenCollection
1863
+ **contents**(): TokenCollection
1864
+ **data**(key: string\|Record\<string, any>, value?: any): this\|any
1865
+ **removeData**(name: string\|string[]): this
1866
+ **on**(events: string\|Record\<string, (e: Event, data: any) => any, [selector: string], handler: (e: Event, data: any) => any): this
1867
+ **one**(events: string\|Record\<string, (e: Event, data: any) => any, [selector: string], handler: (e: Event, data: any) => any): this
1868
+ **off**(events: string\|Record\<string, (e: Event, data: any) => any, [selector: string], [handler: (e: Event, data: any) => any]): this
1869
+ **trigger**(event: Event, data?: any): this
1870
+ **tiggerHandler**(event: Event, data?: any): any
1871
+ **append**(content: string\|Token\|TokenCollection\|(string\|Token)[]\|function(this: Token, number, string): string\|Token\|TokenCollection\|(string\|Token)[]): this
1872
+ **prepend**(content: string\|Token\|TokenCollection\|(string\|Token)[]\|function(this: Token, number, string): string\|Token\|TokenCollection\|(string\|Token)[]): this
1873
+ **before**(content: string\|Token\|TokenCollection\|(string\|Token)[]\|function(this: Token, number, string): string\|Token\|TokenCollection\|(string\|Token)[]): this
1874
+ **after**(content: string\|Token\|TokenCollection\|(string\|Token)[]\|function(this: Token, number, string): string\|Token\|TokenCollection\|(string\|Token)[]): this
1875
+ **html**(content: string\|Token\|TokenCollection\|(string\|Token)[]\|function(this: Token, number, string): string\|Token\|TokenCollection\|(string\|Token)[]): this
1876
+ **replaceWith**(content: string\|Token\|TokenCollection\|(string\|Token)[]\|function(this: Token, number, string): string\|Token\|TokenCollection\|(string\|Token)[]): this
1877
+ **remove**(selector?: string): this
1878
+ **detach**(selector?: string): this
1879
+ **empty**(): this
1880
+ **appendTo**(target: Token\|Token[]): this
1881
+ **prependTo**(target: Token\|Token[]): this
1882
+ **insertBefore**(target: Token\|Token[]): this
1883
+ **insertAfter**(target: Token\|Token[]): this
1884
+ **replaceAll**(target: Token\|Token[]): this
1885
+ **val**(value: string\|string[]\|function(this: Token, number, string): string): this
1886
+ **attr**(name: string\|Record\<string, string>, value?: string): this\|string
1887
+ **removeAttr**(name: string): this
1888
+ **prop**(name: string\|Record\<string, any>, value?: any): this\|any
1889
+ **removeProp**(name: string): this
1890
+ **wrapAll**(wrapper: string[]\|function(this: Token, string): string[]): this
1891
+ **wrapInner**(wrapper: string[]\|function(this: Token, string): string[]): this
1892
+ **wrap**(wrapper: string[]\|function(this: Token, string): string[]): this
1893
+
1894
+ </details>
1895
+
1896
+ [返回目录](#目录)