(() => {
const core = Deno.core;
const DOCUMENT_NODE = core.ops.op_dom_document_node();
const ELEMENT_NODE = 1;
const TEXT_NODE = 3;
const DOCUMENT_NODE_TYPE = 9;
class Node {
constructor(nodeId) {
this._nodeId = nodeId;
}
get nodeType() {
return core.ops.op_dom_get_node_type(this._nodeId);
}
get nodeName() {
const type = this.nodeType;
if (type === ELEMENT_NODE) return this.tagName;
if (type === TEXT_NODE) return "#text";
if (type === DOCUMENT_NODE_TYPE) return "#document";
return "";
}
get parentNode() {
const pid = core.ops.op_dom_get_parent(this._nodeId);
return pid === -1 ? null : wrapNode(pid);
}
get parentElement() {
const pid = core.ops.op_dom_get_parent(this._nodeId);
if (pid === -1) return null;
const n = wrapNode(pid);
return n instanceof Element ? n : null;
}
get childNodes() {
const ids = core.ops.op_dom_get_children(this._nodeId);
return ids.map((id) => wrapNode(id));
}
get firstChild() {
const id = core.ops.op_dom_get_first_child(this._nodeId);
return id === -1 ? null : wrapNode(id);
}
get lastChild() {
const id = core.ops.op_dom_get_last_child(this._nodeId);
return id === -1 ? null : wrapNode(id);
}
get nextSibling() {
const id = core.ops.op_dom_get_next_sibling(this._nodeId);
return id === -1 ? null : wrapNode(id);
}
get previousSibling() {
const id = core.ops.op_dom_get_prev_sibling(this._nodeId);
return id === -1 ? null : wrapNode(id);
}
get textContent() {
return core.ops.op_dom_get_text_content(this._nodeId);
}
set textContent(v) {
core.ops.op_dom_set_text_content(this._nodeId, String(v));
}
appendChild(child) {
if (child && child._nodeId != null) {
core.ops.op_dom_append_child(this._nodeId, child._nodeId);
}
return child;
}
insertBefore(child, ref) {
if (child && child._nodeId != null) {
const refId = ref ? ref._nodeId : -1;
core.ops.op_dom_insert_before(this._nodeId, child._nodeId, refId);
}
return child;
}
removeChild(child) {
if (child && child._nodeId != null) {
core.ops.op_dom_remove_child(this._nodeId, child._nodeId);
}
return child;
}
}
class Element extends Node {
get tagName() {
return core.ops.op_dom_get_tag_name(this._nodeId).toUpperCase();
}
get innerHTML() {
return core.ops.op_dom_get_inner_html(this._nodeId);
}
set innerHTML(v) {
throw new Error("innerHTML setter not yet implemented");
}
get outerHTML() {
return core.ops.op_dom_get_outer_html(this._nodeId);
}
get id() {
return this.getAttribute("id") || "";
}
set id(v) {
}
get className() {
return this.getAttribute("class") || "";
}
set className(v) {
}
getAttribute(name) {
const v = core.ops.op_dom_get_attribute(this._nodeId, name);
return v === "" &&
!core.ops.op_dom_has_attribute(this._nodeId, name)
? null
: v;
}
hasAttribute(name) {
return core.ops.op_dom_has_attribute(this._nodeId, name);
}
setAttribute(name, value) {
throw new Error("setAttribute not yet implemented");
}
removeAttribute(name) {
throw new Error("removeAttribute not yet implemented");
}
querySelector(selector) {
throw new Error("querySelector not yet implemented");
}
querySelectorAll(selector) {
throw new Error("querySelectorAll not yet implemented");
}
get children() {
const ids = core.ops.op_dom_get_child_elements(this._nodeId);
return ids.map((id) => new Element(id));
}
get classList() {
return {
add() {},
remove() {},
contains() {
return false;
},
toggle() {
return false;
},
};
}
}
class Document extends Node {
constructor() {
super(DOCUMENT_NODE);
}
get documentElement() {
const children = this.childNodes;
for (const c of children) {
if (c instanceof Element) return c;
}
return null;
}
get body() {
return this.querySelector("body");
}
get head() {
return this.querySelector("head");
}
getElementById(id) {
const nodeId = core.ops.op_dom_get_element_by_id(id);
return nodeId === -1 ? null : new Element(nodeId);
}
getElementsByTagName(tag) {
const ids = core.ops.op_dom_get_elements_by_tag_name(
DOCUMENT_NODE,
tag
);
return ids.map((id) => new Element(id));
}
createElement(tag) {
const id = core.ops.op_dom_create_element(tag);
return new Element(id);
}
createTextNode(text) {
const id = core.ops.op_dom_create_text_node(text);
return new TextNode(id);
}
createDocumentFragment() {
const id = core.ops.op_dom_create_document_fragment();
return new Element(id);
}
querySelector(selector) {
throw new Error("querySelector not yet implemented");
}
querySelectorAll(selector) {
throw new Error("querySelectorAll not yet implemented");
}
get URL() {
return core.ops.op_dom_get_base_url();
}
}
class TextNode extends Node {
get data() {
return core.ops.op_dom_get_text_content(this._nodeId);
}
set data(v) {
core.ops.op_dom_set_text_content(this._nodeId, String(v));
}
get nodeName() {
return "#text";
}
}
function wrapNode(nodeId) {
const type = core.ops.op_dom_get_node_type(nodeId);
if (type === ELEMENT_NODE) return new Element(nodeId);
if (type === TEXT_NODE) return new TextNode(nodeId);
if (type === DOCUMENT_NODE_TYPE) return new Document();
return new Node(nodeId);
}
globalThis.Node = Node;
globalThis.Element = Element;
globalThis.Document = Document;
globalThis.Text = TextNode;
globalThis.document = new Document();
})();