PageSourceSearch

https://sportingclubhuelva.com/js/bootstrap4-dialog/dist/js/bootstrap-dialog.wf.bridge.js?v=1780298893

js sportingclubhuelva.com collected 2026-10-02 13:36:49 UTC 17,318 bytes, 681 lines download raw bytes

1/* =========================================================
2   WF BRIDGE · BootstrapDialog -> ventana_wf (WF)
3   Cargar DESPUÉS de bootstrap-dialog.*.js y DESPUÉS de wf.js
4   ========================================================= */
5(function(window)
6{
7	if (!window.BootstrapDialog)
8	{
9		console.warn(`[WF Bridge] BootstrapDialog no existe`);
10		return;
11	}
12
13	if (typeof window.ventana_wf !== `function`)
14	{
15		console.warn(`[WF Bridge] ventana_wf() no existe. Carga wf.js antes del bridge.`);
16		return;
17	}
18
19	const BD = window.BootstrapDialog;
20
21	if (BD.__WF_BRIDGE__) return;
22	BD.__WF_BRIDGE__ = true;
23
24	// =========================
25	// DEPURACIÓN
26	// =========================
27	let depuracion_en_consola = true;
28	let d = ``;
29
30	const dbg_print = () =>
31	{
32		if (depuracion_en_consola && d) console.log(d);
33	};
34
35	const dbg_reset = () =>
36	{
37		if (!depuracion_en_consola) return;
38		d = ``;
39	};
40
41	const dbg_add = (txt) =>
42	{
43		if (!depuracion_en_consola) return;
44		d += `\n${txt}`;
45	};
46	// =========================
47
48	const size_map = (size) =>
49	{
50		if (size === BD.SIZE_SMALL) 		return `w576`;
51		if (size === BD.SIZE_LARGE) 		return `w992`;
52		if (size === BD.SIZE_WIDE) 			return `w1500`;
53		if (size === BD.SIZE_EXTRAWIDE) 	return `wfull`;
54
55		return `w500`;									// NORMAL (BS4 default)
56	};
57
58	const mount_message = (root, message, api = null) =>
59	{
60		if (!root) return;
61
62		const cont = root.querySelector(`.contenido`);
63		if (!cont) return;
64
65		cont.innerHTML = ``;
66
67		let m = message;
68
69		// 1) message como función (legacy BootstrapDialog)
70		if (typeof m === `function`)
71		{
72			try
73			{
74				m = m(api);
75			}
76			catch (e)
77			{
78				console.error(`[WF Bridge] message() error:`, e);
79				m = ``;
80			}
81		}
82
83		// 2) jQuery object
84		if (window.jQuery && m && m.jquery)
85		{
86			m.each(function(){ cont.appendChild(this); });
87			return;
88		}
89
90		// 3) DOM element
91		if (m instanceof HTMLElement)
92		{
93			cont.appendChild(m);
94			return;
95		}
96
97		// 4) string / other
98		if (m !== undefined && m !== null) cont.innerHTML = String(m);
99	};
100
101	const render_buttons = (root, buttons = [], api = null) =>
102	{
103		if (!root) return;
104		
105		const footer = root.querySelector(`.border-top`);
106		if (!footer) return;
107
108		// limpiamos todo menos el botón “Cerrar” final (que ya está en ventana_wf)
109		const cerrar = footer.querySelector(`.cerrar_ventana_wf`);
110		footer.innerHTML = ``;
111
112		if (Array.isArray(buttons) && buttons.length)
113		{
114			buttons.forEach(btn =>
115			{
116				const b = document.createElement(`button`);
117				b.type = `button`;
118				b.className = btn.cssClass || `btn btn-sm btn-primary ml-2`;
119				b.innerHTML = btn.icon ? `${btn.icon} ${btn.label || ``}` : (btn.label || `Aceptar`);
120
121				b.addEventListener(`click`, (ev) =>
122				{
123					if (typeof btn.action === `function`) btn.action(api, ev);
124				});
125
126				footer.appendChild(b);
127			});
128		}
129
130		if (cerrar) footer.appendChild(cerrar);
131		else
132		{
133			const c = document.createElement(`span`);
134			c.className = `btn btn-sm btn-light ml-2 cerrar_ventana_wf puntero`;
135			c.textContent = `Cerrar`;
136			footer.appendChild(c);
137		}
138	};
139
140	const wf_bring_to_front = (root) =>
141	{
142		// Mover al final del body suele arreglar stacking contexts raros (formulario por encima, etc.)
143		if (root && root.parentNode) document.body.appendChild(root);
144
145		// Z-index incremental
146		window.__wf_bd_z = (window.__wf_bd_z || 2000) + 2;
147		root.style.zIndex = window.__wf_bd_z;
148
149		// Focus “amable”
150		const f = root.querySelector(`input,select,textarea,button,[tabindex]:not([tabindex="-1"])`);
151		if (f) f.focus({ preventScroll:true });
152	};
153
154	const wf_open = (root) =>
155	{
156		if (!root) return;
157
158		wf_bring_to_front(root);
159
160		if (!root.classList.contains(`visible`))
161		{
162			root.classList.add(`visible`);
163			document.body.style.overflow = `hidden`;
164			root.scrollTop = 0;
165		}
166	};
167
168	const wf_close = (root) =>
169	{
170		root.classList.remove(`visible`);
171
172		// si no quedan ventanas WF visibles, restauramos scroll
173		if (!document.querySelector(`.ventana_wf.visible`)) document.body.style.overflow = ``;
174
175		const eliminar = root.getAttribute(`data-eliminar_al_cerrar`);
176		document.querySelectorAll(`.espera`).forEach(n => n.remove());
177		if (typeof window.eliminar_espera === `function`) window.eliminar_espera();		
178		if (eliminar === `1`) root.remove();
179	};
180
181	// Guardamos el show original por si quieres fallback
182	const original_show = BD.show;
183
184	BD.show = function(options = {})
185	{
186		dbg_reset();
187
188		// ID estable y único
189		const id = `wf_bd_${Date.now()}_${Math.floor(Math.random() * 1000000)}`;
190		const selector = `#${id}`;
191
192		const title 	= options.title || ``;
193		const clase 	= size_map(options.size);
194		const header 	= options.hasOwnProperty(`title`) ? true : true;
195
196		// crea ventana (si existiera, la reiniciamos)
197		const w = new wf_ventana();
198
199		w.abrir({
200			id: selector,
201			eliminar: true,
202			contenido_b64: null,
203			clase_ancho: clase,
204			titulo_ventana: title,
205			pintar_cabecera: header
206		});
207
208		const root = document.getElementById(id);
209
210		if (!root)
211		{
212			console.warn(`[WF Bridge] No se pudo crear la ventana: ${selector}`);
213			return original_show ? original_show(options) : null;
214		}		
215
216		if (root) root.setAttribute(`data-eliminar_al_cerrar`, `1`);
217
218		dbg_add(`=== DEBUG BD.show ===`);
219		dbg_add(`id: ${id}`);
220		dbg_add(`selector: ${selector}`);
221		dbg_add(`root?: ${!!root}`);
222		dbg_add(`root.isConnected: ${root ? root.isConnected : 'n/a'}`);
223		dbg_add(`root.visible: ${root ? root.classList.contains('visible') : 'n/a'}`);
224		dbg_add(`body.overflow: ${document.body.style.overflow || '(vacío)'}`);
225		dbg_add(`ventanas visibles: ${document.querySelectorAll('.ventana_wf.visible').length}`);
226
227		// API compatible mínima
228		const api = {
229			close: () =>
230			{
231				const r = document.getElementById(id);
232				if (!r) return;
233				wf_close(r);
234			},
235
236			open: () =>
237			{
238				const r = asegurar_ventana();
239				if (!r) return;
240				wf_open(r);
241			},
242
243			getModal: () =>
244			{
245				const r = document.getElementById(id);
246				return (window.jQuery ? window.jQuery(r) : r);
247			},
248
249			getModalHeader: () =>
250			{
251				return {
252					hide: function()
253					{
254						const r = document.getElementById(id);
255						if (!r) return this;
256
257						const cabecera = r.querySelector(`.cabecera`);
258						if (cabecera) cabecera.remove();
259
260						return this;
261					}
262				};
263			}			
264		};
265
266		const asegurar_ventana = () =>
267		{
268			let r = document.getElementById(id);
269
270			if (!r)
271			{
272				const w = new wf_ventana();
273
274				w.abrir({
275					id: selector,
276					eliminar: true,
277					contenido_b64: null,
278					clase_ancho: clase,
279					titulo_ventana: title,
280					pintar_cabecera: header
281				});
282
283				r = document.getElementById(id);
284
285				if (!r) return null;
286
287				mount_message(r, options.message, api);
288				render_buttons(r, options.buttons || [], api);
289
290				r.addEventListener(`click`, (ev) =>
291				{
292					const btn = ev.target.closest(`.cerrar_ventana_wf`);
293					if (btn) api.close();
294				});
295
296				r.setAttribute(`data-eliminar_al_cerrar`, `1`);
297			}
298
299			return r;
300		};
301
302		// contenido
303		mount_message(root, options.message, api);
304
305		// botones (si los hay)
306		render_buttons(root, options.buttons || [], api);
307
308		// callbacks similares
309		if (typeof options.onshow === `function`)
310		{
311			const ok = options.onshow(api);
312			if (ok === false)
313			{
314				dbg_add(`onshow devolvió false -> no abrir`);
315				dbg_print();
316				return api;
317			}
318		}
319
320		wf_open(root);
321
322		if (typeof options.onshown === `function`) options.onshown(api);
323
324		// Cerrar con ESC (si quieres)
325		if (options.closable !== false)
326		{
327			const key = (ev) =>
328			{
329				if (ev.key === `Escape`)
330				{
331					api.close();
332					document.removeEventListener(`keydown`, key);
333				}
334			};
335			document.addEventListener(`keydown`, key);
336		}
337
338		// click en .cerrar_ventana_wf
339		root.addEventListener(`click`, (ev) =>
340		{
341			const btn = ev.target.closest(`.cerrar_ventana_wf`);
342			if (btn) api.close();
343		});
344
345		dbg_add(`OPEN ejecutado`);
346		dbg_add(`root.visible (post): ${root ? root.classList.contains('visible') : 'n/a'}`);
347		dbg_add(`[WF Bridge] BootstrapDialog.show -> ventana_wf OK`);
348		dbg_print();
349
350		console.log(`[WF Bridge] BootstrapDialog.show -> ventana_wf OK`, selector);
351
352		return api;
353	};
354
355	// marca para debugging
356	BD.USE_WF = true;
357
358})(window);
359
360/* =========================================================
361   WF BRIDGE (2) · soportar: new BootstrapDialog(...).realize().open()
362   ========================================================= */
363(function(window)
364{
365	if (!window.BootstrapDialog) return;
366	if (typeof window.ventana_wf !== `function`) return;
367
368	// Si ya hemos “proxyado” el constructor, no repetimos
369	if (window.BootstrapDialog.__WF_PROXY_CONSTRUCTOR__) return;
370
371	const BD_ORIG = window.BootstrapDialog;
372
373	// =========================
374	// DEPURACIÓN
375	// =========================
376	let depuracion_en_consola = true;
377	let d = ``;
378
379	const dbg_print = () =>
380	{
381		if (depuracion_en_consola && d) console.log(d);
382	};
383
384	const dbg_reset = () =>
385	{
386		if (!depuracion_en_consola) return;
387		d = ``;
388	};
389
390	const dbg_add = (txt) =>
391	{
392		if (!depuracion_en_consola) return;
393		d += `\n${txt}`;
394	};
395	// =========================
396
397	// Utilidad: mapear tamaños a TUS clases reales
398	const size_map = (size) =>
399	{
400		if (size === BD_ORIG.SIZE_SMALL) 		return `w576`;
401		if (size === BD_ORIG.SIZE_LARGE) 		return `w992`;
402		if (size === BD_ORIG.SIZE_NORMAL) 		return `w992`;
403		if (size === BD_ORIG.SIZE_WIDE) 		return `w1500`;
404		if (size === BD_ORIG.SIZE_EXTRAWIDE) 	return `wfull`;
405
406		return `w500`;
407	};
408
409	const mount_message = (root, message, api = null) =>
410	{
411		const cont = root.querySelector(`.contenido`);
412		if (!cont) return;
413
414		cont.innerHTML = ``;
415
416		let m = message;
417
418		if (typeof m === `function`)
419		{
420			try { m = m(api); }
421			catch (e) { console.error(`[WF Bridge] message() error:`, e); m = ``; }
422		}
423
424		if (window.jQuery && m && m.jquery)
425		{
426			m.each(function(){ cont.appendChild(this); });
427			return;
428		}
429
430		if (m instanceof HTMLElement)
431		{
432			cont.appendChild(m);
433			return;
434		}
435
436		if (m !== undefined && m !== null) cont.innerHTML = String(m);
437	};
438
439	// “Clase” WF compatible con el API mínimo que usa tu legacy
440	function WF_BootstrapDialog(options = {})
441	{
442		this.__wf = {
443			id: `wf_bd_${Date.now()}_${Math.floor(Math.random() * 1000000)}`,
444			opts: options,
445			root: null,
446			opened: false
447		};
448	}
449
450	WF_BootstrapDialog.prototype.realize = function()
451	{
452		dbg_reset();
453
454		const o = this.__wf.opts || {};
455		const selector = `#${this.__wf.id}`;
456
457		// crea ventana
458		const clase = size_map(o.size);
459		const title = o.title || ``;
460
461		const w = new wf_ventana();
462
463		w.abrir({
464			id: selector,
465			eliminar: true,
466			contenido_b64: null,
467			clase_ancho: clase,
468			titulo_ventana: title,
469			pintar_cabecera: true
470		});
471
472		const root = document.getElementById(this.__wf.id);
473		this.__wf.root = root;
474
475		if (root) root.setAttribute(`data-eliminar_al_cerrar`, `1`);
476
477		// inyecta contenido
478		mount_message(root, o.message, this);
479
480		dbg_add(`=== DEBUG realize ===`);
481		dbg_add(`id: ${this.__wf.id}`);
482		dbg_add(`root?: ${!!root}`);
483		dbg_add(`root.isConnected: ${root ? root.isConnected : 'n/a'}`);
484		dbg_add(`root.visible: ${root ? root.classList.contains('visible') : 'n/a'}`);
485		dbg_add(`body.overflow: ${document.body.style.overflow || '(vacío)'}`);
486		dbg_add(`ventanas visibles: ${document.querySelectorAll('.ventana_wf.visible').length}`);
487		dbg_print();
488
489		// onshown (tu legacy lo usa muchísimo)
490		// OJO: lo dispararemos en open(), no aquí, para que sea más fiel al plugin.
491		return this;
492	};
493
494	WF_BootstrapDialog.prototype.open = function()
495	{
496		dbg_reset();
497
498		const o = this.__wf.opts || {};
499
500		let root = this.__wf.root || document.getElementById(this.__wf.id);
501
502		dbg_add(`=== DEBUG open (antes) ===`);
503		dbg_add(`id: ${this.__wf.id}`);
504		dbg_add(`this.__wf.root?: ${!!this.__wf.root}`);
505		dbg_add(`getElementById?: ${!!document.getElementById(this.__wf.id)}`);
506		dbg_add(`root?: ${!!root}`);
507		dbg_add(`root.isConnected: ${root ? root.isConnected : 'n/a'}`);
508		dbg_add(`root.visible: ${root ? root.classList.contains('visible') : 'n/a'}`);
509		dbg_add(`body.overflow: ${document.body.style.overflow || '(vacío)'}`);
510		dbg_add(`ventanas visibles: ${document.querySelectorAll('.ventana_wf.visible').length}`);
511
512		// si lo cerraron con remove(), el root guardado ya no está en DOM
513		if (root && !root.isConnected) root = null;
514
515		if (!root)
516		{
517			dbg_add(`root NO existe -> realize().open()`);
518			dbg_print();
519			return this.realize().open();
520		}
521
522		this.__wf.root = root;
523
524		if (!root.classList.contains(`visible`))
525		{
526			if (root && root.parentNode) document.body.appendChild(root);
527			window.__wf_bd_z = (window.__wf_bd_z || 2000) + 2;
528			root.style.zIndex = window.__wf_bd_z;
529
530			root.classList.add(`visible`);
531			document.body.style.overflow = `hidden`;
532			this.__wf.opened = true;
533		}
534
535		// hook de cierre WF
536		root.addEventListener(`click`, (ev) =>
537		{
538			if (ev.target.closest(`.cerrar_ventana_wf`)) this.close();
539		}, { once:false });
540
541		// callback compatible
542		if (typeof o.onshown === `function`) o.onshown(this);
543
544		dbg_add(`=== DEBUG open (después) ===`);
545		dbg_add(`root.visible: ${root.classList.contains('visible')}`);
546		dbg_add(`body.overflow: ${document.body.style.overflow || '(vacío)'}`);
547		dbg_add(`ventanas visibles: ${document.querySelectorAll('.ventana_wf.visible').length}`);
548		dbg_print();
549
550		return this;
551	};
552
553	WF_BootstrapDialog.prototype.close = function()
554	{
555		dbg_reset();
556
557		const o = this.__wf.opts || {};
558		const root = this.__wf.root || document.getElementById(this.__wf.id);
559
560		dbg_add(`=== DEBUG close (antes) ===`);
561		dbg_add(`id: ${this.__wf.id}`);
562		dbg_add(`root?: ${!!root}`);
563		dbg_add(`root.isConnected: ${root ? root.isConnected : 'n/a'}`);
564		dbg_add(`root.visible: ${root ? root.classList.contains('visible') : 'n/a'}`);
565		dbg_add(`body.overflow: ${document.body.style.overflow || '(vacío)'}`);
566		dbg_add(`ventanas visibles: ${document.querySelectorAll('.ventana_wf.visible').length}`);
567
568		if (!root)
569		{
570			dbg_add(`root NO existe -> return`);
571			dbg_print();
572			return;
573		}
574
575		root.classList.remove(`visible`);
576
577		// Si no quedan ventanas visibles, devolvemos scroll
578		if (!document.querySelector(`.ventana_wf.visible`)) document.body.style.overflow = ``;
579
580		// autodestroy: por defecto sí, para “parecerse” al modal
581		// si lo quieres configurable, usa o.autodestroy / o.removeOnHide
582		if (o.autodestroy === true || o.removeOnHide === true || o.autodestroy === undefined)
583		{
584			root.remove();
585			this.__wf.root = null;
586			this.__wf.opened = false;
587
588			dbg_add(`root.remove() ejecutado`);
589			dbg_add(`root.isConnected (post): ${root ? root.isConnected : 'n/a'}`);
590			dbg_add(`getElementById (post): ${!!document.getElementById(this.__wf.id)}`);
591		}
592
593		if (typeof o.onhidden === `function`) o.onhidden(this);
594
595		dbg_add(`=== DEBUG close (después) ===`);
596		dbg_add(`body.overflow: ${document.body.style.overflow || '(vacío)'}`);
597		dbg_add(`ventanas visibles: ${document.querySelectorAll('.ventana_wf.visible').length}`);
598		dbg_print();
599	};
600
601	WF_BootstrapDialog.prototype.setTitle = function(t)
602	{
603		const root = this.__wf.root || document.getElementById(this.__wf.id);
604		if (!root) return;
605
606		const span = root.querySelector(`.cabecera .text-monospace`);
607		if (span) span.textContent = t || ``;
608	};
609
610	WF_BootstrapDialog.prototype.setMessage = function(m)
611	{
612		const root = this.__wf.root || document.getElementById(this.__wf.id);
613		if (!root) return;
614
615		mount_message(root, m, this);
616	};
617	
618	/**
619	 * Compatibilidad legacy BootstrapDialog
620	 * ----------------------------------------------------------------------------------------------------
621	 * Este método existía en BootstrapDialog original, pero en WF no hay cabecera real.
622	 * 
623	 * Se devuelve un objeto con método hide() vacío para evitar errores en código legacy:
624	 * 
625	 * modal.getModalHeader().hide();
626	 * 
627	 * Resultado:
628	 * - No rompe
629	 * - No hace nada
630	 * - Mantiene compatibilidad sin tocar código antiguo
631	 */
632	WF_BootstrapDialog.prototype.getModalHeader = function()
633	{
634		const self = this;
635
636		return {
637			hide: function()
638			{
639				const root = self.__wf?.root || document.getElementById(self.__wf?.id);
640
641				if (!root) return this;
642
643				const cabecera = root.querySelector(`.cabecera`);
644
645				if (cabecera) cabecera.remove();
646
647				return this;
648			}
649		};
650	};
651
652	// Constructor proxy: cuando hagan `new BootstrapDialog(...)` devolvemos WF_BootstrapDialog
653	function BootstrapDialogProxy(options)
654	{
655		return new WF_BootstrapDialog(options);
656	}
657
658	// Copiamos todas las props/constantes estáticas del original (TYPE_PRIMARY, SIZE_EXTRAWIDE, etc.)
659	Object.keys(BD_ORIG).forEach(k => BootstrapDialogProxy[k] = BD_ORIG[k]);
660
661	// Marcadores
662	BootstrapDialogProxy.__WF_PROXY_CONSTRUCTOR__ = true;
663	BootstrapDialogProxy.__WF_BRIDGE__ = BD_ORIG.__WF_BRIDGE__ || true;
664	BootstrapDialogProxy.__BD_ORIG__ = BD_ORIG;
665
666	// Si ya habías secuestrado show(), lo respetamos; si no, creamos fallback
667	if (typeof BD_ORIG.show === `function`)
668	{
669		BootstrapDialogProxy.show = BD_ORIG.show; // si tu show ya es WF, perfecto
670	}
671	else
672	{
673		BootstrapDialogProxy.show = function(opts){ return new WF_BootstrapDialog(opts).realize().open(); };
674	}
675
676	// Y ahora SÍ: sustituimos global
677	window.BootstrapDialog = BootstrapDialogProxy;
678
679	console.log(`[WF Bridge] Soporte constructor activado: new BootstrapDialog(...).realize().open()`);
680
681})(window);

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.