feat: code blocks beta
This commit is contained in:
parent
362b7aa15e
commit
1ecb6d8682
19 changed files with 756 additions and 94 deletions
|
@ -6,6 +6,8 @@ const StandardElementGenerator = require("./generators/StandardElementGenerator"
|
|||
const RootNodeGenerator = require("./generators/RootNodeGenerator");
|
||||
const InputElementGenerator = require("./generators/InputElementGenerator");
|
||||
const MediaElementGenerator = require("./generators/MediaElementGenerator");
|
||||
const JavaScriptGenerator = require("./generators/JavaScriptGenerator");
|
||||
const ServerCodeGenerator = require("./generators/ServerCodeGenerator");
|
||||
const HTMLTemplate = require("./templates/HTMLTemplate");
|
||||
const StringUtils = require("./utils/StringUtils");
|
||||
|
||||
|
@ -21,6 +23,9 @@ class HTMLGenerator {
|
|||
this.options = options;
|
||||
this.cssGenerator = cssGenerator;
|
||||
this.htmlTemplate = new HTMLTemplate(options);
|
||||
this.serverGenerator = new ServerCodeGenerator(options);
|
||||
this.jsGenerator = new JavaScriptGenerator(options, this.serverGenerator);
|
||||
this.currentElement = null;
|
||||
|
||||
|
||||
this.generators = [
|
||||
|
@ -86,6 +91,10 @@ class HTMLGenerator {
|
|||
console.log("[HTMLGenerator] Node details:", StringUtils.safeStringify(node));
|
||||
}
|
||||
|
||||
// Handle client and server blocks
|
||||
if (node.type === "client" || node.type === "server") {
|
||||
return this.handleScriptBlock(node);
|
||||
}
|
||||
|
||||
if (node.type === "element" && node.tag === "page") {
|
||||
if (this.options.debug) {
|
||||
|
@ -94,20 +103,120 @@ class HTMLGenerator {
|
|||
return "";
|
||||
}
|
||||
|
||||
const prevElement = this.currentElement;
|
||||
this.currentElement = node;
|
||||
|
||||
// Check if this element has an explicit ID in its props
|
||||
if (node.type === "element") {
|
||||
const idProp = node.props.find(p => typeof p === "string" && p.startsWith("id:"));
|
||||
if (idProp) {
|
||||
const idValue = idProp.substring(idProp.indexOf(":") + 1).trim().replace(/^"|"$/g, "");
|
||||
node.elementId = idValue;
|
||||
|
||||
// Register this element as reactive
|
||||
this.jsGenerator.registerReactiveElement(idValue);
|
||||
|
||||
if (this.options.debug) {
|
||||
console.log(`[HTMLGenerator] Found explicit ID: ${idValue}, registered as reactive`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let result = "";
|
||||
for (const generator of this.generators) {
|
||||
if (generator.canHandle(node)) {
|
||||
if (this.options.debug) {
|
||||
console.log(`[HTMLGenerator] Using ${generator.constructor.name} for node`);
|
||||
}
|
||||
return generator.generate(node);
|
||||
|
||||
// If this is an element that might have event handlers,
|
||||
// add a unique ID to it for client scripts if it doesn't already have one
|
||||
if (node.type === "element" && node.children.some(child => child.type === "client")) {
|
||||
// Generate a unique ID for this element if it doesn't already have one
|
||||
if (!node.elementId) {
|
||||
node.elementId = this.jsGenerator.generateElementId();
|
||||
if (this.options.debug) {
|
||||
console.log(`[HTMLGenerator] Generated ID for element: ${node.elementId}`);
|
||||
}
|
||||
}
|
||||
|
||||
result = generator.generate(node);
|
||||
|
||||
// Process all client blocks inside this element
|
||||
node.children
|
||||
.filter(child => child.type === "client")
|
||||
.forEach(clientBlock => {
|
||||
this.handleScriptBlock(clientBlock, node.elementId);
|
||||
});
|
||||
} else {
|
||||
result = generator.generate(node);
|
||||
}
|
||||
|
||||
this.currentElement = prevElement;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (this.options.debug) {
|
||||
console.log(`[HTMLGenerator] No generator found for node type: ${node.type}`);
|
||||
}
|
||||
|
||||
this.currentElement = prevElement;
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles client and server script blocks.
|
||||
* @param {Object} node - The script node to handle
|
||||
* @param {string} [elementId] - The ID of the parent element, if any
|
||||
* @returns {string} - Empty string as script blocks don't directly generate HTML
|
||||
*/
|
||||
handleScriptBlock(node, elementId = null) {
|
||||
if (this.options.debug) {
|
||||
console.log(`\n[HTMLGenerator] Processing ${node.type} script block`);
|
||||
console.log(`[HTMLGenerator] Script content (first 50 chars): "${node.script.substring(0, 50)}..."`);
|
||||
if (elementId) {
|
||||
console.log(`[HTMLGenerator] Attaching to element: ${elementId}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (node.type === "client") {
|
||||
if (!elementId && this.currentElement) {
|
||||
if (!this.currentElement.elementId) {
|
||||
this.currentElement.elementId = this.jsGenerator.generateElementId();
|
||||
}
|
||||
elementId = this.currentElement.elementId;
|
||||
}
|
||||
|
||||
if (elementId) {
|
||||
this.jsGenerator.addClientScript(elementId, node.script);
|
||||
} else {
|
||||
if (this.options.debug) {
|
||||
console.log(`[HTMLGenerator] Warning: Client script with no parent element`);
|
||||
}
|
||||
}
|
||||
} else if (node.type === "server") {
|
||||
if (!elementId && this.currentElement) {
|
||||
if (!this.currentElement.elementId) {
|
||||
this.currentElement.elementId = this.jsGenerator.generateElementId();
|
||||
}
|
||||
elementId = this.currentElement.elementId;
|
||||
}
|
||||
|
||||
if (elementId) {
|
||||
const params = node.params || [];
|
||||
if (this.options.debug && params.length > 0) {
|
||||
console.log(`[HTMLGenerator] Server block parameters: ${params.join(", ")}`);
|
||||
}
|
||||
|
||||
this.jsGenerator.addServerScript(elementId, node.script, params);
|
||||
} else {
|
||||
if (this.options.debug) {
|
||||
console.log(`[HTMLGenerator] Warning: Server script with no parent element`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
@ -177,7 +286,28 @@ class HTMLGenerator {
|
|||
* @returns {string} - A complete HTML document containing the provided head and body content.
|
||||
*/
|
||||
generateFinalHtml(headContent, bodyContent) {
|
||||
return this.htmlTemplate.generateDocument(headContent, bodyContent);
|
||||
const clientScripts = this.jsGenerator.generateClientScripts();
|
||||
|
||||
return this.htmlTemplate.generateDocument(
|
||||
headContent,
|
||||
bodyContent + clientScripts
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates server-side code for Express.js API routes.
|
||||
* @returns {string} - Express.js server code
|
||||
*/
|
||||
generateServerCode() {
|
||||
return this.serverGenerator.generateServerCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there is any server code to generate.
|
||||
* @returns {boolean} - Whether there is server code
|
||||
*/
|
||||
hasServerCode() {
|
||||
return this.serverGenerator.hasServerCodeToGenerate();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue