UNPKG

@altano/html-cdnify

Version:

Transform the relative URLs in your HTML markup (e.g. scripts, stylesheets, images) to use your CDN URL.

67 lines (65 loc) 2.92 kB
import HtmlTransformer from "./HtmlTransformer.js"; import { groupBy } from "lodash"; //#region src/HtmlAttributeStreamTransformer.ts /** * Wraps a node-trumpet Transform stream, w/ HTML as input and * HTML as output. The output will have all non-absolute-URL * attributes that identify CDN-able resources converted to * use the given CDN URL. */ var HtmlAttributeStreamTransformer = class HtmlAttributeStreamTransformer extends HtmlTransformer { condensedTransformOptions = []; constructor(options) { super(); this.options = options; this.processTransforms(); this.applyTransforms(); } static attributeParsers = { default: (attr, transformFunction) => transformFunction(attr) }; applyTransforms() { this.condensedTransformOptions.forEach((settings) => { const selector = settings.selector; const attribute = settings.attribute; const parser = settings.attributeParser; this.stream.selectAll(selector, (elem) => { const oldAttributeValue = elem.getAttribute(attribute); if (typeof oldAttributeValue === "string") { const newAttributeValue = parser && parser(oldAttributeValue, this.options.transformFunction); if (newAttributeValue && newAttributeValue !== oldAttributeValue) elem.setAttribute(attribute, newAttributeValue); } }); }); const { attributeToMarkElementToBeIgnored } = this.options; if (attributeToMarkElementToBeIgnored) this.stream.selectAll(`[${attributeToMarkElementToBeIgnored}]`, (elem) => { elem.removeAttribute(attributeToMarkElementToBeIgnored); }); } processTransforms() { this.options.transformDefinitions.forEach((option) => { if (!option.attributeParser) option.attributeParser = HtmlAttributeStreamTransformer.attributeParsers["default"]; if (typeof option.selector !== "string") throw new Error(`Invalid selector specified.`); if (typeof option.attribute !== "string") throw new Error(`Invalid attribute specified.`); if (!(option.attributeParser instanceof Function)) throw new Error("Invalid attributeParser specified."); }); /** * As a performance enhancement, we can condense the list of transformDefinitions such that * selectors with the same attribute and attributeParser can be combined into a single, * comma-delimited CSS selector. */ const groupedTransformOptions = groupBy(this.options.transformDefinitions, (obj) => { return [obj.attribute, obj.attributeParser]; }); this.condensedTransformOptions = Object.values(groupedTransformOptions).map((likeTransformOptions) => { const attribute = likeTransformOptions[0].attribute; const attributeParser = likeTransformOptions[0].attributeParser; return { attribute, attributeParser, selector: likeTransformOptions.map((likeTransformOption) => likeTransformOption.selector).join(", ") }; }); } }; //#endregion export { HtmlAttributeStreamTransformer }; //# sourceMappingURL=HtmlAttributeStreamTransformer.js.map