Selector (EN) - bhsd-harry/wikiparser-node GitHub Wiki

Table of Contents

Other Languages

Introduction

The design of Token selector is inspired by CSS and jQuery.

✅ Available in the Mini and Browser versions.

type

✅ 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],
);

name

✅ 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`#\(\)`));

attribute

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$"]'));

combinator

Similar to CSS combinator.

descendant 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]);

child combinator

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],
);

subsequent-sibling combinator

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"));

next-sibling combinator

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],
);

pseudo selector

Similar to CSS and jQuery pseudo selector.

any-link

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]);

contains

Expand
// contains (main)
var root = Parser.parse("[[a]]"),
	{firstChild} = root;
assert.deepStrictEqual(root.querySelectorAll(":contains([[)"), [firstChild]);

empty

Expand
// empty (main)
var root = Parser.parse("<!---->"),
	{firstChild} = root;
assert.deepStrictEqual(root.querySelectorAll(":empty"), [firstChild]);

first-child

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],
);

first-of-type

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],
);

has

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],
);

header

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],
);

invalid

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]);

is

Expand
// is (main)
var root = Parser.parse("[[a]]{{b}}"),
	{firstChild, lastChild} = root;
assert.deepStrictEqual(
	root.querySelectorAll(":is(#A, * + *)"),
	[firstChild, lastChild],
);

lang

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)"));

last-child

Expand
// last-child (main)
var root = Parser.parse("<ref/>a"),
	{firstChild} = root;
assert.equal(firstChild, "<ref/>");
assert.deepStrictEqual(
	root.querySelectorAll("root > :last-child"),
	[firstChild],
);

last-of-type

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],
);

local-link

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]);

not

Expand
// not (main)
var root = Parser.parse("");
assert.ok(root.matches(":not(arg, * + *)"));

nth-child

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)"));

nth-last-child

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)"));

nth-last-of-type

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(:)"));

nth-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:)"));

only-child

Expand
// only-child (main)
var root = Parser.parse("<ref/>a"),
	{firstChild} = root;
assert.equal(firstChild, "<ref/>");
assert.deepStrictEqual(
	root.querySelectorAll("root > :only-child"),
	[firstChild],
);

only-of-type

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],
);

only-whitespace

Expand
// only-whitespace (main)
var root = Parser.parse(" ");
assert.ok(root.matches(":only-whitespace"));

optional

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],
);

parent

Expand
// parent (main)
var root = Parser.parse("<!-- -->"),
	{firstChild} = root;
assert.deepStrictEqual(root.querySelectorAll(":parent"), [firstChild]);

required

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"));

root

Expand
// root (main)
var root = Parser.parse("");
assert.ok(root.matches(":root"));

scope

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]);

valid

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

展开
// visible (main)
var root = Parser.parse(" ");
assert.ok(root.matches(":visible"));

regex selector

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")`));
⚠️ **GitHub.com Fallback** ⚠️