CreaRack-SL

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(): Carga glossary.json desde /informes/_kb/glossary.json vía fetch()
  • Error handling: Si falla la carga, el módulo sigue funcionando (liga solo los <abbr data-kb="..."> manuales)
  • Interruptor global: KB_ENABLED = true/false en 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
    • 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})

3. Escaneo y marcado automático

  • scan(container, matcher): Traversal del DOM via TreeWalker

    • Salta tags prohibidos (código, enlaces, títulos, scripts, estilos): SKIP = {A, ABBR, CODE, PRE, ...}
    • Salta contenido de elementos con data-kb ya presente (respeta marcados manuales)
    • Procesa solo nodos de texto con contenido visible
  • 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: fixed para escapar contenedores con overflow: hidden
    • Cálculo dinámico: aparece arriba del término, o abajo si no cabe
    • Padding de 8px al borde de la ventana
  • 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)

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-bound evita re-ligar

Reglas de marcado

ReglaAplicación
Límites de palabraNo marca un término dentro de otro (firewall en firewallsudo se salta)
Caso en siglasDCIM matchea solo DCIM, no dcim (case-sensitive)
Caso en palabrascloud matchea Cloud, CLOUD, cloud (insensible, preserva forma)
AliasesAmbas formas (cloud y nube) activan el mismo gloss
Manuales gananUn <abbr data-kb="..."> puesto a mano se respeta y no se sobre-marca
Tags prohibidosNunca marca dentro de <a>, <code>, <pre>, <h1..h3>, <script>, <style>
Recursión guardadaMá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.json se carga solo si KB_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

Aspectov1v2
MarcadoSolo <abbr data-kb="..."> manualesAutomático desde diccionario
CoberturaLimitada a lo que el editor marcaba100% del diccionario
Límites de palabraManual (responsabilidad del editor)Automático (regex lookbehind/lookahead)
Case-sensitivityManualInteligente (siglas vs palabras)
AliasesNo soportadosSoportados (cloud + nube)
DiccionarioInline en HTMLCentralizado en JSON

Véase también

  • [[feature—informes—diccionario-glosa-127-terminos]]
  • [[concept—workspace—supercontexto-01-biblioteca]]
  • [[concept—saas—multi-tenancy]]