├── .gitignore ├── Idea for compile time javascript.md ├── LICENSE ├── README.md ├── dist ├── index.d.ts ├── index.js └── src │ ├── DebugMode.d.ts │ ├── DebugMode.js │ ├── Mesa.d.ts │ ├── Mesa.js │ ├── assets │ └── ClientHMRHandler.js │ ├── component.d.ts │ ├── component.js │ ├── components.d.ts │ ├── components.js │ ├── folder.d.ts │ ├── folder.js │ ├── helpers │ ├── SyntaxCoding.d.ts │ ├── SyntaxCoding.js │ ├── createNamesForPaths.d.ts │ ├── createNamesForPaths.js │ ├── getAllChildrenOfFolder.d.ts │ ├── getAllChildrenOfFolder.js │ ├── toKebabCase.d.ts │ ├── toKebabCase.js │ ├── traverseElementChildren.d.ts │ ├── traverseElementChildren.js │ ├── variableToString.d.ts │ ├── variableToString.js │ ├── walkTextNodes.d.ts │ └── walkTextNodes.js │ ├── hmr │ ├── MesaHMR.d.ts │ └── MesaHMR.js │ ├── log.d.ts │ ├── log.js │ ├── logText.d.ts │ ├── logText.js │ ├── mesa-js │ ├── analyzeInlineMesaJs.d.ts │ ├── analyzeInlineMesaJs.js │ ├── analyzeMesaJs.d.ts │ ├── analyzeMesaJs.js │ ├── compileMesaJs.d.ts │ ├── compileMesaJs.js │ ├── findMesaJS.d.ts │ ├── findMesaJS.js │ ├── operator-compilers │ │ ├── compileForOperator.d.ts │ │ ├── compileForOperator.js │ │ ├── compileOperators.d.ts │ │ └── compileOperators.js │ ├── removeMesaJs.d.ts │ ├── removeMesaJs.js │ └── types │ │ ├── ArrayVariable.d.ts │ │ ├── ArrayVariable.js │ │ ├── BooleanVariable.d.ts │ │ ├── BooleanVariable.js │ │ ├── NumberVariable.d.ts │ │ ├── NumberVariable.js │ │ ├── StringVariable.d.ts │ │ ├── StringVariable.js │ │ ├── Variable.d.ts │ │ └── Variable.js │ ├── methods │ ├── ProcessHtmlCache.d.ts │ ├── ProcessHtmlCache.js │ ├── convertRelativeToAbsolutePaths.d.ts │ ├── convertRelativeToAbsolutePaths.js │ ├── convertToNonSelfClosing.d.ts │ ├── convertToNonSelfClosing.js │ ├── createComparisonHash.d.ts │ ├── createComparisonHash.js │ ├── element-attributes │ │ ├── getElementAttributes.d.ts │ │ ├── getElementAttributes.js │ │ ├── setElementAttributes.d.ts │ │ └── setElementAttributes.js │ ├── extractBodyContent.d.ts │ ├── extractBodyContent.js │ ├── extractLinksAndScriptsOfBody.d.ts │ ├── extractLinksAndScriptsOfBody.js │ ├── findElementsWithTags.d.ts │ ├── findElementsWithTags.js │ ├── generateUniqueHash.d.ts │ ├── generateUniqueHash.js │ ├── getAbsolutePathOfSource.d.ts │ ├── getAbsolutePathOfSource.js │ ├── getAllTagNames.d.ts │ ├── getAllTagNames.js │ ├── getAttributesOfChildElements.d.ts │ ├── getAttributesOfChildElements.js │ ├── getCurrentEntry.d.ts │ ├── getCurrentEntry.js │ ├── getFileName.d.ts │ ├── getFileName.js │ ├── getHtmlFiles.d.ts │ ├── getHtmlFiles.js │ ├── getHtmlForSource.d.ts │ ├── getHtmlForSource.js │ ├── getTagName.d.ts │ ├── getTagName.js │ ├── getTagsUsedInHtml.d.ts │ ├── getTagsUsedInHtml.js │ ├── inner-html │ │ ├── getInnerHtml.d.ts │ │ ├── getInnerHtml.js │ │ ├── setInnerHtml.d.ts │ │ └── setInnerHtml.js │ ├── processHtml.d.ts │ ├── processHtml.js │ ├── processHtmlAndInjectCss.d.ts │ ├── processHtmlAndInjectCss.js │ ├── setAttr.d.ts │ ├── setAttr.js │ ├── setHotModuleReloadID.d.ts │ ├── setHotModuleReloadID.js │ ├── setSlot.d.ts │ ├── setSlot.js │ ├── splitHtmlCSSAndJS.d.ts │ ├── splitHtmlCSSAndJS.js │ ├── splitHtmlCSSAndJSFromComponents.d.ts │ ├── splitHtmlCSSAndJSFromComponents.js │ ├── uniqueIdForFile.d.ts │ └── uniqueIdForFile.js │ ├── types │ ├── ComponentSource.d.ts │ ├── ComponentSource.js │ ├── ComponentsMap.d.ts │ ├── ComponentsMap.js │ ├── ElementAttributes.d.ts │ └── ElementAttributes.js │ └── universal │ ├── ensureModule.d.ts │ ├── ensureModule.js │ ├── generateRandomId.d.ts │ ├── generateRandomId.js │ ├── getHtmlInputsOfViteInput.d.ts │ ├── getHtmlInputsOfViteInput.js │ └── js-html │ ├── convertExportToHtml.d.ts │ ├── convertExportToHtml.js │ ├── convertHtmlToExport.d.ts │ └── convertHtmlToExport.js ├── index.ts ├── package.json ├── plans.md ├── props idea 2.0.md ├── props idea.md ├── src ├── DebugMode.ts ├── Mesa.ts ├── assets │ └── ClientHMRHandler.js ├── component.ts ├── components.ts ├── folder.ts ├── helpers │ ├── SyntaxCoding.ts │ ├── createNamesForPaths.ts │ ├── getAllChildrenOfFolder.ts │ ├── toKebabCase.ts │ ├── traverseElementChildren.ts │ ├── variableToString.ts │ └── walkTextNodes.ts ├── hmr │ └── MesaHMR.ts ├── log.ts ├── logText.ts ├── mesa-js │ ├── analyzeInlineMesaJs.ts │ ├── analyzeMesaJs.ts │ ├── compileMesaJs.ts │ ├── findMesaJS.ts │ ├── operator-compilers │ │ ├── compileForOperator.ts │ │ ├── compileOperators.ts │ │ ├── example.html │ │ └── test.js │ ├── removeMesaJs.ts │ └── types │ │ ├── ArrayVariable.ts │ │ ├── BooleanVariable.ts │ │ ├── NumberVariable.ts │ │ ├── StringVariable.ts │ │ └── Variable.ts ├── methods │ ├── ProcessHtmlCache.ts │ ├── convertRelativeToAbsolutePaths.ts │ ├── convertToNonSelfClosing.ts │ ├── createComparisonHash.ts │ ├── element-attributes │ │ ├── getElementAttributes.ts │ │ └── setElementAttributes.ts │ ├── extractBodyContent.ts │ ├── extractLinksAndScriptsOfBody.ts │ ├── findElementsWithTags.ts │ ├── generateUniqueHash.ts │ ├── getAbsolutePathOfSource.ts │ ├── getAllTagNames.ts │ ├── getAttributesOfChildElements.ts │ ├── getCurrentEntry.ts │ ├── getFileName.ts │ ├── getHtmlFiles.ts │ ├── getHtmlForSource.ts │ ├── getTagName.ts │ ├── getTagsUsedInHtml.ts │ ├── inner-html │ │ ├── getInnerHtml.ts │ │ └── setInnerHtml.ts │ ├── processHtml.ts │ ├── processHtmlAndInjectCss.ts │ ├── setAttr.ts │ ├── setHotModuleReloadID.ts │ ├── setSlot.ts │ ├── splitHtmlCSSAndJS.ts │ ├── splitHtmlCSSAndJSFromComponents.ts │ └── uniqueIdForFile.ts ├── types │ ├── ComponentSource.ts │ ├── ComponentsMap.ts │ └── ElementAttributes.ts └── universal │ ├── ensureModule.ts │ ├── generateRandomId.ts │ ├── getHtmlInputsOfViteInput.ts │ └── js-html │ ├── convertExportToHtml.ts │ └── convertHtmlToExport.ts ├── tsconfig.json └── vite.config.ts /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | !dist/ -------------------------------------------------------------------------------- /Idea for compile time javascript.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ```html 4 | 18 | 19 | 24 | segment.default 25 | ``` 26 | 27 | Gets compiled to: 28 | ```html 29 |
30 |
31 | Document Tools 32 |
33 |
34 | 3D Configurators 35 |
36 |
37 | ``` -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 octamap 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /dist/index.d.ts: -------------------------------------------------------------------------------- 1 | import Mesa from "./src/Mesa.js"; 2 | import component from "./src/component.js"; 3 | import components from "./src/components.js"; 4 | import folder from "./src/folder.js"; 5 | import ComponentSource from "./src/types/ComponentSource.js"; 6 | import ComponentsMap from "./src/types/ComponentsMap.js"; 7 | export type { ComponentsMap, ComponentSource, }; 8 | export { Mesa, component, components, folder }; 9 | -------------------------------------------------------------------------------- /dist/index.js: -------------------------------------------------------------------------------- 1 | import Mesa from "./src/Mesa.js"; 2 | import component from "./src/component.js"; 3 | import components from "./src/components.js"; 4 | import folder from "./src/folder.js"; 5 | export { Mesa, component, components, folder }; 6 | -------------------------------------------------------------------------------- /dist/src/DebugMode.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace DebugMode { 2 | let Enabled: boolean; 3 | } 4 | export default DebugMode; 5 | -------------------------------------------------------------------------------- /dist/src/DebugMode.js: -------------------------------------------------------------------------------- 1 | var DebugMode; 2 | (function (DebugMode) { 3 | DebugMode.Enabled = false; 4 | })(DebugMode || (DebugMode = {})); 5 | export default DebugMode; 6 | -------------------------------------------------------------------------------- /dist/src/Mesa.d.ts: -------------------------------------------------------------------------------- 1 | import { Plugin } from 'vite'; 2 | import ComponentsMap from './types/ComponentsMap.js'; 3 | export default function Mesa(componentsSource: ComponentsMap | (() => ComponentsMap), options?: { 4 | debugMode?: boolean; 5 | }): Plugin; 6 | -------------------------------------------------------------------------------- /dist/src/assets/ClientHMRHandler.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | if (import.meta.hot) { 3 | import.meta.hot.on('mesa-style-update', ({ componentName, style }) => { 4 | const cssStart = '/*start:' + componentName + '*/'; 5 | const cssEnd = '/*end:' + componentName + '*/'; 6 | // Construct the new CSS block 7 | const newText = style == null ? "" : `${cssStart}\n${style}\n${cssEnd}`; 8 | const existingStyleElements = document.querySelectorAll("style[mesa]"); 9 | 10 | if (existingStyleElements.length === 0) { 11 | if (style != null) { 12 | // Create a new `); 37 | } 38 | else { 39 | // Add a new `; 41 | html = style + "\n" + html; 42 | } 43 | } 44 | if (scriptsToImport.length > 0) { 45 | const newScripts = scriptsToImport.join(";\n"); 46 | const script = ``; 47 | html = script + "\n" + html; 48 | } 49 | return { ...response, html }; 50 | } 51 | -------------------------------------------------------------------------------- /dist/src/methods/setAttr.d.ts: -------------------------------------------------------------------------------- 1 | export default function setAttr(attr: Attr, element: Element): void; 2 | -------------------------------------------------------------------------------- /dist/src/methods/setAttr.js: -------------------------------------------------------------------------------- 1 | export default function setAttr(attr, element) { 2 | try { 3 | const operators = [ 4 | { 5 | name: "add:", 6 | handler: (name, currentValue) => { 7 | if (!currentValue) { 8 | element.setAttribute(name, attr.value); 9 | } 10 | else { 11 | element.setAttribute(name, [currentValue, attr.value].join(" ")); 12 | } 13 | } 14 | }, 15 | { 16 | name: "remove:", 17 | handler: (name, currentValue) => { 18 | if (!currentValue) { 19 | return; 20 | } 21 | let c = currentValue; 22 | attr.value.split(" ").filter(x => x.length).forEach(x => { 23 | c = c.replaceAll(x, ""); 24 | }); 25 | element.setAttribute(name, c); 26 | } 27 | } 28 | ]; 29 | for (const { name, handler } of operators) { 30 | if (attr.name.startsWith(name) && attr.name.length > name.length) { 31 | const realName = attr.name.slice(name.length, attr.name.length); 32 | const currentValue = element.getAttribute(realName); 33 | handler(realName, currentValue); 34 | return; 35 | } 36 | } 37 | if (attr.name.startsWith("@")) { 38 | element.setAttribute(`mesa-at-${attr.name.slice(1)}`, attr.value); 39 | } 40 | else if (attr.name.startsWith("#")) { 41 | element.setAttribute(`mesa-hash-${attr.name.slice(1)}`, attr.value); 42 | } 43 | else { 44 | element.setAttribute(attr.name, attr.value); 45 | } 46 | } 47 | catch (error) { 48 | throw new Error(`Issue while trying to set value: ${attr.value} on attribute with name: ${attr.name}, error: ${error?.message ?? ``}`); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /dist/src/methods/setHotModuleReloadID.d.ts: -------------------------------------------------------------------------------- 1 | export default function setHotModuleReloadId(content: string, id: string, usedHotModuleIds: Map): string; 2 | -------------------------------------------------------------------------------- /dist/src/methods/setHotModuleReloadID.js: -------------------------------------------------------------------------------- 1 | export default function setHotModuleReloadId(content, id, usedHotModuleIds) { 2 | // We'll match opening or closing tags, capturing the tag name. 3 | const tagRegex = /<\/?([a-z][^/\s>]*)[^>]*>/gi; 4 | let nestingLevel = 0; 5 | let lastIndex = 0; 6 | let result = ''; 7 | let match; 8 | while ((match = tagRegex.exec(content)) !== null) { 9 | // text up to the current tag 10 | result += content.substring(lastIndex, match.index); 11 | const fullTag = match[0]; // e.g. "
" or "" 12 | const isClosingTag = fullTag.startsWith(' reduce nesting 15 | nestingLevel--; 16 | result += fullTag; 17 | } 18 | else { 19 | // opening or self-closing 20 | const selfClosing = /\/>$/.test(fullTag.trim()); 21 | // If nesting is 0 before this tag, it's a root-level element 22 | if (nestingLevel === 0) { 23 | // Inject mesa-hmr-id right after the tag name 24 | // We'll do a simple replace to insert the attribute 25 | const injectedTag = fullTag.replace(/^<([a-zA-Z0-9-]+)(\s|>|$)/, (_, tagName, trailing) => { 26 | const timesUsed = usedHotModuleIds.get(id) ?? 0; 27 | usedHotModuleIds.set(id, timesUsed + 1); 28 | // Ensure trailing space or `>` is handled correctly 29 | return `<${tagName} mesa-hmr="${id}${timesUsed === 0 ? '' : `:${timesUsed + 1}`}"${trailing}`; 30 | }); 31 | result += injectedTag; 32 | } 33 | else { 34 | // not at root, just keep the tag as is 35 | result += fullTag; 36 | } 37 | // Increase nesting if it's not self-closing 38 | if (!selfClosing) { 39 | nestingLevel++; 40 | } 41 | } 42 | // Move index after this tag 43 | lastIndex = tagRegex.lastIndex; 44 | } 45 | // Append remaining text after the last match 46 | result += content.substring(lastIndex); 47 | return result; 48 | } 49 | -------------------------------------------------------------------------------- /dist/src/methods/setSlot.d.ts: -------------------------------------------------------------------------------- 1 | export default function setSlot(element: Element, newContent: string): void; 2 | -------------------------------------------------------------------------------- /dist/src/methods/setSlot.js: -------------------------------------------------------------------------------- 1 | export default function setSlot(element, newContent) { 2 | const slotBehaviour = element?.getAttribute("m-slot"); 3 | switch (slotBehaviour) { 4 | case "insertAtStart": 5 | element.innerHTML = newContent + element.innerHTML; 6 | break; 7 | case "insertAtEnd": 8 | element.innerHTML = element.innerHTML + newContent; 9 | break; 10 | default: 11 | element.innerHTML = newContent; 12 | break; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /dist/src/methods/splitHtmlCSSAndJS.d.ts: -------------------------------------------------------------------------------- 1 | export default function splitHtmlCSSAndJS(input: string, allTagNames: string[], inputFilePath?: string | null): [string, string | null, string | null]; 2 | -------------------------------------------------------------------------------- /dist/src/methods/splitHtmlCSSAndJS.js: -------------------------------------------------------------------------------- 1 | import convertRelativeToAbsolutePaths from "./convertRelativeToAbsolutePaths.js"; 2 | export default function splitHtmlCSSAndJS(input, allTagNames, inputFilePath) { 3 | try { 4 | if (!input.includes(" 69 | 70 | ``` 71 | 72 | Usage 73 | ```html 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | ``` 82 | 83 | Becomes 84 | 85 | ```html 86 | 87 | 88 | 89 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 137 | 143 | 144 | 145 | ``` -------------------------------------------------------------------------------- /src/DebugMode.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | namespace DebugMode { 4 | 5 | export let Enabled = false; 6 | 7 | 8 | } 9 | 10 | export default DebugMode -------------------------------------------------------------------------------- /src/assets/ClientHMRHandler.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | if (import.meta.hot) { 3 | import.meta.hot.on('mesa-style-update', ({ componentName, style }) => { 4 | const cssStart = '/*start:' + componentName + '*/'; 5 | const cssEnd = '/*end:' + componentName + '*/'; 6 | // Construct the new CSS block 7 | const newText = style == null ? "" : `${cssStart}\n${style}\n${cssEnd}`; 8 | const existingStyleElements = document.querySelectorAll("style[mesa]"); 9 | 10 | if (existingStyleElements.length === 0) { 11 | if (style != null) { 12 | // Create a new `); 49 | } else { 50 | // Add a new `; 52 | html = style + "\n" + html; 53 | } 54 | } 55 | if (scriptsToImport.length > 0) { 56 | const newScripts = scriptsToImport.join(";\n") 57 | const script = `` 58 | html = script + "\n" + html 59 | } 60 | return {...response, html} 61 | } -------------------------------------------------------------------------------- /src/methods/setAttr.ts: -------------------------------------------------------------------------------- 1 | 2 | export default function setAttr(attr: Attr, element: Element) { 3 | try { 4 | const operators: { name: string, handler: (name: string, currentValue: string | null) => void }[] = [ 5 | { 6 | name: "add:", 7 | handler: (name, currentValue) => { 8 | if (!currentValue) { 9 | element.setAttribute(name, attr.value) 10 | } else { 11 | element.setAttribute(name, [currentValue, attr.value].join(" ")) 12 | } 13 | } 14 | }, 15 | { 16 | name: "remove:", 17 | handler: (name, currentValue) => { 18 | if (!currentValue) { 19 | return; 20 | } 21 | let c = currentValue 22 | attr.value.split(" ").filter(x => x.length).forEach(x => { 23 | c = c.replaceAll(x, "") 24 | }) 25 | element.setAttribute(name, c) 26 | } 27 | } 28 | ] 29 | for (const { name, handler } of operators) { 30 | if (attr.name.startsWith(name) && attr.name.length > name.length) { 31 | const realName = attr.name.slice(name.length, attr.name.length) 32 | const currentValue = element.getAttribute(realName) 33 | handler(realName, currentValue) 34 | return; 35 | } 36 | } 37 | if (attr.name.startsWith("@")) { 38 | element.setAttribute(`mesa-at-${attr.name.slice(1)}`, attr.value) 39 | } else if (attr.name.startsWith("#")) { 40 | element.setAttribute(`mesa-hash-${attr.name.slice(1)}`, attr.value) 41 | } else { 42 | element.setAttribute(attr.name, attr.value) 43 | } 44 | } catch (error) { 45 | throw new Error(`Issue while trying to set value: ${attr.value} on attribute with name: ${attr.name}, error: ${(error as any)?.message ?? ``}`) 46 | } 47 | } -------------------------------------------------------------------------------- /src/methods/setHotModuleReloadID.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | export default function setHotModuleReloadId(content: string, id: string, usedHotModuleIds: Map): string { 5 | // We'll match opening or closing tags, capturing the tag name. 6 | const tagRegex = /<\/?([a-z][^/\s>]*)[^>]*>/gi; 7 | 8 | let nestingLevel = 0; 9 | let lastIndex = 0; 10 | let result = ''; 11 | 12 | let match: RegExpExecArray | null; 13 | 14 | while ((match = tagRegex.exec(content)) !== null) { 15 | // text up to the current tag 16 | result += content.substring(lastIndex, match.index); 17 | const fullTag = match[0]; // e.g. "
" or "" 18 | const isClosingTag = fullTag.startsWith(' reduce nesting 22 | nestingLevel--; 23 | result += fullTag; 24 | } else { 25 | // opening or self-closing 26 | const selfClosing = /\/>$/.test(fullTag.trim()); 27 | 28 | // If nesting is 0 before this tag, it's a root-level element 29 | if (nestingLevel === 0) { 30 | // Inject mesa-hmr-id right after the tag name 31 | // We'll do a simple replace to insert the attribute 32 | const injectedTag = fullTag.replace( 33 | /^<([a-zA-Z0-9-]+)(\s|>|$)/, 34 | (_, tagName, trailing) => { 35 | const timesUsed = usedHotModuleIds.get(id) ?? 0; 36 | usedHotModuleIds.set(id, timesUsed + 1); 37 | 38 | // Ensure trailing space or `>` is handled correctly 39 | return `<${tagName} mesa-hmr="${id}${timesUsed === 0 ? '' : `:${timesUsed + 1}`}"${trailing}`; 40 | } 41 | ); 42 | result += injectedTag; 43 | } else { 44 | // not at root, just keep the tag as is 45 | result += fullTag; 46 | } 47 | 48 | // Increase nesting if it's not self-closing 49 | if (!selfClosing) { 50 | nestingLevel++; 51 | } 52 | } 53 | 54 | // Move index after this tag 55 | lastIndex = tagRegex.lastIndex; 56 | } 57 | 58 | // Append remaining text after the last match 59 | result += content.substring(lastIndex); 60 | 61 | return result; 62 | } -------------------------------------------------------------------------------- /src/methods/setSlot.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | export default function setSlot(element: Element, newContent: string) { 5 | const slotBehaviour = element?.getAttribute("m-slot") 6 | switch (slotBehaviour) { 7 | case "insertAtStart": 8 | element.innerHTML = newContent + element.innerHTML 9 | break; 10 | case "insertAtEnd": 11 | element.innerHTML = element.innerHTML + newContent 12 | break; 13 | default: 14 | element.innerHTML = newContent 15 | break; 16 | } 17 | } -------------------------------------------------------------------------------- /src/methods/splitHtmlCSSAndJS.ts: -------------------------------------------------------------------------------- 1 | import convertRelativeToAbsolutePaths from "./convertRelativeToAbsolutePaths.js"; 2 | 3 | export default function splitHtmlCSSAndJS(input: string, allTagNames: string[], inputFilePath?: string | null): [string, string | null, string | null] { 4 | try { 5 | if (!input.includes("