-
Notifications
You must be signed in to change notification settings - Fork 2
Selector (EN)
Bhsd edited this page Nov 30, 2024
·
14 revisions
Table of Contents
The design of Token selector is inspired by CSS and jQuery.
✅ Available in the Mini and Browser versions.
✅ Expand
Similar to CSS tag name selector.
// type
var root = Parser.parse([[a]]{{{b}}}'),
{firstChild, lastChild} = root;
assert.equal(firstChild, '[[a]]');
assert.equal(lastChild, '{{{b}}}');
assert.deepStrictEqual(
root.querySelectorAll('link, arg'),
[firstChild, lastChild],
);
✅ Expand
Similar to CSS id selector.
// name
var root = Parser.parse('<ref/><poem/>'),
{firstChild} = root;
assert.equal(firstChild, '<ref/>');
assert.deepStrictEqual(root.querySelectorAll('ext#ref'), [firstChild]);
Expand
Similar to CSS attribute selector.
// attribute (main)
var root = Parser.parse('<p id="ab-c" class="c1 c2" style="top:0"/>'),
{firstChild} = root,
attrs = firstChild.firstChild;
assert.equal(firstChild, '<p id="ab-c" class="c1 c2" style="top:0"/>');
assert.equal(attrs, ' id="ab-c" class="c1 c2" style="top:0"');
assert.deepStrictEqual(root.querySelectorAll('[selfClosing]'), [firstChild]);
assert.deepStrictEqual(root.querySelectorAll('[id^=A i]'), [firstChild, attrs]);
assert.deepStrictEqual(root.querySelectorAll('[id$=C i]'), [firstChild, attrs]);
assert.deepStrictEqual(
root.querySelectorAll('html[style*=TOP i]'),
[firstChild],
);
assert(firstChild.matches('[name!=P]'));
assert.deepStrictEqual(
root.querySelectorAll('[name=P i]'),
[firstChild, attrs],
);
assert.deepStrictEqual(
root.querySelectorAll('[id|=AB i]'),
[firstChild, attrs],
);
assert.deepStrictEqual(
root.querySelectorAll('[class~=C1 i]'),
[firstChild, attrs],
);
Similar to CSS combinator.
Expand
// descendant combinator (main)
var root = Parser.parse('<poem>{{a}}</poem>{{b}}'),
template = root.querySelector('template');
assert.equal(template, '{{a}}');
assert.deepStrictEqual(root.querySelectorAll('ext template'), [template]);
Expand
// child combinator (main)
var root = Parser.parse('<poem>{{a}}</poem>{{b}}'),
template = root.querySelector('template');
assert.equal(template, '{{a}}');
assert.deepStrictEqual(
root.querySelectorAll('root > ext > ext-inner > template'),
[template],
);
Expand
// subsequent-sibling combinator (main)
var root = Parser.parse('<poem>[[a]]{{b}}</poem>{{c}}'),
template = root.querySelector('template');
assert.equal(template, '{{b}}');
assert.deepStrictEqual(root.querySelectorAll('link ~ template'), [template]);
Expand
// next-sibling combinator (main)
var root = Parser.parse('<poem>[[a]]{{{b}}}{{c}}</poem>{{d}}'),
template = root.querySelector('template');
assert.equal(template, '{{c}}');
assert.deepStrictEqual(
root.querySelectorAll('link + arg + template'),
[template],
);
Similar to CSS and jQuery pseudo selector.
Expand
// root (main)
var root = Parser.parse('');
assert(root.matches(':root'));
Expand
// first-child (main)
var root = Parser.parse('a<ref/>[[b]]'),
{firstElementChild} = root;
assert.equal(firstElementChild, '<ref/>');
assert.deepStrictEqual(
root.querySelectorAll('root > :first-child'),
[firstElementChild],
);
Expand
// first-of-type (main)
var root = Parser.parse('a<ref/>[[b]]'),
{firstElementChild, lastChild} = root;
assert.equal(firstElementChild, '<ref/>');
assert.equal(lastChild, '[[b]]');
assert.deepStrictEqual(
root.querySelectorAll('root > :first-of-type'),
[firstElementChild, lastChild],
);
Expand
// last-child (main)
var root = Parser.parse('<ref/>a'),
{firstChild} = root;
assert.equal(firstChild, '<ref/>');
assert.deepStrictEqual(
root.querySelectorAll('root > :last-child'),
[firstChild],
);
Expand
// last-of-type (main)
var root = Parser.parse('<ref/>[[a]]'),
{firstChild, lastChild} = root;
assert.equal(firstChild, '<ref/>');
assert.equal(lastChild, '[[a]]');
assert.deepStrictEqual(
root.querySelectorAll('root > :last-of-type'),
[firstChild, lastChild],
);
Expand
// only-child (main)
var root = Parser.parse('<ref/>a'),
{firstChild} = root;
assert.equal(firstChild, '<ref/>');
assert.deepStrictEqual(
root.querySelectorAll('root > :only-child'),
[firstChild],
);
Expand
// only-of-type (main)
var root = Parser.parse('<ref/>[[a]]'),
{firstChild, lastChild} = root;
assert.equal(firstChild, '<ref/>');
assert.equal(lastChild, '[[a]]');
assert.deepStrictEqual(
root.querySelectorAll('root > :only-of-type'),
[firstChild, lastChild],
);
Expand
// empty (main)
var root = Parser.parse('<!---->'),
{firstChild} = root;
assert.deepStrictEqual(root.querySelectorAll(':empty'), [firstChild]);
Expand
// parent (main)
var root = Parser.parse('<!-- -->'),
{firstChild} = root;
assert.deepStrictEqual(root.querySelectorAll(':parent'), [firstChild]);
Expand
// header (main)
var root = Parser.parse('==a=='),
{firstChild} = root;
assert.deepStrictEqual(root.querySelectorAll(':header'), [firstChild]);
Expand
// hidden (main)
var root = Parser.parse('<!-- -->__nocc__'),
{firstChild, lastChild} = root;
assert.equal(firstChild, '<!-- -->');
assert.equal(lastChild, '__nocc__');
assert(root.matches(':hidden'));
assert.deepStrictEqual(
root.querySelectorAll(':hidden'),
[firstChild, lastChild],
);
展开
// visible (main)
var root = Parser.parse(' ');
assert(root.matches(':visible'));
Expand
// only-whitespace (main)
var root = Parser.parse(' ');
assert(root.matches(':only-whitespace'));
Expand
// any-link (main)
var root = Parser.parse('#redirect [[a]]ftp://b PMID 0[//d][[file:e]]'),
[{lastChild: a}, b, c, d, e] = root.children;
assert.equal(a, '[[a]]');
assert.equal(b, 'ftp://b');
assert.equal(c, 'PMID 0');
assert.equal(d, '[//d]');
assert.equal(e, '[[file:e]]');
assert.deepStrictEqual(root.querySelectorAll(':any-link'), [a, b, c, d, e]);
Expand
// local-link (main)
var root = Parser.parse([[#a]][[file:b|link=#b]]'),
[a, b] = root.childNodes;
assert.equal(a, '[[#a]]');
assert.equal(b, '[[file:b|link=#b]]');
assert.deepStrictEqual(root.querySelectorAll(':local-link'), [a, b]);
Expand
// invalid (main)
var root = Parser.parse('{|\na\n|}<gallery>b|1px</gallery>'),
a = root.querySelector('table-inter'),
b = root.querySelector('image-parameter');
assert.equal(a, '\na');
assert.equal(b, '1px');
assert.deepStrictEqual(root.querySelectorAll(':invalid'), [a, b]);
Expand
version added: 1.13.0
// valid (main)
var root = Parser.parse('{|\na\n|}<gallery>b|1px</gallery>'),
a = root.querySelector('table-inter'),
b = root.querySelector('image-parameter');
assert.equal(a, '\na');
assert.equal(b, '1px');
assert(!a.matches(':valid'));
assert(!b.matches(':valid'));
Expand
// required (main)
var root = Parser.parse('{{{a}}}'),
a = root.querySelector('arg-name');
assert.equal(a, 'a');
assert.deepStrictEqual(root.querySelectorAll(':required'), [a]);
Expand
// optional (main)
var root = Parser.parse('{{{|a}}}'),
{firstChild} = root,
{lastChild} = firstChild;
assert.equal(lastChild, 'a');
assert.deepStrictEqual(
root.querySelectorAll(':optional'),
[firstChild, lastChild],
);
Expand
version added: 1.13.0
// scope (main)
var root = Parser.parse('[[a]]'),
{firstChild} = root;
assert(firstChild.matches(':scope'));
assert.deepStrictEqual(root.querySelectorAll(':is(:scope > *)'), [firstChild]);
Expand
// is (main)
var root = Parser.parse([[a]]{{b}}'),
{firstChild, lastChild} = root;
assert.deepStrictEqual(
root.querySelectorAll(':is(#A, * + *)'),
[firstChild, lastChild],
);
Expand
// not (main)
var root = Parser.parse('');
assert(root.matches(':not(arg, * + *)'));
Expand
// nth-child (main)
var {lastChild} = Parser.parse([[a]]<ref/>');
assert(lastChild.matches(':nth-child(2)'));
assert(lastChild.matches(':nth-child(even)'));
assert(lastChild.matches(':nth-child(2n)'));
assert(lastChild.matches(':nth-child(:4:2)'));
Expand
// nth-of-type (main)
var {lastChild} = Parser.parse([[a]]<ref/>');
assert(lastChild.matches(':nth-of-type(1)'));
assert(lastChild.matches(':nth-of-type(odd)'));
assert(lastChild.matches(':nth-of-type(-2n+3)'));
assert(lastChild.matches(':nth-of-type(1:)'));
Expand
// nth-last-child (main)
var {firstChild} = Parser.parse('<ref/>[[a]]');
assert(firstChild.matches(':nth-last-child(2)'));
assert(firstChild.matches(':nth-last-child(even)'));
assert(firstChild.matches(':nth-last-child(2n-2)'));
assert(firstChild.matches(':nth-last-child(:3)'));
Expand
// nth-last-of-type (main)
var {firstChild} = Parser.parse('<ref/>[[a]]');
assert(firstChild.matches(':nth-last-of-type(1)'));
assert(firstChild.matches(':nth-last-of-type(odd)'));
assert(firstChild.matches(':nth-last-of-type(3n+1)'));
assert(firstChild.matches(':nth-last-of-type(:)'));
Expand
// contains (main)
var root = Parser.parse('[[a]]'),
{firstChild} = root;
assert.deepStrictEqual(root.querySelectorAll(':contains([[)'), [firstChild]);
Expand
// has (main)
var root = Parser.parse('<ref>[[a]]</ref>'),
attrs = root.querySelector('ext-attrs'),
inner = attrs.nextSibling;
assert.equal(attrs, '');
assert.equal(inner, '[[a]]');
assert(root.matches(':has(#A, #B)'));
assert.deepStrictEqual(root.querySelectorAll(':has(+ ext-inner)'), [attrs]);
assert.deepStrictEqual(root.querySelectorAll(':has(> link)'), [inner]);
assert.deepStrictEqual(
root.querySelectorAll(':has(+ ext-inner, > link)'),
[attrs, inner],
);
Expand
// lang (main)
var [p, b] = Parser.parse('<poem lang="en"><p lang="zh-cn"><b></poem>')
.querySelectorAll('html');
assert.equal(p, '<p lang="zh-cn">');
assert.equal(b, '<b>');
assert(p.matches(':lang(zh)'));
assert(p.matches(':lang(zh-CN)'));
assert(!p.matches(':lang(en)'));
assert(b.matches(':lang(en)'));
Expand
The format is similar to pseudo selector.
// regex (main)
var root = Parser.parse([[aa]]<p id=段落>'),
{firstChild, lastChild} = root;
assert.equal(firstChild, '[[aa]]');
assert.equal(lastChild, '<p id=段落>');
assert.deepStrictEqual(
root.querySelectorAll(':regex("name, /^A{2,}$/i")'),
[firstChild],
);
assert(lastChild.matches(String.raw`:regex("id, /\p{L}/u")`));
对维基文本批量执行语法检查的命令行工具
用于维基文本的 ESLint 插件
A command-line tool that performs linting on Wikitext in bulk
ESLint plugin for Wikitext