El objetivo es construir una aplicación web de página única (SPA) que funcione como un editor visual (WYSIWYG) para modificar archivos de presentaciones HTML generados previamente. Los usuarios podrán cargar una presentación existente, editar textos e imágenes, añadir nuevos elementos con una interfaz de arrastrar y soltar, y guardar el resultado como un nuevo archivo HTML en el servidor.
Administradores de contenido o usuarios que necesitan personalizar las presentaciones generadas por el agente de IA sin necesidad de editar código HTML directamente.
El sistema se divide en tres componentes lógicos principales que se comunican entre sí:
Se debe construir una única página HTML (`editor.html`) que contenga toda la interfaz del editor.
La interfaz se dividirá en tres áreas principales utilizando un sistema de rejilla (grid) de Bootstrap:
<input type="file" id="cargadorHtml" accept=".html">
con un botón estilizado con Bootstrap ("Cargar Presentación").<button id="btnGuardar" class="btn btn-primary">
que iniciará el proceso de guardado. Inicialmente estará deshabilitado.<div class="col-md-2" id="panelNavegacion">
).<div class="col-md-8" id="escenario">
).<iframe id="canvasFrame">
. El uso de un iframe es **crucial** para aislar los estilos de la presentación (Reveal.js) de los estilos del propio editor (Bootstrap).<div class="col-md-2">
) con un sistema de pestañas (Tabs) de Bootstrap.draggable="true"
.draggable="true"
.Este es el núcleo funcional de la aplicación. Se debe escribir en un archivo editor.js
y modularizarlo en responsabilidades.
#cargadorHtml
.FileReader
para leer su contenido como texto (reader.readAsText(file)
).DOMParser
para convertir el string HTML en un documento DOM manipulable (new DOMParser().parseFromString(htmlText, "text/html")
).<section>
.<section>
, generar una miniatura (se puede usar una librería como `html2canvas` para crear una imagen o simplemente mostrar el título) y añadirla al #panelNavegacion
. Almacenar el contenido HTML de cada sección en un arreglo o un objeto para fácil acceso.<section>
en el <iframe id="canvasFrame">
.iframe.contentDocument
) y buscar todos los elementos de texto (`h3`, `p`, `li`, etc.).contenteditable="true"
.[contenteditable="true"]:hover { outline: 1px dashed #3498db; }
) para indicar que es editable.<img>
dentro del iframe, el panel de propiedades debe mostrar un <input type="file" accept="image/*">
.FileReader
para leerla como una URL de datos base64 (reader.readAsDataURL(file)
).src
de la imagen seleccionada se debe actualizar con la nueva URL de datos.draggable="true"
.<iframe>
debe tener listeners para los eventos dragover
(para prevenir el comportamiento por defecto) y drop
.drop
, se debe:
let p = iframe.contentDocument.createElement('p');
).contenteditable="true"
, un texto por defecto, etc.).position: absolute;
y se calcularán sus coordenadas left
y top
basadas en la posición del puntero al momento de soltar.#btnGuardar
, JavaScript debe recorrer todas las diapositivas (almacenadas desde el paso de parseo) y actualizar su contenido HTML con la versión que está actualmente en el DOM del editor.contenteditable="true"
y cualquier estilo de resaltado antes de guardar.<head>
original (con los enlaces a Reveal.js) y el nuevo contenido del <div class="slides">
.fetch
para enviar el string HTML completo y el nombre del archivo original a `guardar_presentacion.php` mediante una petición `POST`.Un script PHP simple (`guardar_presentacion.php`) que no requiere conexión a base de datos.
file_put_contents('ruta/a/presentaciones/' . $nuevo_nombre, $contenido_html)
para guardar el archivo en el servidor.echo json_encode(['success' => true, 'message' => 'Archivo guardado con éxito.']);