diff --git a/src/builder.js b/src/builder.js index dc238b6..5c613a2 100644 --- a/src/builder.js +++ b/src/builder.js @@ -73,6 +73,15 @@ class Builder { * @property {string} [StanzaAttrs.xmlns] */ + /** @type {Element} */ + #nodeTree; + /** @type {Element} */ + #node; + /** @type {string} */ + #name; + /** @type {StanzaAttrs} */ + #attrs; + /** * The attributes should be passed in object notation. * @param {string} name - The name of the root element. @@ -89,10 +98,35 @@ class Builder { attrs = { xmlns: NS.CLIENT }; } } - // Holds the tree being built. - this.nodeTree = xmlElement(name, attrs); - // Points to the current operation node. - this.node = this.nodeTree; + + this.#name = name; + this.#attrs = attrs; + } + + buildTree() { + return xmlElement(this.#name, this.#attrs); + } + + /** @return {Element} */ + get nodeTree() { + if (!this.#nodeTree) { + // Holds the tree being built. + this.#nodeTree = this.buildTree(); + } + return this.#nodeTree; + } + + /** @return {Element} */ + get node() { + if (!this.#node) { + this.#node = this.tree(); + } + return this.#node; + } + + /** @param {Element} el */ + set node(el) { + this.#node = el; } /** diff --git a/src/stanza.js b/src/stanza.js index cd8606d..127a74f 100644 --- a/src/stanza.js +++ b/src/stanza.js @@ -1,3 +1,4 @@ +import Builder from './builder.js'; import log from './log.js'; import { getFirstElementChild, getParserError, xmlHtmlNode } from './utils.js'; @@ -32,36 +33,41 @@ export function toStanzaElement(string, throwErrorIfInvalidNS) { /** * A Stanza represents a XML element used in XMPP (commonly referred to as stanzas). */ -export class Stanza { +export class Stanza extends Builder { + + /** @type {string} */ + #string; + /** @type {Array} */ + #strings; + /** @type {Array} */ + #values; + /** * @param {string[]} strings * @param {any[]} values */ constructor(strings, values) { - this.strings = strings; - this.values = values; + super('stanza'); + this.#strings = strings; + this.#values = values; + } + + buildTree() { + return toStanzaElement(this.toString(), true); } /** * @return {string} */ toString() { - this.string = - this.string || - this.strings.reduce((acc, str) => { - const idx = this.strings.indexOf(str); - const value = this.values.length > idx ? this.values[idx] : ''; + this.#string = + this.#string || + this.#strings.reduce((acc, str) => { + const idx = this.#strings.indexOf(str); + const value = this.#values.length > idx ? this.#values[idx] : ''; return acc + str + (Array.isArray(value) ? value.join('') : value.toString()); }, ''); - return this.string; - } - - /** - * @return {Element} - */ - tree() { - this.node = this.node ?? toStanzaElement(this.toString(), true); - return this.node; + return this.#string; } }