Token - bhsd-harry/wikiparser-node GitHub Wiki
目录
这是所有特定维基语法对应节点的父类。Token 类的父类 AstElement 是仿照 HTMLElement 类设计的。本页面仅介绍 Token 类新增的属性和方法。
从 AstElement 继承的属性
- childElementCount
- children
- clientHeight
- clientWidth
- embeds
- firstElementChild
- hidden
- images
- lastElementChild
- length ✅
- links
- outerText
- parentElement
从 AstNode 继承的属性
- bold
- childNodes ✅
- eof
- firstChild ✅
- font
- isConnected
- italic
- lastChild ✅
- nextElementSibling
- nextSibling ✅
- nextVisibleSibling
- offsetHeight ✅
- offsetLeft
- offsetTop
- offsetWidth ✅
- parentNode ✅
- previousElementSibling
- previousSibling ✅
- previousVisibleSibling
- style
✅ 展开
加入的版本:1.29.0
type: string | undefined
与节点关联的页面名称。如果未设置页面名称则为 undefined。
// pageName
var root = Parser.parse('');
assert.strictEqual(root.pageName, undefined);
root.pageName = 'help:wiki parser#fragment';
assert.strictEqual(root.pageName, 'Help:Wiki_parser');
root.pageName = '|';
assert.strictEqual(root.pageName, undefined);
root.pageName = '';
assert.strictEqual(root.pageName, '');
root.pageName = undefined;
assert.strictEqual(root.pageName, undefined);✅ 展开
type: string
节点类型。
// type
var root = Parser.parse('');
assert.strictEqual(root.type, 'root');
root.type = 'plain';
assert.strictEqual(root.type, 'plain');从 AstElement 继承的方法
- append ✅
- caretPositionFromIndex ✅
- caretPositionFromPoint
- closest ✅
- elementFromIndex ✅
- elementFromPoint ✅
- elementsFromIndex
- elementsFromPoint
- getElementById
- getElementByTypes
- getElementsByClassName
- getElementsByTagName
- insertAt ✅
- insertBefore
- json 🌐
- matches
- normalize
- prepend
- print 🌐
- querySelector ✅
- querySelectorAll ✅
- removeAt ✅
- removeChild
- replaceChildren
- setText ✅
- text ✅
从 AstNode 继承的方法
- addEventListener
- after
- before
- compareDocumentPosition
- contains
- destroy
- dispatchEvent
- getAbsoluteIndex ✅
- getAncestors
- getLine
- getLines ✅
- getRelativeIndex ✅
- getRootNode ✅
- indexFromPos ✅
- is ✅
- isEqualNode
- listEventListeners
- posFromIndex ✅
- remove
- removeAllEventListeners
- removeEventListener
- replaceWith
展开
加入的版本:1.17.1
构建所有 list-range 节点。
// buildLists (main)
var root = Parser.parse(';*#;a:b:c');
root.buildLists();
assert.deepStrictEqual(root.json(), {
range: [0, 9],
type: 'root',
childNodes: [
{
range: [0, 3],
type: 'list',
childNodes: [
{
range: [0, 3],
data: ';*#',
},
],
},
{
range: [3, 7],
type: 'list-range',
childNodes: [
{
range: [3, 4],
type: 'list',
childNodes: [
{
range: [3, 4],
data: ';',
},
],
},
{
range: [4, 5],
type: 'list-range',
childNodes: [
{
range: [4, 5],
data: 'a',
},
],
},
{
range: [5, 6],
type: 'dd',
indent: 1,
childNodes: [
{
range: [5, 6],
data: ':',
},
],
},
{
range: [6, 7],
type: 'list-range',
childNodes: [
{
range: [6, 7],
data: 'b',
},
],
},
],
},
{
range: [7, 8],
type: 'dd',
indent: 1,
childNodes: [
{
range: [7, 8],
data: ':',
},
],
},
{
range: [8, 9],
type: 'list-range',
childNodes: [
{
range: [8, 9],
data: 'c',
},
],
},
],
});展开
returns: this
深拷贝节点。不同类型的节点采用了不同的深拷贝算法。
// cloneNode (main)
var token = Parser.parse('<ref>a[[b]]</ref>').querySelector('ext-inner'),
cloned;
token.pageName = 'A';
cloned = token.cloneNode();
assert.strictEqual(cloned.type, token.type);
assert.strictEqual(cloned.name, token.name);
assert.strictEqual(cloned.pageName, token.pageName);
assert.deepStrictEqual(cloned, token);展开
param: string 注释内容
returns: CommentToken
生成一个 HTML 注释。
// createComment (main)
var root = Parser.parse('');
assert.equal(root.createComment('a-->'), '<!--a-->-->');
assert.equal(root.createComment(), '<!---->');展开
param: string 标签名
param: {closing?: boolean, selfClosing?: boolean} 选项
returns: Token
生成一个 HTML 标签或扩展标签。
// createElement (main)
var root = Parser.parse('');
assert.equal(
root.createElement('includeonly'),
'<includeonly></includeonly>',
);
assert.equal(
root.createElement('includeonly', {selfClosing: true}),
'<includeonly/>',
);
assert.equal(
root.createElement('REF'),
'<ref></ref>',
);
assert.equal(
root.createElement('ref', {selfClosing: true}),
'<ref/>',
);
assert.equal(
root.createElement('li'),
'<li>',
);
assert.equal(
root.createElement('li', {closing: true}),
'</li>',
);
assert.equal(
root.createElement('li', {selfClosing: true}),
'<li/>',
);展开
returns: AstRange
生成一个 AstRange 对象。
// createRange (main)
var root = Parser.parse('text'),
{firstChild} = root,
range = root.createRange();
range.setStart(firstChild, 1);
range.setEnd(firstChild, 3);
assert.equal(range, 'ex');展开
param: string
returns: AstText
生成一个纯文本节点。
// createTextNode (main)
var root = Parser.parse(''),
text = root.createTextNode('a');
assert.strictEqual(text.type, 'text');
assert.strictEqual(text.data, 'a');
text = root.createTextNode();
assert.strictEqual(text.type, 'text');
assert.strictEqual(text.data, '');展开
加入的版本:1.10.0
returns: Token
展开模板和部分魔术字。
// expand (main)
var root, copy;
Parser.templates.set(
'Template:Link_start',
`[[{{{1|<noinclude>Template:Link start]]</noinclude>}}}<noinclude>
{{doc}}</noinclude>`,
);
root = Parser.parse('{{link start|a}}b|c]]');
copy = root.expand();
assert.deepStrictEqual(copy.childNodes.map(({type}) => type), ['link']);
assert.equal(copy, '[[ab|c]]');展开
param: string HTML 标签名(可省略)
returns: AstRange | undefined
获取指定的外层HTML标签。注意纯文本节点无法使用此方法。
// findEnclosingHtml (main)
var root = Parser.parse('<p><b><li/><br><i>{{{|[[a]]}}}</b></p>'),
arg = root.querySelector('arg'),
link = arg.querySelector('link');
assert.equal(arg, '{{{|[[a]]}}}');
assert.equal(link, '[[a]]');
assert.strictEqual(root.findEnclosingHtml(), undefined);
assert.equal(
arg.findEnclosingHtml(),
'<b><li/><br><i>{{{|[[a]]}}}</b>',
);
assert.equal(
arg.findEnclosingHtml('p'),
'<p><b><li/><br><i>{{{|[[a]]}}}</b></p>',
);
assert.equal(
link.findEnclosingHtml(),
'<b><li/><br><i>{{{|[[a]]}}}</b>',
);
assert.equal(
link.findEnclosingHtml('p'),
'<p><b><li/><br><i>{{{|[[a]]}}}</b></p>',
);展开
合并普通节点的普通子节点。
// flatten (main)
var root = Parser.parse(''),
plain = Parser.parse('a'),
{firstChild} = plain;
root.append(plain);
root.flatten();
assert.strictEqual(root.lastChild, firstChild);展开
returns: [string, string | undefined][]
获取全部分类及其排序关键词。
// getCategories (main)
assert.deepStrictEqual(
Parser.parse([[category:a]][[category:b|c]]').getCategories(),
[
['Category:A', undefined],
['Category:B', 'c'],
],
);展开
param: string 链接标题
returns: RegExpExecArray | null
类似 Parser.isInterwiki 方法,但使用与当前节点相同的解析设置。
✅ 展开
returns: LintError[]
报告潜在语法错误。
// lint
var root = Parser.parse(`<br id=a>
<pre id=a/>
{|id=a
|}`);
assert.deepStrictEqual(root.lint(), [
{
rule: 'no-duplicate',
severity: 'warning',
message: 'duplicate HTML id',
startLine: 0,
startCol: 4,
startIndex: 4,
endLine: 0,
endCol: 8,
endIndex: 8,
},
{
rule: 'no-duplicate',
severity: 'warning',
message: 'duplicate HTML id',
startLine: 1,
startCol: 5,
startIndex: 15,
endLine: 1,
endCol: 9,
endIndex: 19,
},
{
rule: 'no-duplicate',
severity: 'warning',
message: 'duplicate HTML id',
startLine: 2,
startCol: 2,
startIndex: 24,
endLine: 2,
endCol: 6,
endIndex: 28,
},
]);
root = Parser.parse([[category:a]][[category:a|b]]');
assert.deepStrictEqual(root.lint(), [
{
rule: 'no-duplicate',
severity: 'warning',
message: 'duplicate category',
startLine: 0,
startCol: 0,
startIndex: 0,
endLine: 0,
endCol: 14,
endIndex: 14,
suggestions: [
{
range: [0, 14],
text: '',
desc: 'remove',
},
],
},
{
rule: 'no-duplicate',
severity: 'warning',
message: 'duplicate category',
startLine: 0,
startCol: 14,
startIndex: 14,
endLine: 0,
endCol: 30,
endIndex: 30,
suggestions: [
{
range: [14, 30],
text: '',
desc: 'remove',
},
],
},
]);
root = Parser.parse(`<!-- lint-disable no-duplicate -->
[[category:a]][[category:a]]
<!-- lint-enable no-duplicate -->
<a> <!-- lint-disable-line -->
<!-- lint-disable-next-line no-duplicate, tag-like -->
[[category:a]][[category:a]]<a>`);
assert.deepStrictEqual(root.lint(), []);
Parser.lintConfig = {computeEditInfo: false};
root = Parser.parse([[category:a]][[category:a]]');
assert.deepStrictEqual(root.lint(), [
{
rule: 'no-duplicate',
severity: 'warning',
message: 'duplicate category',
startLine: 0,
startCol: 0,
startIndex: 0,
endLine: 0,
endCol: 14,
endIndex: 14,
},
{
rule: 'no-duplicate',
severity: 'warning',
message: 'duplicate category',
startLine: 0,
startCol: 14,
startIndex: 14,
endLine: 0,
endCol: 28,
endIndex: 28,
},
]);
Parser.lintConfig = {fix: true};
root = Parser.parse('</br>');
assert.strictEqual(root.lint().output, '<br>');✅ 展开
param: string 标题(含或不含命名空间前缀)
param: number 命名空间,默认为 0
returns: Title
规范化页面标题。
// normalizeTitle
var root = Parser.parse(''),
title;
root.pageName = 'Help:A/1';
title = root.normalizeTitle('../2');
assert.strictEqual(title.title, 'Help:A/2');展开
param: this 待替换的节点
一些具有特殊语法作用的节点只能使用这个方法替换为同类节点。注意需要使用这个方法的场合一般也需要搭配 AstNode.prototype.destroy 方法。
// safeReplaceWith (main)
var {firstChild, lastChild: {lastChild}} = Parser.parse('<p><p lang="zh">'),
attrs = lastChild.cloneNode(),
error;
assert.equal(firstChild, '<p>');
assert.equal(lastChild, ' lang="zh"');
assert.equal(attrs, ' lang="zh"');
try {
firstChild.lastChild.replaceWith(attrs);
} catch (e) {
error = e;
}
assert.ok(error instanceof Error);
assert.equal(error.message, 'HtmlToken cannot insert child nodes!');
firstChild.lastChild.safeReplaceWith(attrs);展开
param: number 章节序号
returns: AstRange
获取指定章节。只可用于根节点。
// section (main)
var root = Parser.parse('a\n==1==\nb\n===2===\nc\n==3==\nd');
assert.equal(root.section(0), 'a\n');
assert.equal(root.section(1), '==1==\nb\n===2===\nc\n');
assert.equal(root.section(2), '===2===\nc\n');
assert.equal(root.section(3), '==3==\nd');
root = Parser.parse('a');
assert.equal(root.section(0), 'a');展开
returns: AstRange[]
获取全部章节(含序言),每个章节均是一个数组。只可用于根节点。
// sections (main)
var root = Parser.parse('a\n==1==\nb\n===2===\nc\n==3==\nd'),
[s0, s1, s2, s3] = root.sections();
assert.equal(s0, 'a\n');
assert.equal(s1, '==1==\nb\n===2===\nc\n');
assert.equal(s2, '===2===\nc\n');
assert.equal(s3, '==3==\nd');
root = Parser.parse('a');
[s0] = root.sections();
assert.equal(s0, 'a');展开
returns: Token
解析参变量和部分魔术字。
// solveConst (main)
var root = Parser.parse(
`{{{null}}}{{{|[[a]]}}}{{#if:||[//b]}}{{#switch:|#default={{c}}}}{{#switch:d|d|e=}}`,
),
copy = root.solveConst();
assert.deepStrictEqual(
copy.childNodes.map(({type}) => type),
['text', 'link', 'ext-link', 'template'],
);
assert.deepStrictEqual(
copy.childNodes.map(String),
['{{{null}}}', '[[a]]', '[//b]', '{{c}}'],
);展开
加入的版本:1.10.0
param: boolean 是否禁用换行
returns: string
转换为 HTML。
// toHtml (main)
var root = Parser.parse(`a
<!-- -->
b
[[category:1]] [[category:2]]
[[category:3]]
c`);
root.type = 'plain';
assert.strictEqual(
root.toHtml(),
'a\n\nb\n\nc',
);
Parser.templates.set('Template:Dt', ';');
root = Parser.parse('a\n\nb{{dt}}{{dt}}c:d');
assert.strictEqual(
root.toHtml(),
'<p>a\n</p><p>b\n</p>\n<dl><dt></dt>\n<dt>c</dt>\n<dd>d</dd></dl>',
);