1 Documentación código (tabs.js)
johan.ocampo edited this page 7 months ago

1. tabs.js.

Este archivo es el encargado de crear, cargar y enviar la información de cada una de las pestañas para que finalmente sean almacenadas.

1.1. Variables globales.

tabCount: Lleva un registro del número total de pestañas creadas. Se utiliza para asignar IDs únicos a cada nueva pestaña.

activeTabId: Guarda el ID de la pestaña actualmente activa. Es null cuando no hay ninguna pestaña activa.

tabNodes: Un objeto que almacena los nodos asociados a cada pestaña. La clave es el ID de la pestaña y el valor es un array de nodos.

tabConnections: Similar a tabNodes, pero almacena las conexiones entre nodos para cada pestaña.

1.2. AddEvenListener

DOMContentLoaded: Este evento se dispara cuando el documento HTML ha sido completamente cargado y parseado. Dentro de este evento:

loadExistingTabs(): Llama a la función que carga las pestañas existentes desde el servidor.

Botón de Crear Pestaña: Se agrega un listener al botón con ID "createTabButton". Al hacer clic, se solicita al usuario que ingrese un nombre para la nueva pestaña (por defecto, "Pestaña X"). Si el usuario proporciona un nombre, se llama a createNewTab(tabName) para crear la pestaña.

1.3. Función getCSRFToken

Propósito: Recuperar el token CSRF (Cross-Site Request Forgery) de las cookies. Este token es esencial para proteger las solicitudes POST contra ataques CSRF.

Funcionamiento:

Define el nombre de la cookie que contiene el token CSRF ('csrftoken').

Verifica si existen cookies en document.cookie.

Divide las cookies en un array utilizando ; como separador.

Itera sobre cada cookie, elimina espacios en blanco y verifica si comienza con 'csrftoken='.

Si encuentra la cookie, decodifica su valor y lo retorna.

Funciones para Crear y Eliminar Menú Contextual

1.4. createContextMenu

Propósito: Crear un menú contextual (apariencia de menú al hacer clic derecho) en las coordenadas (x, y) con las opciones proporcionadas.

Parámetros:

x y y: Coordenadas donde se mostrará el menú.

options: Array de objetos que contienen label (texto del menú) y action (función a ejecutar al hacer clic).

Funcionamiento:

Llama a removeContextMenu() para asegurarse de que no haya menús contextuales existentes.

Crea un div con clase 'context-menu' y lo posiciona en (x, y).

Itera sobre las options, crea un div para cada opción con clase 'context-menu-item', establece su texto y agrega un listener para el evento 'click' que ejecuta la acción correspondiente.

Añade el menú al body del documento y le agrega la clase 'show' para mostrarlo.

Agrega un listener al documento para cerrar el menú cuando se haga clic en cualquier parte.

1.5. removeContextMenu

Propósito: Eliminar cualquier menú contextual existente del DOM.

Funcionamiento:

Busca un elemento con la clase 'context-menu'.

Si existe, lo elimina del DOM.

Remueve el listener 'click' que fue agregado en createContextMenu para evitar múltiples escuchas.

1.6. Carga de Pestañas Existentes

Propósito: Cargar las pestañas previamente existentes desde el servidor al iniciar la aplicación.

Funcionamiento:

Realiza una solicitud fetch a la ruta '/list-tabs/' para obtener la lista de pestañas.

Si la respuesta es exitosa (response.ok), parsea el JSON recibido.

Itera sobre cada pestaña en data.tabs y llama a createNewTab con el nombre y el ID existente de la pestaña.

Mantiene un seguimiento del ID máximo de las pestañas para actualizar tabCount correctamente.

Si la solicitud falla o hay un error de red, lo registra en la consola.

1.7. Creación de una Nueva Pestaña

Propósito: Crear una nueva pestaña en la interfaz, ya sea una pestaña nueva o una que ya existe (recuperada del servidor).

Parámetros:

tabName: Nombre de la pestaña a crear.

existingTabId: (Opcional) ID de una pestaña existente. Si se proporciona, se usa este ID sin incrementar tabCount.

Funcionamiento:

Asignación de tabId:

Si existingTabId se proporciona, se utiliza como tabId. De lo contrario, se incrementa tabCount y se asigna como nuevo tabId. Referencias al DOM:

tabList: Elemento que contiene la lista de pestañas (ul id="tabsList"). tabContent: Elemento que contiene el contenido de las pestañas (div id="tabContent"). Creación del Elemento de Pestaña ({li}):

Crea un li con el nombre de la pestaña, un ID único (tab{tabId}), y la clase 'tab'. Establece un atributo data-tab-name para almacenar el nombre de la pestaña. Agrega listeners para: click: Activa la pestaña al hacer clic. dblclick: Permite renombrar la pestaña al hacer doble clic. contextmenu: Muestra un menú contextual al hacer clic derecho, con la opción de eliminar la pestaña. Creación del Contenido de la Pestaña (div):

Crea un div con ID content{tabId} y clase 'tabContent', inicialmente oculto (display: none). Inserta HTML que incluye: Un canvas para dibujar conexiones (canvas id="canvas{tabId}"). Un contenedor para los nodos (div id="nodeContainer{tabId}"). Una barra lateral derecha (div class="right_sidebar") con varios tipos de nodos y un botón para guardar. Inserción en el DOM:

Añade la nueva pestaña a tabList y el contenido a tabContent. Inicialización de Datos:

Inicializa tabNodes[tabId] y tabConnections[tabId] como arrays vacíos para almacenar nodos y conexiones. Configuración de Nodos en la Barra Lateral:

Selecciona todos los elementos con clase .node en la barra lateral. Agrega un listener de 'click' a cada nodo para crear un nuevo nodo en el canvas al hacer clic. Activación de la Nueva Pestaña: Llama a activateTab(newTab) para hacerla la pestaña activa.

Inicialización del Canvas: Espera un frame de animación para asegurarse de que el DOM esté actualizado y luego llama a initializeCanvas(tabId) para configurar el canvas.

Carga de Datos Existentes: Si la pestaña es existente (existingTabId proporcionado), llama a loadTabData(tabId) para cargar los datos guardados previamente.

1.8. Activación de una Pestaña

Propósito: Activar una pestaña específica, mostrando su contenido y actualizando el estado de la aplicación en consecuencia.

Parámetros:

selectedTab: Elemento DOM de la pestaña que se va a activar. Funcionamiento:

Desactivación de Todas las Pestañas y Contenidos:

Selecciona todas las pestañas (#tabsList li.tab) y les remueve la clase 'active'. Selecciona todos los contenidos de pestañas (.tabContent) y los oculta (display: none). Activación de la Pestaña Seleccionada:

Agrega la clase 'active' a selectedTab. Muestra el contenido correspondiente (display: block) obteniendo el ID del contenido a partir del ID de la pestaña (content{tabId}). Actualización de activeTabId: Extrae el ID numérico de la pestaña y lo asigna a activeTabId.

Inicialización y Actualización del Canvas y Conexiones:

Usa requestAnimationFrame para asegurarse de que el DOM esté actualizado antes de inicializar el canvas y actualizar los puntos y conexiones. Llama a: initializeCanvas(activeTabId): Inicializa el canvas para la pestaña activa. updateConnectionPoints(activeTabId): Actualiza los puntos de conexión de los nodos. updateConnections(activeTabId): Dibuja o actualiza las líneas de conexión entre nodos.

1.9. Renombrar una Pestaña

Propósito: Permitir al usuario renombrar una pestaña existente mediante un prompt y actualizar el servidor con el nuevo nombre.

Parámetros:

tabElement: Elemento DOM de la pestaña que se va a renombrar. Funcionamiento:

Obtener Nombre Actual y Solicitar Nuevo Nombre:

Recupera el nombre actual de la pestaña desde el atributo data-tab-name. Muestra un prompt al usuario con el nombre actual como valor por defecto. Validación:

Verifica que el usuario haya ingresado un nombre y que sea diferente al nombre actual. Extracción de tabId: Asume que el ID de la pestaña sigue el formato 'tab{id}' y extrae el ID numérico.

Solicitud al Servidor:

Realiza una solicitud POST a '/rename_tab/' con el tabId y el newTabName. Incluye el token CSRF en los headers para seguridad. Manejo de la Respuesta:

Si la respuesta indica éxito (status: 'success'), actualiza el texto y el atributo data-tab-name de la pestaña en el DOM y muestra una alerta de éxito. Si hay un error, muestra una alerta con el mensaje de error proporcionado por el servidor. Manejo de Errores de Red: Si ocurre un error durante la solicitud, lo registra en la consola y muestra una alerta al usuario.

1.10. Eliminar una Pestaña

Propósito: Permitir al usuario eliminar una pestaña existente, tanto del DOM como del servidor.

Parámetros:

tabElement: Elemento DOM de la pestaña que se va a eliminar. Funcionamiento:

Confirmación del Usuario: Muestra un confirm para que el usuario confirme la eliminación. Si el usuario cancela, la función termina.

Extracción de tabId y tabName:

Extrae el ID numérico de la pestaña. Obtiene el nombre de la pestaña desde el atributo data-tab-name. Solicitud al Servidor:

Realiza una solicitud POST a '/delete_tab/' con el tabId y el tabName. Incluye el token CSRF en los headers para seguridad. Manejo de la Respuesta:

Si la respuesta indica éxito (status: 'success'): Elimina la pestaña y su contenido del DOM. Elimina los datos asociados en tabConnections y tabNodes. Muestra una alerta de éxito. Si hay un error, muestra una alerta con el mensaje de error proporcionado por el servidor. Manejo de Errores de Red: Si ocurre un error durante la solicitud, lo registra en la consola y muestra una alerta al usuario.

1.11. Guardar Datos de una Pestaña

Propósito: Guardar el estado actual de una pestaña, incluyendo sus nodos y conexiones, enviándolos al servidor para persistencia.

Parámetros:

tabId: ID de la pestaña cuyos datos se van a guardar. Funcionamiento:

Obtención del Nombre de la Pestaña: Recupera el elemento de la pestaña utilizando tabId. Obtiene el nombre de la pestaña desde data-tab-name o asigna un nombre por defecto si no está disponible. Recopilación de Datos de los Nodos: Selecciona todos los elementos con clase .slice_node dentro de #nodeContainer{tabId}. Convierte la NodeList en un array y mapea cada nodo a un objeto que representa sus propiedades. Dependiendo del data-node-type, extrae diferentes propiedades de cada nodo. Recopilación de Conexiones: Toma las conexiones almacenadas en window.tabConnections[tabId] y las mapea a objetos que representan cada conexión, incluyendo IDs de nodos de inicio y fin, clases de puerto, y estado de activación. Estructura de Datos a Enviar: Crea un objeto data que incluye tabId, tabName, nodes y connections. Procesamiento Especial para Nodos de Tipo node3: Itera sobre cada nodo y, si es de tipo node3 con contenido y sin archivo de texto previamente guardado, realiza una solicitud POST a '/save_tts/' para generar archivos de texto. Si la respuesta es exitosa, actualiza node.textFile con la URL del archivo generado. Si hay un error (excepto si el estado es 'skipped'), lo registra y notifica al usuario, pero continúa con los demás nodos. Envío de Datos Completos al Servidor: Realiza una solicitud POST a '/save-tab-data/' con el objeto data en formato JSON. Incluye el token CSRF en los headers para seguridad. Manejo de la Respuesta: Si la respuesta es exitosa (response.ok), registra el mensaje de éxito en la consola. Si hay un error, extrae y muestra el mensaje de error al usuario. Manejo de Errores de Red o Servidor: Si ocurre un error durante las solicitudes, lo registra en la consola y muestra una alerta al usuario.

1.12. Cargar Datos de una Pestaña.

Propósito: Cargar los datos guardados de una pestaña específica desde el servidor y reconstruir su estado en el DOM, incluyendo nodos y conexiones.

Parámetros:

tabId: ID de la pestaña cuyos datos se van a cargar.

tabName: (Opcional) Nombre de la pestaña. Se utiliza si data.tabName no está disponible en la respuesta del servidor.

Funcionamiento:

Solicitud al Servidor: Realiza una solicitud GET a '/load-tab-data/{tabId}/' para obtener los datos de la pestaña. Verificación de la Respuesta: Si la respuesta es exitosa (response.ok), parsea el JSON recibido. Extracción de Datos: nodesData: Array de nodos. Si data.nodes no es un array, se asigna un array vacío. connectionsData: Array de conexiones. Si data.connections no es un array, se asigna un array vacío. Determinación del Nombre de la Pestaña: Se utiliza data.tabName si está disponible; de lo contrario, se usa tabName proporcionado como parámetro; si ninguno está disponible, se asigna un nombre por defecto basado en tabId. Actualización del Nombre de la Pestaña en el DOM: Busca el elemento de la pestaña y actualiza su texto y atributo data-tab-name con effectiveTabName. Limpieza del Contenedor de Nodos: Busca el contenedor de nodos (#nodeContainer{tabId}) y limpia su contenido (innerHTML = ''). Reconstrucción de Nodos: Crea un mapa (nodeMap) para asociar IDs de nodos con sus elementos DOM. Itera sobre cada nodeData y realiza lo siguiente: Crea un {div} con clase 'slice_node', posición absoluta, y establece sus propiedades según el tipo de nodo (data-node-type). Dependiendo del tipo de nodo, asigna propiedades específicas como extensionNumber, content, textFile, etc. Crea y añade elementos hijos: Título: div class="node-title". Archivo de Texto: Para node3, crea un div class="txt-file" oculto que muestra el nombre del archivo de texto si está disponible. Ícono de Reproducción: Para node2 y node6, crea un span class="play-icon" que permite reproducir un archivo de audio asociado. Elemento de Extensión: Para node4, crea un div class="display-extension" oculto que muestra el número de extensión. Puertos de Conexión: Dependiendo del tipo de nodo, añade puertos de entrada (port-in) y salida (port-out) para establecer conexiones. Eventos: mousedown: Para permitir el movimiento del nodo si no se hace clic en un puerto o en el ícono de reproducción. dblclick: Para abrir un modal de configuración del nodo. mousedown en Puertos: Para iniciar una conexión al hacer clic en un puerto. contextmenu: Para mostrar un menú contextual con la opción de eliminar el nodo. Inserción en el DOM: Añade el nodo al contenedor correspondiente y lo registra en nodeMap. Inicialización de Conexiones: Reinicia window.tabConnections[tabId] como un array vacío. Espera un frame de animación para asegurar que el DOM esté actualizado. Itera sobre cada connData en connectionsData: Busca los nodos de inicio y fin usando nodeMap. Busca los puertos de inicio y fin basándose en las clases de puerto especificadas. Calcula las coordenadas de los puntos de conexión relativas al canvas. Añade la conexión a window.tabConnections[tabId] con startPoint, endPoint y isActive. Actualización de Puntos y Conexiones: Llama a updateConnectionPoints(tabId) y updateConnections(tabId) para actualizar visualmente las conexiones en el canvas. Actualización de Números de Extensión para node4: Itera sobre cada nodo y, si es de tipo node4, busca conexiones activas que terminan en este nodo. Si la conexión proviene de un node3, actualiza el extensionNumber de node4 con el contenido de node3. Actualiza el elemento DOM que muestra el número de extensión. Manejo de Errores: Si la solicitud al servidor falla o hay un error durante el procesamiento, lo registra en la consola.

1.13. Atajo de Teclado para Guardar

Propósito: Permitir a los usuarios guardar el estado de la pestaña activa rápidamente usando el atajo de teclado Ctrl + S.

Funcionamiento:

Agrega un listener al documento para el evento 'keydown'.

Verifica si se presiona la tecla Ctrl junto con la tecla 's'.

Si se detecta el atajo:

Previene la acción por defecto del navegador (como abrir el diálogo de guardar página). Verifica si hay una pestaña activa (activeTabId !== null). Si hay una pestaña activa, llama a saveTabData(activeTabId) para guardar sus datos. Si no hay ninguna pestaña activa, muestra una alerta indicando que no hay pestaña activa.

1.14. Exportación de Funciones para connections.js

Propósito: Hacer que ciertas funciones sean accesibles globalmente (a través del objeto window) para que puedan ser utilizadas en otros scripts, específicamente en connections.js.

Funcionamiento:

initializeCanvas: Inicializa el canvas para dibujar conexiones.

updateConnectionPoints: Actualiza los puntos de conexión de los nodos en el canvas.

updateConnections: Dibuja o actualiza las líneas de conexión entre nodos.

startConnection: Inicia una nueva conexión cuando se interactúa con un puerto.

deleteTab: Permite eliminar una pestaña desde el menú contextual.