kb.js v2 — Módulo de auto-marcado de términos del diccionario
Resumen técnico
Módulo: public/informes/_kb/kb.js
Versión: v2 (2026-07-09)
Arquitectura: Sistema de auto-marcado de términos basado en diccionario centralizado
Dependencias: glossary.json (consumida vía fetch en runtime)
El módulo marca automáticamente TODAS las apariciones de los 127 términos del [[feature—informes—diccionario-glosa-127-terminos|diccionario central]] en las páginas de informes públicos, sin tocar enlaces, código, títulos ni marcados manuales previos.
Componentes principales
1. Inicialización y bootstrap
boot(): Cargaglossary.jsondesde/informes/_kb/glossary.jsonvíafetch()- Error handling: Si falla la carga, el módulo sigue funcionando (liga solo los
<abbr data-kb="...">manuales) - Interruptor global:
KB_ENABLED = true/falseen línea 25 desactiva todo el sistema para troubleshooting
2. Construcción del matcher
buildMatcher(terms): Crea un objeto de búsqueda optimizado a partir de la lista de términos- Agrupa términos por tipo:
- Siglas (CSS case-sensitive):
DCIM,UPS,API, etc. — coincidencia exacta por mayúsculas - Palabras normales (insensible):
cloud,nube, etc. — preserva la forma del texto pero no fuerza mayúsculas
- Siglas (CSS case-sensitive):
- Ordena por longitud descendente (los más largos ganan para evitar solapamientos)
- Construye dos regex con lookahead/lookbehind de límites de palabra (
\p{L}\p{N})
- Agrupa términos por tipo:
3. Escaneo y marcado automático
-
scan(container, matcher): Traversal del DOM viaTreeWalker- Salta tags prohibidos (código, enlaces, títulos, scripts, estilos):
SKIP = {A, ABBR, CODE, PRE, ...} - Salta contenido de elementos con
data-kbya presente (respeta marcados manuales) - Procesa solo nodos de texto con contenido visible
- Salta tags prohibidos (código, enlaces, títulos, scripts, estilos):
-
markNode(textNode, matcher): Busca la PRIMERA aparición en cada nodo- Aplica ambas regex (siglas y palabras)
- Compara índice entre regex y marca solo la más temprana (evita false positives por solapamiento)
- Reemplaza el nodo original con fragmento:
[antes] + <abbr data-kb="...">término</abbr> + [después] - Recursivo: continúa desde el resto del texto (
afterNode) para marcar más apariciones
4. El globo flotante (tooltip)
-
ensureTip(): Crea un<div>reutilizable, único en toda la página- Posicionamiento:
position: fixedpara escapar contenedores conoverflow: hidden - Cálculo dinámico: aparece arriba del término, o abajo si no cabe
- Padding de 8px al borde de la ventana
- Posicionamiento:
-
show(el)/hide(el): Ligas y desligas del globo- Triggers:
mouseenter,mouseleave,focus,blur - Escape key cierra el globo (accesibilidad)
- Scroll/resize ocultan el globo (evita posicionamiento desviado)
- Triggers:
5. Binding de términos marcados
bindOne(el)/bindAll(): Conecta event listeners a todos los<abbr data-kb="...">(manuales + auto-marcados)- Añade
tabindex="0"si el término no lo tiene (accesibilidad: navegable por teclado) - Flag
data-kb-boundevita re-ligar
- Añade
Reglas de marcado
| Regla | Aplicación |
|---|---|
| Límites de palabra | No marca un término dentro de otro (firewall en firewallsudo se salta) |
| Caso en siglas | DCIM matchea solo DCIM, no dcim (case-sensitive) |
| Caso en palabras | cloud matchea Cloud, CLOUD, cloud (insensible, preserva forma) |
| Aliases | Ambas formas (cloud y nube) activan el mismo gloss |
| Manuales ganan | Un <abbr data-kb="..."> puesto a mano se respeta y no se sobre-marca |
| Tags prohibidos | Nunca marca dentro de <a>, <code>, <pre>, <h1..h3>, <script>, <style> |
| Recursión guardada | Máximo 200 iteraciones por nodo para evitar bucles (safety) |
Variables de control
var KB_ENABLED = true; // Apagar todo el sistema
var GLOSSARY_URL = '/informes/_kb/glossary.json'; // Ruta del JSON
Por página: añadir <html data-kb-off> para desactivar (respeta estructura del documento).
Por contenedor: añadir data-kb-scan="..." a un elemento para acotar el escaneo solo a su subárbol (por defecto <body>).
Ejemplos de uso
Activación implícita
<!-- Sin hacer nada, el módulo carga y marca automáticamente -->
<p>Para montar un datacenter con alta disponibilidad,
necesitas redundancia en energía (UPS + generador).</p>
<!-- Se transforma en: -->
<p>Para montar un <abbr data-kb="Centro de datos...">datacenter</abbr>
con alta disponibilidad, necesitas redundancia en energía
(<abbr data-kb="Sistema con baterías...">UPS</abbr> + generador).</p>
Marcado manual con prioridad
<!-- Esto respeta el gloss manual, no lo sobre-marca -->
<p>El <abbr data-kb="Custom gloss para este contexto">API</abbr>
del proveedor permite...</p>
Desactivación por página
<html data-kb-off> <!-- Todo el sistema desactivado aquí -->
<body>
<p>datacenter, API, etc. NO se marcarán</p>
</body>
</html>
Desactivación por contenedor
<html>
<body>
<p data-kb-scan>Esto SÍ se marca</p>
<article>Esto NO se marca (fuera del scope)</article>
</body>
</html>
Performance y optimizaciones
- Fetch lazy:
glossary.jsonse carga solo siKB_ENABLED = true - TreeWalker eficiente: Una única pasada por el DOM (no múltiples querySelectorAll)
- Regex compiladas una sola vez: Se construyen al boot, no en cada búsqueda
- Globo reutilizado: Un único
<div>para todos los términos (sin memory leak) - Guardia de recursión: Máximo 200 iteraciones por nodo (safety contra textos enormes)
Cambios v1 → v2
| Aspecto | v1 | v2 |
|---|---|---|
| Marcado | Solo <abbr data-kb="..."> manuales | Automático desde diccionario |
| Cobertura | Limitada a lo que el editor marcaba | 100% del diccionario |
| Límites de palabra | Manual (responsabilidad del editor) | Automático (regex lookbehind/lookahead) |
| Case-sensitivity | Manual | Inteligente (siglas vs palabras) |
| Aliases | No soportados | Soportados (cloud + nube) |
| Diccionario | Inline en HTML | Centralizado en JSON |
Véase también
- [[feature—informes—diccionario-glosa-127-terminos]]
- [[concept—workspace—supercontexto-01-biblioteca]]
- [[concept—saas—multi-tenancy]]