import { ElementType as n } from "./index-esm6.js";
import { Document as o, Element as l, Text as d, Comment as a, CDATA as r, ProcessingInstruction as c } from "./index-node.js";
import { DataNode as g, Node as w, NodeWithChildren as I, cloneNode as C, isCDATA as S, isComment as T, isDirective as k, isDocument as y, isTag as D, isText as v } from "./index-node.js";
const h = {
  withStartIndices: !1,
  withEndIndices: !1,
  xmlMode: !1
};
class m {
  /**
   * @param callback Called once parsing has completed.
   * @param options Settings for the handler.
   * @param elementCB Callback whenever a tag is closed.
   */
  constructor(t, e, s) {
    this.dom = [], this.root = new o(this.dom), this.done = !1, this.tagStack = [this.root], this.lastNode = null, this.parser = null, typeof e == "function" && (s = e, e = h), typeof t == "object" && (e = t, t = void 0), this.callback = t ?? null, this.options = e ?? h, this.elementCB = s ?? null;
  }
  onparserinit(t) {
    this.parser = t;
  }
  // Resets the handler back to starting state
  onreset() {
    this.dom = [], this.root = new o(this.dom), this.done = !1, this.tagStack = [this.root], this.lastNode = null, this.parser = null;
  }
  // Signals the handler that parsing is done
  onend() {
    this.done || (this.done = !0, this.parser = null, this.handleCallback(null));
  }
  onerror(t) {
    this.handleCallback(t);
  }
  onclosetag() {
    this.lastNode = null;
    const t = this.tagStack.pop();
    this.options.withEndIndices && (t.endIndex = this.parser.endIndex), this.elementCB && this.elementCB(t);
  }
  onopentag(t, e) {
    const s = this.options.xmlMode ? n.Tag : void 0, i = new l(t, e, void 0, s);
    this.addNode(i), this.tagStack.push(i);
  }
  ontext(t) {
    const { lastNode: e } = this;
    if (e && e.type === n.Text)
      e.data += t, this.options.withEndIndices && (e.endIndex = this.parser.endIndex);
    else {
      const s = new d(t);
      this.addNode(s), this.lastNode = s;
    }
  }
  oncomment(t) {
    if (this.lastNode && this.lastNode.type === n.Comment) {
      this.lastNode.data += t;
      return;
    }
    const e = new a(t);
    this.addNode(e), this.lastNode = e;
  }
  oncommentend() {
    this.lastNode = null;
  }
  oncdatastart() {
    const t = new d(""), e = new r([t]);
    this.addNode(e), t.parent = e, this.lastNode = t;
  }
  oncdataend() {
    this.lastNode = null;
  }
  onprocessinginstruction(t, e) {
    const s = new c(t, e);
    this.addNode(s);
  }
  handleCallback(t) {
    if (typeof this.callback == "function")
      this.callback(t, this.dom);
    else if (t)
      throw t;
  }
  addNode(t) {
    const e = this.tagStack[this.tagStack.length - 1], s = e.children[e.children.length - 1];
    this.options.withStartIndices && (t.startIndex = this.parser.startIndex), this.options.withEndIndices && (t.endIndex = this.parser.endIndex), e.children.push(t), s && (t.prev = s, s.next = t), t.parent = e, this.lastNode = null;
  }
}
export {
  r as CDATA,
  a as Comment,
  g as DataNode,
  o as Document,
  m as DomHandler,
  l as Element,
  w as Node,
  I as NodeWithChildren,
  c as ProcessingInstruction,
  d as Text,
  C as cloneNode,
  S as isCDATA,
  T as isComment,
  k as isDirective,
  y as isDocument,
  D as isTag,
  v as isText
};
