summaryrefslogtreecommitdiff
path: root/node_modules/@11ty/eleventy/src/Util/HtmlTransformer.js
diff options
context:
space:
mode:
authorShipwreckt <me@shipwreckt.co.uk>2025-10-31 20:02:14 +0000
committerShipwreckt <me@shipwreckt.co.uk>2025-10-31 20:02:14 +0000
commit7a52ddeba2a68388b544f529d2d92104420f77b0 (patch)
tree15ddd47457a2cb4a96060747437d36474e4f6b4e /node_modules/@11ty/eleventy/src/Util/HtmlTransformer.js
parent53d6ae2b5568437afa5e4995580a3fb679b7b91b (diff)
Changed from static to 11ty!
Diffstat (limited to 'node_modules/@11ty/eleventy/src/Util/HtmlTransformer.js')
-rw-r--r--node_modules/@11ty/eleventy/src/Util/HtmlTransformer.js172
1 files changed, 172 insertions, 0 deletions
diff --git a/node_modules/@11ty/eleventy/src/Util/HtmlTransformer.js b/node_modules/@11ty/eleventy/src/Util/HtmlTransformer.js
new file mode 100644
index 0000000..f28910f
--- /dev/null
+++ b/node_modules/@11ty/eleventy/src/Util/HtmlTransformer.js
@@ -0,0 +1,172 @@
+import posthtml from "posthtml";
+import urls from "@11ty/posthtml-urls";
+import { FilePathUtil } from "./FilePathUtil.js";
+
+import { arrayDelete } from "./ArrayUtil.js";
+
+class HtmlTransformer {
+ // feature test for Eleventy Bundle Plugin
+ static SUPPORTS_PLUGINS_ENABLED_CALLBACK = true;
+
+ static TYPES = ["callbacks", "plugins"];
+
+ constructor() {
+ // execution order is important (not order of addition/object key order)
+ this.callbacks = {};
+ this.posthtmlProcessOptions = {};
+ this.plugins = {};
+ }
+
+ get aggregateBench() {
+ if (!this.userConfig) {
+ throw new Error("Internal error: Missing `userConfig` in HtmlTransformer.");
+ }
+ return this.userConfig.benchmarkManager.get("Aggregate");
+ }
+
+ setUserConfig(config) {
+ this.userConfig = config;
+ }
+
+ static prioritySort(a, b) {
+ if (b.priority > a.priority) {
+ return 1;
+ }
+ if (a.priority > b.priority) {
+ return -1;
+ }
+ return 0;
+ }
+
+ // context is important as it is used in html base plugin for page specific URL
+ static _getPosthtmlInstance(callbacks = [], plugins = [], context = {}) {
+ let inst = posthtml();
+
+ // already sorted by priority when added
+ for (let { fn: plugin, options } of plugins) {
+ inst.use(plugin(Object.assign({}, context, options)));
+ }
+
+ // Run the built-ins last
+ if (callbacks.length > 0) {
+ inst.use(
+ urls({
+ eachURL: (url, attrName, tagName) => {
+ for (let { fn: callback } of callbacks) {
+ // already sorted by priority when added
+ url = callback.call(context, url, { attribute: attrName, tag: tagName });
+ }
+
+ return url;
+ },
+ }),
+ );
+ }
+
+ return inst;
+ }
+
+ _add(extensions, addType, value, options = {}) {
+ options = Object.assign(
+ {
+ priority: 0,
+ },
+ options,
+ );
+
+ let extensionsArray = (extensions || "").split(",");
+ for (let ext of extensionsArray) {
+ let target = this[addType];
+ if (!target[ext]) {
+ target[ext] = [];
+ }
+
+ target[ext].push({
+ // *could* fallback to function name, `value.name`
+ name: options.name, // for `remove` and debugging
+ fn: value, // callback or plugin
+ priority: options.priority, // sorted in descending order
+ enabled: options.enabled || (() => true),
+ options: options.pluginOptions,
+ });
+
+ target[ext].sort(HtmlTransformer.prioritySort);
+ }
+ }
+
+ addPosthtmlPlugin(extensions, plugin, options = {}) {
+ this._add(extensions, "plugins", plugin, options);
+ }
+
+ // match can be a plugin function or a filter callback(plugin => true);
+ remove(extensions, match) {
+ for (let removeType of HtmlTransformer.TYPES) {
+ for (let ext of (extensions || "").split(",")) {
+ this[removeType][ext] = arrayDelete(this[removeType][ext], match);
+ }
+ }
+ }
+
+ addUrlTransform(extensions, callback, options = {}) {
+ this._add(extensions, "callbacks", callback, options);
+ }
+
+ setPosthtmlProcessOptions(options) {
+ Object.assign(this.posthtmlProcessOptions, options);
+ }
+
+ isTransformable(extension, context) {
+ return (
+ this.getCallbacks(extension, context).length > 0 || this.getPlugins(extension).length > 0
+ );
+ }
+
+ getCallbacks(extension, context) {
+ let callbacks = this.callbacks[extension] || [];
+ return callbacks.filter(({ enabled }) => {
+ if (!enabled || typeof enabled !== "function") {
+ return true;
+ }
+ return enabled(context);
+ });
+ }
+
+ getPlugins(extension) {
+ let plugins = this.plugins[extension] || [];
+ return plugins.filter(({ enabled }) => {
+ if (!enabled || typeof enabled !== "function") {
+ return true;
+ }
+ return enabled();
+ });
+ }
+
+ static async transformStandalone(content, callback, posthtmlProcessOptions = {}) {
+ let posthtmlInstance = this._getPosthtmlInstance([
+ {
+ fn: callback,
+ enabled: () => true,
+ },
+ ]);
+ let result = await posthtmlInstance.process(content, posthtmlProcessOptions);
+ return result.html;
+ }
+
+ async transformContent(outputPath, content, context) {
+ let extension = FilePathUtil.getFileExtension(outputPath);
+ if (!this.isTransformable(extension, context)) {
+ return content;
+ }
+
+ let bench = this.aggregateBench.get(`Transforming \`${extension}\` with posthtml`);
+ bench.before();
+ let callbacks = this.getCallbacks(extension, context);
+ let plugins = this.getPlugins(extension);
+ let posthtmlInstance = HtmlTransformer._getPosthtmlInstance(callbacks, plugins, context);
+ let result = await posthtmlInstance.process(content, this.posthtmlProcessOptions);
+ bench.after();
+ return result.html;
+ }
+}
+
+export { HtmlTransformer };