UNPKG

libxslt-wasm

Version:

JavaScript bindings for libxslt compiled to WebAssembly

97 lines (96 loc) 4.35 kB
import { XmlOutputBuffer } from "./XmlOutputBuffer.js"; import { DataSegment } from "../common/DataSegment.js"; import { NULL_POINTER } from "../constants.js"; import { stringToNewUTF8, HEAPU8 } from "../internal/emscripten.js"; import { xmlReadFile, xmlReadDoc, xmlReadMemory, xmlNodeDumpOutput, xmlFreeDoc, htmlDocContentDumpFormatOutput, } from "../internal/libxml2.js"; import { free, malloc } from "../internal/main.js"; import { parseXmlOptions } from "../utils/parseXmlOptions.js"; /** * A wrapper class for `xmlDocPtr` in libxml2 */ class XmlDocument extends DataSegment { static async fromUrl(url, { encoding, options } = {}) { const encodingPtr = encoding ? stringToNewUTF8(encoding) : NULL_POINTER; const urlPtr = stringToNewUTF8(url); const xmlDocument = new XmlDocument(await xmlReadFile(urlPtr, encodingPtr, parseXmlOptions(options ?? {}))); if (encodingPtr !== NULL_POINTER) { free(encodingPtr); } free(urlPtr); return xmlDocument; } static async fromString(xmlString, { encoding, url, options } = {}) { const xmlStringPtr = xmlString !== "" ? stringToNewUTF8(xmlString) : NULL_POINTER; const urlPtr = url ? stringToNewUTF8(url) : NULL_POINTER; const encodingPtr = encoding ? stringToNewUTF8(encoding) : NULL_POINTER; const xmlDocument = new XmlDocument(await xmlReadDoc(xmlStringPtr, urlPtr, encodingPtr, parseXmlOptions(options ?? {}))); if (encodingPtr !== NULL_POINTER) { free(encodingPtr); } if (urlPtr !== NULL_POINTER) { free(urlPtr); } free(xmlStringPtr); return xmlDocument; } static async fromBuffer(buffer, options) { return this.from(new Uint8Array(buffer), options); } static async from(buffer, { url, encoding, options } = {}) { const bufferPtr = malloc(buffer.byteLength); HEAPU8.set(buffer, bufferPtr); const urlPtr = url ? stringToNewUTF8(url) : NULL_POINTER; const encodingPtr = encoding ? stringToNewUTF8(encoding) : NULL_POINTER; return new XmlDocument(await xmlReadMemory(bufferPtr, buffer.byteLength, urlPtr, encodingPtr, parseXmlOptions(options ?? {}))); } delete() { xmlFreeDoc(this.byteOffset); } /** * Formats the XML document as a string by dumping the XML tree to an * {@link XmlOutputBuffer} and returning its string representation. */ toString(options) { const xmlOutputBuffer = XmlOutputBuffer.allocate(); const encodingPtr = options?.encoding ? stringToNewUTF8(options.encoding) : null; /** * 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.byteOffset ?? NULL_POINTER, /* doc */ this.byteOffset ?? NULL_POINTER, /* cur */ this.byteOffset ?? NULL_POINTER, /* level */ 0, options?.format ? 1 : 0, /* encoding */ encodingPtr ?? NULL_POINTER); 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) { const xmlOutputBuffer = XmlOutputBuffer.allocate(); const encodingPtr = options?.encoding ? stringToNewUTF8(options.encoding) : NULL_POINTER; htmlDocContentDumpFormatOutput(xmlOutputBuffer.byteOffset, this.byteOffset, encodingPtr, options?.format ? 1 : 0); if (encodingPtr !== NULL_POINTER) { 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 };