1/***********************************************************/ 2/* */ 3/* Plataforma e-ducativa - Argentina */ 4/* */ 5/* Copyright (c) 2026 de e-ducativa Educación Virtual S.A. */ 6/* */ 7/***********************************************************/ 8/** 9 * EducativaSpotlightQueue - Cola con prioridad para spotlights/tours. 10 * 11 * Coordina la ejecucion de multiples spotlights en una misma pagina para 12 * que se muestren uno a la vez, evitando overlays superpuestos. Cada 13 * llamador encola un item con prioridad numerica; la cola los procesa en 14 * orden ascendente, esperando el cierre de cada uno antes de iniciar el 15 * siguiente. 16 * 17 * Reservorio de prioridades (documentar al agregar tours nuevos): 18 * 10 - Visualizacion (sidebar/topbar/flotantes/admin) 19 * 20 - Paginador 20 * 30 - Novedades webmaster 21 * 40 - Lang switcher (cambio de idioma) 22 * 50+ - Disponibles para futuros tours 23 * 24 * @module Educativa/EducativaSpotlightQueue 25 */ 26 27/** 28 * @typedef {Object} SpotlightQueueItem 29 * @property {number} priority - Menor numero = mayor prioridad 30 * @property {string} [name] - Identificador para debug/log 31 * @property {string} [storageKey] - Clave localStorage del tour. Si se 32 * provee, skipAll() la marca como vista 33 * para que no reaparezca en recargas. 34 * @property {number} [maxTimes] - Maximo de veces que se muestra (default 1) 35 * @property {Function} run - Funcion que arranca el tour. Debe 36 * retornar una Promise que resuelve 37 * cuando el tour cierra (skip o done). 38 */ 39 40var pending = []; 41var running = false; 42var flushScheduled = false; 43var skipped = false; 44var registeredKeys = new Set(); 45 46function flush() { 47 flushScheduled = false; 48 if ( running ) { return; } 49 if ( !pending.length ) { return; } 50 51 pending.sort( function( a, b ) { return a.priority - b.priority; }); 52 53 var item = pending.shift(); 54 running = true; 55 56 Promise.resolve() 57 .then( function() { return item.run(); }) 58 .catch( function( err ) { 59 console.error( 60 '[SpotlightQueue] tour "' + ( item.name || 'unnamed' ) + 61 '" fallo:', err 62 ); 63 }) 64 .then( function() { 65 running = false; 66 if ( pending.length ) { flush(); } 67 }); 68} 69 70export var SpotlightQueue = { 71 /** 72 * Encola un spotlight para ser ejecutado en orden de prioridad. 73 * @param {SpotlightQueueItem} item 74 */ 75 enqueue: function( item ) { 76 if ( skipped ) { return; } 77 pending.push( item ); 78 if ( item.storageKey ) { registeredKeys.add( item.storageKey ); } 79 if ( !flushScheduled ) { 80 flushScheduled = true; 81 Promise.resolve().then( flush ); 82 } 83 }, 84 85 skipAll: function() { 86 /* Marcar como vistos los items pendientes que exponen storageKey, 87 para que no reaparezcan tras una recarga de pagina. */ 88 var writtenKeys = {}; 89 pending.forEach( function( item ) { 90 if ( item.storageKey ) { 91 var max = item.maxTimes || 1; 92 localStorage.setItem( item.storageKey, String( max ) ); 93 writtenKeys[ item.storageKey ] = true; 94 } 95 }); 96 /* Persistir tours standalone (tracked via start() pero no encolados) */ 97 registeredKeys.forEach( function( k ) { 98 if ( !writtenKeys[ k ] ) { 99 localStorage.setItem( k, '1' ); 100 } 101 }); 102 skipped = true; 103 pending = []; 104 }, 105 106 /** Retorna true si skipAll() fue invocado; nuevos enqueues y starts son ignorados. */ 107 isSkipped: function() { 108 return skipped; 109 }, 110 111 /** Retorna el Set de storageKeys de todos los items encolados en esta pagina. */ 112 getRegisteredKeys: function() { 113 return registeredKeys; 114 }, 115 116 /** 117 * Registra una storageKey sin encolar. Permite que resetSpotlights() 118 * encuentre la clave aunque el tour haya retornado temprano (ya visto). 119 * @param {string} key 120 */ 121 track: function( key ) { 122 if ( key ) { registeredKeys.add( key ); } 123 } 124};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.