///|
#external
type Node
// ---------- node API --------------
///|
pub extern "js" fn node_type(self : Node) -> Int = "(x) => x.nodeType"
///|
pub extern "js" fn node_name(self : Node) -> String = "(x) => x.nodeName"
///|
pub extern "js" fn node_value(self : Node) -> String = "(x) => x.nodeValue"
///|
pub extern "js" fn first_child(self : Node) -> Node = "(x) => x.firstChild"
///|
pub extern "js" fn last_child(self : Node) -> Node = "(x) => x.lastChild"
///|
pub extern "js" fn next_sibling(self : Node) -> Node = "(x) => x.nextSibling"
///|
pub extern "js" fn previous_sibling(self : Node) -> Node = "(x) => x.previousSibling"
///|
pub extern "js" fn parent_node(self : Node) -> Node = "(x) => x.parentNode"
///|
pub extern "js" fn append_child(self : Node, child : Node) = "(p,c) => p.appendChild(c)"
///|
pub extern "js" fn remove_child(self : Node, child : Node) = "(p,c) => p.removeChild(c)"
///|
pub extern "js" fn replace_child(self : Node, new : Node, old : Node) = "(p,n,o) => p.replaceChild(n,o)"
///|
pub extern "js" fn insert_before(self : Node, value : Node, before : Node) = "(p,value,before) => p.insertBefore(value,before)"
// ---------- some specific node API --------------
// Note: the childNodes property is a NodeList, not an array, so we can't use the Array type.
///|
pub extern "js" fn nth_child(self : Node, index : Int) -> Node =
#| (x,i) => {
#| const r = x.childNodes[i];
#| if (r === undefined) throw new Error(`nth_child: index ${i} out of bounds, length=${x.childNodes.length}`);
#| return r;
#| }
///|
pub extern "js" fn count_child(self : Node) -> Int = "(x) => x.childNodes.length"