@mitre/nuxt-smartscript
Version:
Smart typography transformations for Nuxt - automatic superscript, subscript, and symbol formatting
71 lines (70 loc) • 3.1 kB
JavaScript
import { useRuntimeConfig } from "#imports";
import { JSDOM } from "jsdom";
import { mergeConfig } from "../smartscript/config.js";
import { processElement } from "../smartscript/engine.js";
import { logger } from "../smartscript/logger.js";
import { createCombinedPattern, createPatterns } from "../smartscript/patterns.js";
export default (function(nitro) {
nitro.hooks.hook("render:html", (html, { event: _event }) => {
const runtimeConfig = useRuntimeConfig();
const config = runtimeConfig.public?.smartscript;
if (!config || config.ssr === false) {
logger.debug("[Nitro] SSR processing disabled via config");
return;
}
if (html.head?.some((h) => h.includes("smartscript-processed"))) {
logger.debug("[Nitro] Content already processed, skipping");
return;
}
logger.info("[Nitro] Processing HTML for SSR/SSG with jsdom");
try {
const mergedConfig = mergeConfig(config);
const patterns = createPatterns(mergedConfig);
const pattern = createCombinedPattern(patterns, mergedConfig);
if (html.body) {
html.body = html.body.map((bodyHtml, index) => {
logger.debug(`[Nitro] Processing body part ${index + 1}/${html.body.length}`);
if (!bodyHtml || typeof bodyHtml !== "string") {
return bodyHtml;
}
const dom = new JSDOM(bodyHtml);
const document = dom.window.document;
const window = dom.window;
const originalDocument = global.document;
const originalWindow = global.window;
const originalNodeFilter = global.NodeFilter;
const originalHTMLElement = global.HTMLElement;
global.document = document;
global.window = window;
global.NodeFilter = window.NodeFilter;
global.HTMLElement = window.HTMLElement;
try {
const elements = document.querySelectorAll(mergedConfig.selectors.include.join(","));
elements.forEach((element) => {
processElement(element, mergedConfig, patterns, pattern);
});
const transformed = dom.serialize();
if (transformed !== bodyHtml) {
logger.debug("[Nitro] Content was transformed");
}
return transformed;
} finally {
global.document = originalDocument;
global.window = originalWindow;
global.NodeFilter = originalNodeFilter;
global.HTMLElement = originalHTMLElement;
}
});
}
if (config.cssVariables && Object.keys(config.cssVariables).length > 0) {
const cssVars = Object.entries(config.cssVariables).map(([key, value]) => `--ss-${key}: ${value};`).join(" ");
html.head?.push(`<style>:root { ${cssVars} }</style>`);
logger.debug("[Nitro] Added CSS variables to head");
}
html.head?.push('<meta name="smartscript-processed" content="true">');
logger.info("[Nitro] HTML processing complete");
} catch (error) {
logger.error("[Nitro] Error processing HTML:", error);
}
});
});