UNPKG

libxslt-wasm

Version:

JavaScript bindings for libxslt compiled to WebAssembly

96 lines (95 loc) 3.98 kB
import { XmlOutputBuffer } from "./XmlOutputBuffer.js"; import { NULL_POINTER } from "../constants.js"; import { stringToNewUTF8 } from "../internal/emscripten.js"; import { xmlReadFile, xmlReadDoc, xmlNodeDumpOutput, xmlFreeDoc, htmlDocContentDumpFormatOutput, } from "../internal/libxml2.js"; import { free } from "../internal/main.js"; import { DataSegment } from "../utils/DataSegment.js"; /** * A wrapper class for `xmlDocPtr` in libxml2 */ class XmlDocument extends DataSegment { static async fromFileOrUrl(fileOrUrl, encoding = null) { const encodingPtr = encoding ? stringToNewUTF8(encoding) : null; const fileOrUrlPtr = stringToNewUTF8(fileOrUrl); const xmlDocument = new XmlDocument(await xmlReadFile(fileOrUrlPtr, encodingPtr ?? NULL_POINTER, 1 | 2 | 4 | 8 | 1024)); if (encodingPtr !== null) { free(encodingPtr); } free(fileOrUrlPtr); return xmlDocument; } static async fromString(xmlString) { const xmlStringPtr = xmlString !== "" ? stringToNewUTF8(xmlString) : NULL_POINTER; const xmlDocument = new XmlDocument(await xmlReadDoc(xmlStringPtr, 0, 0, 1 | 2 | 4 | 8 | 1024)); free(xmlStringPtr); return xmlDocument; } delete() { if (this.dataOffset !== null) { xmlFreeDoc(this.dataOffset); } super.delete(); } /** * Formats the XML document as a string by dumping the XML tree to an * {@link XmlOutputBuffer} and returning its string representation. */ toString(options) { if (this.dataOffset === null) { throw new Error("XML document has already been disposed"); } const xmlOutputBuffer = XmlOutputBuffer.allocate(); const encodingPtr = options?.encoding ? stringToNewUTF8(options.encoding) : null; if (xmlOutputBuffer.dataOffset === null) { throw new Error("Failed to allocate memory for XML output buffer"); } /** * Since `xmlDocPtr` is a super pointer to `xmlNodePtr`, it can be passed to * `cur`. While this usage may be suspect, this technique is used for for * `htmlDocContentDumpOutput`. * * @see {@link https://gitlab.gnome.org/GNOME/libxml2/-/blob/master/HTMLtree.c#L938-942} */ xmlNodeDumpOutput(xmlOutputBuffer.dataOffset, /* doc */ this.dataOffset, /* cur */ this.dataOffset, /* level */ 0, options?.format ? 1 : 0, /* encoding */ encodingPtr ?? NULL_POINTER); if (encodingPtr !== null) { free(encodingPtr); } const xmlString = xmlOutputBuffer.toString(); xmlOutputBuffer.delete(); return xmlString; } /** * Assuming the document is an HTML tree, dumps the document to an * {@link XmlOutputBuffer} and returns the output buffer */ toHtmlOutputBuffer(options) { if (this.dataOffset === null) { throw new Error("XML document has already been disposed"); } const xmlOutputBuffer = XmlOutputBuffer.allocate(); const encodingPtr = options?.encoding ? stringToNewUTF8(options.encoding) : null; if (xmlOutputBuffer.dataOffset === null) { throw new Error("Failed to allocate memory for output buffer"); } htmlDocContentDumpFormatOutput(xmlOutputBuffer.dataOffset, this.dataOffset, encodingPtr ?? NULL_POINTER, options?.format ? 1 : 0); if (encodingPtr !== null) { free(encodingPtr); } return xmlOutputBuffer; } /** * Assuming the document is an HTML tree, serializes the document via * {@link toHtmlOutputBuffer} and returns the string */ toHtmlString(options) { const xmlOutputBuffer = this.toHtmlOutputBuffer(options); const xmlString = xmlOutputBuffer.toString(); xmlOutputBuffer.delete(); return xmlString; } } export { XmlDocument };