Selector (EN) - bhsd-harry/wikiparser-node GitHub Wiki
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]);// name (main)
var {firstChild} = Parser.parse("[[()]]");
assert.equal(firstChild, "[[()]]");
// Escape special characters
assert.ok(firstChild.matches(String.raw`#\(\)`));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.ok(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],
);
assert.deepStrictEqual(
root.querySelectorAll("[classList~=C1 i]"),
[firstChild, attrs],
);
({firstChild} = Parser.parse("__INDEX__"));
assert.equal(firstChild, "__INDEX__");
assert.ok(firstChild.matches('[pattern="^INDEX$"]'));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]);
assert.ok(!root.matches("* ~ root"));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
// 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
// contains (main)
var root = Parser.parse("[[a]]"),
{firstChild} = root;
assert.deepStrictEqual(root.querySelectorAll(":contains([[)"), [firstChild]);Expand
// empty (main)
var root = Parser.parse("<!---->"),
{firstChild} = root;
assert.deepStrictEqual(root.querySelectorAll(":empty"), [firstChild]);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
// 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.ok(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
// header (main)
var root = Parser.parse("==a=="),
{firstChild} = root;
assert.deepStrictEqual(root.querySelectorAll(":header"), [firstChild]);hidden
Expand
// hidden (main)
var root = Parser.parse("<!-- -->__nocc__"),
{firstChild, lastChild} = root;
assert.equal(firstChild, "<!-- -->");
assert.equal(lastChild, "__nocc__");
assert.ok(root.matches(":hidden"));
assert.deepStrictEqual(
root.querySelectorAll(":hidden"),
[firstChild, lastChild],
);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
// is (main)
var root = Parser.parse("[[a]]{{b}}"),
{firstChild, lastChild} = root;
assert.deepStrictEqual(
root.querySelectorAll(":is(#A, * + *)"),
[firstChild, lastChild],
);Expand
// lang (main)
var root = Parser.parse('<poem lang="en"><p lang="zh-cn"><b></poem>'),
[p, b] = root.querySelectorAll("html");
assert.equal(p, '<p lang="zh-cn">');
assert.equal(b, "<b>");
assert.ok(p.matches(":lang(zh)"));
assert.ok(p.matches(":lang(zh-CN)"));
assert.ok(!p.matches(":lang(en)"));
assert.ok(b.matches(":lang(en)"));
assert.ok(!root.matches(":lang(en)"));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
// 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
// not (main)
var root = Parser.parse("");
assert.ok(root.matches(":not(arg, * + *)"));Expand
// nth-child (main)
var {lastChild} = Parser.parse("[[a]]<ref/>");
assert.ok(lastChild.matches(":nth-child(2)"));
assert.ok(lastChild.matches(":nth-child(even)"));
assert.ok(lastChild.matches(":nth-child(2n)"));
assert.ok(lastChild.matches(":nth-child(:4:2)"));Expand
// nth-last-child (main)
var {firstChild} = Parser.parse("<ref/>[[a]]");
assert.ok(firstChild.matches(":nth-last-child(2)"));
assert.ok(firstChild.matches(":nth-last-child(even)"));
assert.ok(firstChild.matches(":nth-last-child(2n-2)"));
assert.ok(firstChild.matches(":nth-last-child(:3)"));Expand
// nth-last-of-type (main)
var {firstChild} = Parser.parse("<ref/>[[a]]");
assert.ok(firstChild.matches(":nth-last-of-type(1)"));
assert.ok(firstChild.matches(":nth-last-of-type(odd)"));
assert.ok(firstChild.matches(":nth-last-of-type(3n+1)"));
assert.ok(firstChild.matches(":nth-last-of-type(:)"));Expand
// nth-of-type (main)
var {lastChild} = Parser.parse("[[a]]<ref/>");
assert.ok(lastChild.matches(":nth-of-type(1)"));
assert.ok(lastChild.matches(":nth-of-type(odd)"));
assert.ok(lastChild.matches(":nth-of-type(-2n+3)"));
assert.ok(lastChild.matches(":nth-of-type(1:)"));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
// only-whitespace (main)
var root = Parser.parse(" ");
assert.ok(root.matches(":only-whitespace"));Expand
// optional (main)
var root = Parser.parse("{{{|a}}}"),
{firstChild} = root,
{lastChild} = firstChild;
assert.equal(lastChild, "a");
// Not applicable to the root
assert.ok(!root.matches(":optional"));
assert.deepStrictEqual(
root.querySelectorAll(":optional"),
[firstChild, lastChild],
);Expand
// parent (main)
var root = Parser.parse("<!-- -->"),
{firstChild} = root;
assert.deepStrictEqual(root.querySelectorAll(":parent"), [firstChild]);Expand
// required (main)
var root = Parser.parse("{{{a}}}\n=b="),
a = root.querySelector("arg-name"),
b = root.querySelector("heading-title");
assert.equal(a, "a");
assert.equal(b, "b");
// Not applicable to the root
assert.ok(!root.matches(":required"));
assert.ok(a.matches(":required"));
assert.ok(b.matches(":required"));Expand
// root (main)
var root = Parser.parse("");
assert.ok(root.matches(":root"));Expand
version added: 1.13.0
// scope (main)
var root = Parser.parse("[[a]]"),
{firstChild} = root;
assert.ok(firstChild.matches(":scope"));
assert.deepStrictEqual(root.querySelectorAll(":is(:scope > *)"), [firstChild]);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.ok(!a.matches(":valid"));
assert.ok(!b.matches(":valid"));展开
// visible (main)
var root = Parser.parse(" ");
assert.ok(root.matches(":visible"));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.ok(lastChild.matches(String.raw`:regex("id, /\p{L}/u")`));