Files
crochet/js/render.js
T

57 lines
2.8 KiB
JavaScript

// Genera el resultado (#panel-output) a partir de las secciones actuales y
// de "Personalización de página" (título/autor), y decide cuándo hay que
// repintarlo: al escribir, al cambiar de idioma, o al añadir/quitar/
// reordenar secciones o elementos soltados.
import { outputText, sectionsContainer, pageTitleInput, pageAuthorInput } from './dom-refs.js';
import { TRANSLATABLE_FIELDS_SELECTOR, setTranslation, setupLanguageSelect } from './i18n.js';
import { renderOutputSection, appendOutputLine } from './section-types.js';
// Recorre todas las secciones de nivel superior (en su orden actual) y
// reconstruye #panel-output desde cero.
export function renderOutput() {
outputText.innerHTML = '';
// Título y autor del patrón (ver "Personalización de página"): son
// configuración de todo el documento, no una sección más, así que se
// pintan siempre delante, haya o no secciones añadidas.
// Tamaños en "em" (no las clases normales de Tailwind, en "rem") para que
// escalen con el "Tamaño de letra" de #panel-output-text (ver
// page-settings.js): "rem" ignora el font-size de cualquier ancestro.
appendOutputLine(outputText, 'h1', pageTitleInput.value.trim(), 'text-[1.5em] font-bold mb-1');
appendOutputLine(outputText, 'p', pageAuthorInput.value.trim(), 'text-[0.875em] opacity-70 mb-2');
// Si aún no se ha añadido ninguna sección, avisar en vez de dejar el
// resultado vacío.
if (sectionsContainer.children.length === 0) {
appendOutputLine(outputText, 'p', outputText.dataset.emptyMessage, 'opacity-50 italic');
return;
}
Array.from(sectionsContainer.children).forEach(section => renderOutputSection(section, outputText));
}
// El resultado se regenera con cualquier cambio dentro de las secciones:
// escribir texto/título ('input'), elegir una imagen ('change'), o
// añadir/quitar/reordenar secciones o elementos soltados (MutationObserver).
// Al estar en #panel-top-sections y usar subtree:true, esto ya cubre
// también los cambios dentro de las secciones anidadas en un "Grupo". Si el
// campo es traducible (título/subtítulo/texto/nota/materiales), cada
// pulsación de tecla también se guarda en su mapa de traducciones para el
// idioma actual, así no hace falta un paso aparte de "guardar" al cambiar
// de idioma o al serializar la sección.
sectionsContainer.addEventListener('input', (e) => {
if (e.target.matches(TRANSLATABLE_FIELDS_SELECTOR)) {
setTranslation(e.target, e.target.value);
}
renderOutput();
});
sectionsContainer.addEventListener('change', renderOutput);
new MutationObserver(renderOutput).observe(sectionsContainer, { childList: true, subtree: true });
setupLanguageSelect(renderOutput);
// El título/autor del patrón no pasan por sectionsContainer, así que se
// escuchan aparte.
[pageTitleInput, pageAuthorInput].forEach(el => el.addEventListener('input', renderOutput));