Skip to content

AstNode (EN)

Bhsd edited this page Nov 30, 2024 · 11 revisions
Table of Contents

Other Languages

Introduction

AstNode is the parent class of all text nodes and other nodes, modeled after the Node class, with properties and methods very similar to the Node class.

✅ Available in the Mini and Browser versions.

Properties

childNodes

✅ Expand

type: AstNode[]
An array of all child nodes, read-only.

// childNodes
var root = Parser.parse([[a]]b'),
	{firstChild, lastChild} = root;
assert.equal(firstChild, '[[a]]');
assert.equal(lastChild, 'b');
assert.deepStrictEqual(root.childNodes, [firstChild, lastChild]);
assert.deepStrictEqual(lastChild.childNodes, []);

firstChild

✅ Expand

type: AstNode
First child node, read-only.

// firstChild
var root = Parser.parse('a'),
	{firstChild} = root;
assert.equal(firstChild, 'a');
assert.strictEqual(firstChild.firstChild, undefined);

lastChild

✅ Expand

type: AstNode
Last child node, read-only.

// lastChild
var root = Parser.parse('a'),
	{lastChild} = root;
assert.equal(lastChild, 'a');
assert.strictEqual(lastChild.lastChild, undefined);

parentNode

✅ Expand

type: Token
Parent node, read-only.

// parentNode
var root = Parser.parse('a'),
	{firstChild} = root;
assert.equal(firstChild, 'a');
assert.strictEqual(firstChild.parentNode, root);
assert.strictEqual(root.parentNode, undefined);

nextSibling

✅ Expand

type: AstNode
Next sibling node, read-only.

// nextSibling
var {firstChild, lastChild} = Parser.parse([[a]]b');
assert.equal(firstChild, '[[a]]');
assert.equal(lastChild, 'b');
assert.strictEqual(firstChild.nextSibling, lastChild);
assert.strictEqual(lastChild.nextSibling, undefined);

previousSibling

✅ Expand

type: AstNode
Previous sibling node, read-only.

// previousSibling
var {firstChild, lastChild} = Parser.parse([[a]]b');
assert.equal(firstChild, '[[a]]');
assert.equal(lastChild, 'b');
assert.strictEqual(lastChild.previousSibling, firstChild);
assert.strictEqual(firstChild.previousSibling, undefined);

offsetHeight

✅ Expand

type: number
Number of rows, read-only.

// offsetHeight
var root = Parser.parse('a\nb');
assert.strictEqual(root.offsetHeight, 2);

offsetWidth

✅ Expand

type: number
Number of columns in the last row, read-only.

// offsetWidth
var root = Parser.parse('ab\nc');
assert.strictEqual(root.offsetWidth, 1);

nextElementSibling

Expand

type: Token
Next non-text sibling node, read-only.

// nextElementSibling (main)
var {childNodes: [a, b, c]} = Parser.parse([[a]]b{{c}}');
assert.equal(a, '[[a]]');
assert.equal(b, 'b');
assert.equal(c, '{{c}}');
assert.strictEqual(a.nextElementSibling, c);
assert.strictEqual(b.nextElementSibling, c);
assert.strictEqual(c.nextElementSibling, undefined);

previousElementSibling

Expand

type: Token
Previous non-text sibling node, read-only.

// previousElementSibling (main)
var {childNodes: [a, b, c]} = Parser.parse([[a]]b{{c}}');
assert.equal(a, '[[a]]');
assert.equal(b, 'b');
assert.equal(c, '{{c}}');
assert.strictEqual(c.previousElementSibling, a);
assert.strictEqual(b.previousElementSibling, a);
assert.strictEqual(a.previousElementSibling, undefined);

nextVisibleSibling

Expand

type: AstNode
Next visible sibling node, read-only.

// nextVisibleSibling (main)
var {firstChild, lastChild} = Parser.parse([[a]]<!--b--><noinclude>c');
assert.equal(firstChild, '[[a]]');
assert.equal(lastChild, 'c');
assert.strictEqual(firstChild.nextVisibleSibling, lastChild);

previousVisibleSibling

Expand

type: AstNode
Previous visible sibling node, read-only.

// previousVisibleSibling (main)
var {firstChild, lastChild} = Parser.parse('a<!--b--><noinclude>{{c}}');
assert.equal(firstChild, 'a');
assert.equal(lastChild, '{{c}}');
assert.strictEqual(lastChild.previousVisibleSibling, firstChild);

isConnected

Expand

type: boolean
Whether the node has a root node, read-only.

// isConnected (main)
var root = Parser.parse('a'),
	{firstChild} = root;
assert(root.isConnected);
assert(firstChild.isConnected);
firstChild.remove();
assert(!firstChild.isConnected);
root.append(firstChild);
assert(firstChild.isConnected);

eof

Expand

type: boolean
Whether there are other nodes (excluding descendants) behind, read-only.

// eof (main)
var root = Parser.parse('a[[b]]\n'),
	{firstChild, firstElementChild} = root,
	{lastChild} = firstElementChild;
assert.equal(firstChild, 'a');
assert.equal(firstElementChild, '[[b]]');
assert.equal(lastChild, 'b');
assert(root.eof);
assert(!firstChild.eof);
assert(firstElementChild.eof); // trailing whitespace is ignored
assert(lastChild.eof);

offsetTop

Expand

type: number
Row number relative to the parent container (starting from 0), read-only.

// offsetTop (main)
var root = Parser.parse('a\n[[b]]'),
	{firstChild, lastChild} = root;
assert.equal(lastChild, '[[b]]');
assert.strictEqual(root.offsetTop, 0);
assert.strictEqual(firstChild.offsetTop, 0);
assert.strictEqual(lastChild.offsetTop, 1);

offsetLeft

Expand

type: number
Column number relative to the parent container (starting from 0), read-only.

// offsetLeft (main)
var root = Parser.parse([[a]]\nb'),
	{firstChild, lastChild} = root;
assert.equal(firstChild, '[[a]]');
assert.strictEqual(root.offsetLeft, 0);
assert.strictEqual(firstChild.offsetLeft, 0);
assert.strictEqual(lastChild.offsetLeft, 5);

style

Expand

type: {top: number, left: number, height: number, width: number, padding: number}
Position, size and padding, read-only.

// style (main)
var root = Parser.parse('a\n[[b]]'),
	{firstChild, lastChild} = root;
assert.equal(lastChild, '[[b]]');
assert.deepStrictEqual(root.style, {
	top: 0,
	left: 0,
	height: 2,
	width: 5,
	padding: 0,
});
assert.deepStrictEqual(firstChild.style, {
	top: 0,
	left: 0,
	height: 2,
	width: 0,
	padding: 0,
});
assert.deepStrictEqual(lastChild.style, {
	top: 1,
	left: 0,
	height: 1,
	width: 5,
	padding: 2, // `[[`
});

font

Expand

version added: 1.8.0

Font style.

// font (main)
var {
	childNodes: [, text],
	lastChild: {lastChild},
} = Parser.parse("''a'''\n'''''[//b c''d]");
assert.equal(text, "a'");
assert.equal(lastChild, "c''d");
assert.deepStrictEqual(text.font, {
	italic: true,
	bold: false,
});
assert.deepStrictEqual(lastChild.firstChild.font, {
	italic: true,
	bold: true,
});
assert.deepStrictEqual(lastChild.lastChild.font, {
	italic: false,
	bold: true,
});

bold

Expand

version added: 1.8.0

Whether it is bold.

// bold (main)
var {
	childNodes: [, text],
	lastChild: {lastChild},
} = Parser.parse("''a'''\n'''''[//b c''d]");
assert.equal(text, "a'");
assert.equal(lastChild, "c''d");
assert(text.bold === false);
assert(lastChild.firstChild.bold === true);
assert(lastChild.lastChild.bold === true);

italic

Expand

version added: 1.8.0

Whether it is italic.

// italic (main)
var {
	childNodes: [, text],
	lastChild: {lastChild},
} = Parser.parse("''a'''\n'''''[//b c''d]");
assert.equal(text, "a'");
assert.equal(lastChild, "c''d");
assert(text.italic === true);
assert(lastChild.firstChild.italic === true);
assert(lastChild.lastChild.italic === false);

Methods

getRootNode

✅ Expand

returns: Token
Get the root node.

// getRootNode
var root = Parser.parse('[[a]]'),
	{firstChild: {firstChild}} = root;
assert.equal(firstChild, 'a');
assert.strictEqual(firstChild.getRootNode(), root);
assert.strictEqual(root.getRootNode(), root);

indexFromPos

✅ Expand

param: number row number
param: number column number
returns: number
Converts row and column numbers to character position.

// indexFromPos
var root = Parser.parse('a\nb');
assert.strictEqual(root.indexFromPos(0, 0), 0);
assert.strictEqual(root.indexFromPos(0, 1), 1);
assert.strictEqual(root.indexFromPos(1, 0), 2);
assert.strictEqual(root.indexFromPos(1, 1), 3);
assert.strictEqual(root.indexFromPos(2, 0), undefined);

posFromIndex

✅ Expand

param: number Character position
returns: {top: number, left: number}
Converts the character position to row and column numbers.

// posFromIndex
var root = Parser.parse('a\nb');
assert.deepStrictEqual(root.posFromIndex(3), {top: 1, left: 1});
assert.strictEqual(root.posFromIndex(4), undefined);

getRelativeIndex

✅ Expand

param: number the index of the child node, optional
returns: number
Get the character position of a child node (or itself) relative to the parent node.

// getRelativeIndex
var root = Parser.parse('a[[b]]'),
	{lastChild} = root,
	{firstChild} = lastChild;
assert.equal(lastChild, '[[b]]');
assert.equal(firstChild, 'b');
assert.strictEqual(root.getRelativeIndex(), 0);
assert.strictEqual(root.getRelativeIndex(0), 0);
assert.strictEqual(root.getRelativeIndex(1), 1);
assert.strictEqual(root.getRelativeIndex(2), 6);
assert.strictEqual(lastChild.getRelativeIndex(), 1);
assert.strictEqual(lastChild.getRelativeIndex(0), 2);
// 插入新的子节点必须使用`|`作为分隔符
assert.strictEqual(lastChild.getRelativeIndex(1), 4);
assert.strictEqual(firstChild.getRelativeIndex(), 2);
assert.strictEqual(firstChild.getRelativeIndex(0), 0);

getAbsoluteIndex

✅ Expand

returns: number
Get the absolute character position of the current node.

// getAbsoluteIndex
var root = Parser.parse('a[[b]]'),
	{lastChild} = root,
	{firstChild} = lastChild;
assert.equal(lastChild, '[[b]]');
assert.equal(firstChild, 'b');
assert.strictEqual(root.getAbsoluteIndex(), 0);
assert.strictEqual(lastChild.getAbsoluteIndex(), 1);
assert.strictEqual(firstChild.getAbsoluteIndex(), 3);

getBoundingClientRect

✅ Expand

returns: {top: number, left: number, height: number, width: number}
Get the row and column position and size of the current node.

// getBoundingClientRect
var {firstChild, lastChild} = Parser.parse('a\n[[b]]');
assert.equal(lastChild, '[[b]]');
assert.deepStrictEqual(firstChild.getBoundingClientRect(), {
	top: 0,
	left: 0,
	height: 2,
	width: 0,
});
assert.deepStrictEqual(lastChild.getBoundingClientRect(), {
	top: 1,
	left: 0,
	height: 1,
	width: 5,
});

is

✅ Expand

version added: 1.10.0

param: string Node type
returns: boolean
Check if the node is of a certain type.

// is
var root = Parser.parse('a');
assert(root.is('root'));
assert(!root.firstChild.is('link'));

isEqualNode

Expand

param: AstNode Node to compare
returns: boolean
Whether the node is identical to the other node.

// isEqualNode (main)
var a = Parser.parse('[[a]]'),
	b = Parser.parse('[[a]]'),
	c = Parser.parse('[[ a]]'),
	d = a.firstChild,
	e = Parser.parse('<!--[[a]]-->').firstChild.firstChild,
	f = Parser.parse('[[a]]', true);
assert.equal(d, '[[a]]');
assert.equal(e, '[[a]]');
assert(a.isEqualNode(b));
assert(!a.isEqualNode(c));
assert(!a.isEqualNode(d));
assert(!a.isEqualNode(e));
assert(a.isEqualNode(f));
assert(!d.isEqualNode(e));

after

Expand

param: AstNode | string Nodes to insert
Inserts sibling nodes in the back.

// after (main)
var root = Parser.parse('a'),
	{firstChild} = root;
firstChild.after('b', 'c');
assert.equal(root, 'abc');

before

Expand

param: AstNode | string Nodes to insert
Inserts sibling nodes in the front.

// before (main)
var root = Parser.parse('a'),
	{firstChild} = root;
firstChild.before('b', 'c');
assert.equal(root, 'bca');

remove

Expand

Remove the current node.

// remove (main)
var root = Parser.parse('[[a|b]]'),
	{firstChild} = root,
	{lastChild} = firstChild;
assert.equal(firstChild, '[[a|b]]');
assert.equal(lastChild, 'b');
lastChild.remove();
assert.equal(root, '[[a]]');
firstChild.remove();
assert.equal(root, '');

replaceWith

Expand

param: AstNode | string Nodes to insert
Replaces the current node with new nodes.

// replaceWith (main)
var root = Parser.parse('a'),
	{firstChild} = root;
firstChild.replaceWith('b', 'c');
assert.equal(root, 'bc');

contains

Expand

param: AstNode Node to compare
Whether the node is the same as or an ancestor of the other node.

// contains (main)
var root = Parser.parse('a'),
	{firstChild} = root;
assert(root.contains(root));
assert(root.contains(firstChild));
assert(!firstChild.contains(root));

addEventListener

Expand

param: string | string[] type of event
param: Function listener
param: {once?: boolean} options
Add event listeners. Used in conjunction with the dispatchEvent method.

// addEventListener (main)
var root = Parser.parse(''),
	counter = 0;
var listener = (_, data) => {
	counter += data;
};
root.addEventListener('x', listener);
root.addEventListener('y', listener, {once: true});
root.dispatchEvent(new Event('x'), 1);
assert.strictEqual(counter, 1);
root.dispatchEvent(new Event('x'), 2);
assert.strictEqual(counter, 3);
root.dispatchEvent(new Event('y'), 3);
assert.strictEqual(counter, 6);
root.dispatchEvent(new Event('y'), 4);
assert.strictEqual(counter, 6);

removeEventListener

Expand

param: string | string[] type of event
param: Function listener
Remove event listeners.

// removeEventListener (main)
var root = Parser.parse(''),
	counter = 0;
var listener = () => {
	counter++;
};
root.addEventListener('x', listener);
root.dispatchEvent(new Event('x'));
assert.strictEqual(counter, 1);
root.removeEventListener('x', listener);
root.dispatchEvent(new Event('x'));
assert.strictEqual(counter, 1);

removeAllEventListeners

Expand

param: string | string[] type of event
Remove all listeners for the event.

// removeAllEventListeners (main)
var root = Parser.parse(''),
	counter = 0;
var f = () => {
	counter++;
};
var g = () => {
	counter += 2;
};
root.addEventListener('x', f);
root.addEventListener('x', g);
root.dispatchEvent(new Event('x'));
assert.strictEqual(counter, 3);
root.removeAllEventListeners('x');
root.dispatchEvent(new Event('x'));
assert.strictEqual(counter, 3);

listEventListeners

Expand

param: string type of event
List event listeners.

// listEventListeners (main)
var {firstChild} = Parser.parse('[[a]]'),
	listeners = firstChild.listEventListeners('remove');
assert.strictEqual(listeners.length, 1);
// predefined listener in the Parser
assert.strictEqual(listeners[0].name, 'linkListener');

dispatchEvent

Expand

param: Event event object
param: any event data
Trigger an event.

// dispatchEvent (main)
var root = Parser.parse('a'),
	{firstChild} = root,
	record = '';
var listener = ({target, currentTarget, prevTarget}) => {
	record += `${target.type} ${currentTarget.type} ${prevTarget?.type}\n`;
};
root.addEventListener('x', listener, {once: true});
firstChild.addEventListener('x', listener);
firstChild.dispatchEvent(new Event('x', {bubbles: true}));
assert.strictEqual(record, 'text text undefined\ntext root text\n');
firstChild.dispatchEvent(new Event('x', {bubbles: true}));
assert.strictEqual(
	record,
	'text text undefined\ntext root text\ntext text undefined\n',
);

getAncestors

Expand

returns: Token[]
Get all ancestor nodes (from bottom to top).

// getAncestors (main)
var root = Parser.parse('[[a]]'),
	{firstChild} = root,
	{lastChild} = firstChild;
assert.equal(firstChild, '[[a]]');
assert.equal(lastChild, 'a');
assert.deepStrictEqual(root.getAncestors(), []);
assert.deepStrictEqual(firstChild.getAncestors(), [root]);
assert.deepStrictEqual(lastChild.getAncestors(), [firstChild, root]);

compareDocumentPosition

Expand

param: AstNode
returns: number
Compare the position of the current node with another node.

// compareDocumentPosition (main)
var root = Parser.parse([[a]]b'),
	{firstElementChild, lastChild} = root,
	{firstChild} = firstElementChild;
assert.equal(firstElementChild, '[[a]]');
assert.equal(firstChild, 'a');
assert.strictEqual(root.compareDocumentPosition(root), 0);
assert(root.compareDocumentPosition(firstChild) < 0);
assert(firstChild.compareDocumentPosition(root) > 0);
assert(firstElementChild.compareDocumentPosition(lastChild) < 0);
assert(lastChild.compareDocumentPosition(firstElementChild) > 0);
assert(firstChild.compareDocumentPosition(lastChild) < 0);
assert(lastChild.compareDocumentPosition(firstChild) > 0);

destroy

Expand

Destroy the node. Will destroy all ancestor nodes in a chain, so please use the remove method to detach from the parent node before using it.

getLine

Expand

param: number Line number
returns: string
Extract the source text of a line.

// getLine (main)
assert.strictEqual(Parser.parse('a\nb').getLine(1), 'b');
Clone this wiki locally