UNPKG

@idomatic/parser-html

Version:

HTML/Vue/Angular parser for idomatic CLI

78 lines (64 loc) 2.87 kB
import MagicString from "magic-string"; import { randomUUID } from "crypto"; /** * Processes a Vue template content by inserting unique IDs while preserving formatting. * * @param {string} templateContent - The content inside the Vue <template> tag. * @param {object} config - The configuration object. * @param {string} config.attributeName - The attribute name to add (e.g. "id" or "data-id"). * @param {string} config.prefix - The prefix for generated IDs. * @param {string[]} [config.excludeTags] - An array of tag names to exclude (optional). * @returns {string} - The updated template content. */ export function processVueTemplate(templateContent, config) { const { attributeName, prefix, excludeTags = [] } = config; const ms = new MagicString(templateContent); // A generic regex to match opening tags: // - It captures the tag name and its attributes. // - This regex is simplified, so you might need additional adjustments for complex cases. const tagRegex = /<([a-zA-Z][^\s/>]*)([^>]*?)(\/?)>/g; let match; while ((match = tagRegex.exec(templateContent)) !== null) { const fullMatch = match[0]; // entire opening tag text const tagName = match[1]; // tag name, e.g., v-btn, i, etc. const attributesStr = match[2]; // all attributes as a string const selfClosing = match[3] || ""; // self-closing slash if present // If the tag is in the exclude list, skip processing. if (excludeTags.includes(tagName)) continue; // Check if this tag already has the attribute const idRegex = new RegExp(`\\s${attributeName}\\s*=`); if (idRegex.test(attributesStr)) continue; // Insert the attribute just before the closing of the tag. // We subtract the length of any trailing self-closing slash and the ">" character. const insertPosition = match.index + fullMatch.length - (selfClosing.length + 1); ms.appendLeft( insertPosition, ` ${attributeName}="${prefix}${randomUUID()}"` ); } return ms.toString(); } export function processHtmlContent(htmlContent, config) { const { attributeName, prefix, excludeTags = [] } = config; const ms = new MagicString(htmlContent); // This regex is similar to the Vue one. const tagRegex = /<([a-zA-Z][^\s/>]*)([^>]*?)(\/?)>/g; let match; while ((match = tagRegex.exec(htmlContent)) !== null) { const fullMatch = match[0]; const tagName = match[1]; const attributesStr = match[2]; const selfClosing = match[3] || ""; if (excludeTags.includes(tagName)) continue; const idRegex = new RegExp(`\\s${attributeName}\\s*=`); if (idRegex.test(attributesStr)) continue; const insertPosition = match.index + fullMatch.length - (selfClosing.length + 1); ms.appendLeft( insertPosition, ` ${attributeName}="${prefix}${randomUUID()}"` ); } return ms.toString(); }