PageSourceSearch

https://qedine.com/wp-content/plugins/futbol-partidos-tabs-pro/assets/js/fp-tabs.js?ver=4.3

js qedine.com collected 2026-10-03 01:41:16 UTC 10,661 bytes, 236 lines download raw bytes

1(function () {
2    'use strict';
3
4    var REFRESH_INTERVAL_MS = 60000; // cada cuánto se piden datos frescos en segundo plano
5
6    function initTabs(root) {
7        root.querySelectorAll('.fp-tab-btn').forEach(function (btn) {
8            btn.addEventListener('click', function () {
9                root.dataset.userTab = btn.dataset.target; // recordar la pestaña elegida por el usuario
10                root.querySelectorAll('.fp-tab-btn').forEach(function (b) { b.classList.remove('active'); });
11                root.querySelectorAll('.fp-slider-rel').forEach(function (s) { s.classList.remove('active'); });
12                btn.classList.add('active');
13                var panel = root.querySelector('.fp-slider-rel[data-tab="' + btn.dataset.target + '"]');
14                if (panel) panel.classList.add('active');
15            });
16        });
17    }
18
19    function initNav(root) {
20        root.querySelectorAll('.fp-next').forEach(function (btn) {
21            btn.addEventListener('click', function () {
22                btn.parentElement.querySelector('.fp-scroll-row').scrollBy({ left: 280, behavior: 'smooth' });
23            });
24        });
25        root.querySelectorAll('.fp-prev').forEach(function (btn) {
26            btn.addEventListener('click', function () {
27                btn.parentElement.querySelector('.fp-scroll-row').scrollBy({ left: -280, behavior: 'smooth' });
28            });
29        });
30    }
31
32    function initLigasPanel(root) {
33        var ligasBtn = root.querySelector('.fp-ligas-btn');
34        var ligasPanel = root.querySelector('.fp-ligas-panel');
35        if (!ligasBtn) return;
36
37        ligasBtn.addEventListener('click', function () {
38            ligasPanel.classList.toggle('open');
39        });
40        document.addEventListener('click', function (e) {
41            if (!root.querySelector('.fp-ligas-wrap').contains(e.target)) {
42                ligasPanel.classList.remove('open');
43            }
44        });
45    }
46
47    // Mensaje "no hay partidos de esta liga" para las filas normales
48    // (pestañas Hoy/Mañana). En la agenda no se usa por fila/día, porque el
49    // bloque del día entero se oculta cuando no tiene partidos de la liga
50    // elegida (ver showAgendaEmptyMessage más abajo, que cubre el caso de
51    // que TODOS los días queden ocultos).
52    function showEmptyMessage(row, code) {
53        var visibles = row.querySelectorAll('.fp-card:not([style*="display: none"])');
54        var empty = row.querySelector('.fp-empty-filtered');
55        if (code && visibles.length === 0) {
56            if (!empty) {
57                empty = document.createElement('p');
58                empty.className = 'fp-empty fp-empty-filtered';
59                empty.textContent = 'No hay partidos de esta liga.';
60                row.appendChild(empty);
61            }
62        } else if (empty) {
63            empty.remove();
64        }
65    }
66
67    // Si, tras filtrar por liga, ningún día de la agenda tiene partidos
68    // visibles, se muestra un único aviso a nivel de agenda completa (en
69    // vez de dejar el bloque en blanco sin explicación).
70    function showAgendaEmptyMessage(root, code) {
71        var body = root.querySelector('.fp-agenda-body');
72        if (!body) return;
73        var diasVisibles = body.querySelectorAll('.fp-agenda-day:not([style*="display: none"])');
74        var empty = body.querySelector('.fp-empty-filtered');
75        if (code && diasVisibles.length === 0) {
76            if (!empty) {
77                empty = document.createElement('p');
78                empty.className = 'fp-empty fp-empty-filtered';
79                empty.textContent = 'No hay partidos de esta liga en los próximos días.';
80                body.appendChild(empty);
81            }
82        } else if (empty) {
83            empty.remove();
84        }
85    }
86
87    // Aplica el filtro de liga actual (por código) a las tarjetas ya
88    // presentes en el DOM. Se usa tanto al hacer clic en una liga como
89    // después de cada auto-refresh, para no perder el filtro elegido.
90    // Funciona igual en las pestañas Hoy/Mañana (.fp-scroll-row) que en la
91    // agenda de página completa agrupada por día (.fp-list-row).
92    function applyLigaFilter(root, code) {
93        root.querySelectorAll('.fp-card, .fp-list-row').forEach(function (card) {
94            var match = !code || card.dataset.liga === code;
95            card.style.display = match ? '' : 'none';
96        });
97
98        // Los placeholders se ocultan al filtrar para no dejar huecos de
99        // "faltan partidos" cuando en realidad hay más partidos fuera de
100        // la liga seleccionada.
101        root.querySelectorAll('.fp-card-placeholder').forEach(function (ph) {
102            ph.style.display = code ? 'none' : '';
103        });
104
105        root.querySelectorAll('.fp-scroll-row').forEach(function (row) {
106            showEmptyMessage(row, code);
107        });
108
109        // En la agenda, si un día se queda sin partidos tras filtrar, se
110        // oculta el bloque completo de ese día (encabezado incluido).
111        root.querySelectorAll('.fp-agenda-day').forEach(function (day) {
112            var visibles = day.querySelectorAll('.fp-list-row:not([style*="display: none"])');
113            day.style.display = (code && visibles.length === 0) ? 'none' : '';
114        });
115
116        if (root.dataset.agenda) {
117            showAgendaEmptyMessage(root, code);
118        }
119    }
120
121    function initLigaFilter(root) {
122        var ligasBtn = root.querySelector('.fp-ligas-btn');
123        var ligasPanel = root.querySelector('.fp-ligas-panel');
124
125        root.querySelectorAll('.fp-liga-opt').forEach(function (opt) {
126            opt.addEventListener('click', function (e) {
127                e.preventDefault();
128                var code = opt.dataset.code;
129
130                root.querySelectorAll('.fp-liga-opt').forEach(function (o) { o.classList.remove('active'); });
131                opt.classList.add('active');
132                root.dataset.ligaCode = code; // recordar el filtro elegido por el usuario
133
134                applyLigaFilter(root, code);
135
136                ligasBtn.innerHTML = (code ? opt.textContent : 'Ligas') + ' <span>⌄</span>';
137                if (ligasPanel) ligasPanel.classList.remove('open');
138            });
139        });
140    }
141
142    // Pide los partidos de Hoy/Mañana frescos al servidor. En la primera
143    // carga (isInitial) usa la pestaña que la API recomienda por defecto. En
144    // los refrescos automáticos posteriores respeta la pestaña y el filtro
145    // de liga que el usuario ya haya elegido, para no interrumpirlo.
146    function loadMatches(root, isInitial) {
147        if (typeof fpTabsData === 'undefined') return;
148
149        var url = fpTabsData.ajaxUrl
150            + '?action=fp_get_matches'
151            + '&nonce=' + encodeURIComponent(fpTabsData.nonce)
152            + '&_=' + Date.now(); // evita que la propia URL se quede cacheada
153
154        fetch(url, { credentials: 'same-origin', cache: 'no-store' })
155            .then(function (res) { return res.json(); })
156            .then(function (json) {
157                if (!json || !json.success) return;
158                var data = json.data;
159
160                var hoyBtn = root.querySelector('.fp-tab-btn[data-target="hoy"] span');
161                var mananaBtn = root.querySelector('.fp-tab-btn[data-target="manana"] span');
162                if (hoyBtn) hoyBtn.textContent = data.hoyLabel;
163                if (mananaBtn) mananaBtn.textContent = data.mananaLabel;
164
165                var hoyRow = root.querySelector('.fp-slider-rel[data-tab="hoy"] .fp-scroll-row');
166                var mananaRow = root.querySelector('.fp-slider-rel[data-tab="manana"] .fp-scroll-row');
167                if (hoyRow) hoyRow.innerHTML = data.hoyHtml;
168                if (mananaRow) mananaRow.innerHTML = data.mananaHtml;
169
170                var targetTab = isInitial ? data.defaultTab : (root.dataset.userTab || data.defaultTab);
171                root.querySelectorAll('.fp-tab-btn').forEach(function (b) { b.classList.remove('active'); });
172                root.querySelectorAll('.fp-slider-rel').forEach(function (s) { s.classList.remove('active'); });
173                var activeBtn = root.querySelector('.fp-tab-btn[data-target="' + targetTab + '"]');
174                var activePanel = root.querySelector('.fp-slider-rel[data-tab="' + targetTab + '"]');
175                if (activeBtn) activeBtn.classList.add('active');
176                if (activePanel) activePanel.classList.add('active');
177
178                var ligaCode = root.dataset.ligaCode || '';
179                if (ligaCode) applyLigaFilter(root, ligaCode);
180            })
181            .catch(function () { /* si falla, se conserva el contenido que ya había en pantalla */ });
182    }
183
184    // Pide la agenda completa (varios días agrupados) fresca al servidor y
185    // reemplaza el cuerpo entero, reaplicando el filtro de liga si había uno.
186    function loadAgenda(root) {
187        if (typeof fpTabsData === 'undefined') return;
188
189        var dias = root.dataset.dias || '';
190        var url = fpTabsData.ajaxUrl
191            + '?action=fp_get_agenda'
192            + '&nonce=' + encodeURIComponent(fpTabsData.nonce)
193            + (dias ? '&dias=' + encodeURIComponent(dias) : '')
194            + '&_=' + Date.now();
195
196        fetch(url, { credentials: 'same-origin', cache: 'no-store' })
197            .then(function (res) { return res.json(); })
198            .then(function (json) {
199                if (!json || !json.success) return;
200                var body = root.querySelector('.fp-agenda-body');
201                if (body) body.innerHTML = json.data.html;
202
203                var ligaCode = root.dataset.ligaCode || '';
204                if (ligaCode) applyLigaFilter(root, ligaCode);
205            })
206            .catch(function () { /* si falla, se conserva el contenido que ya había en pantalla */ });
207    }
208
209    function initAutoRefresh(root, loader) {
210        setInterval(function () {
211            // No pedimos datos si la pestaña del navegador está en segundo
212            // plano, para no gastar cuota de la API sin que nadie lo vea.
213            if (document.hidden) return;
214            loader(root, false);
215        }, REFRESH_INTERVAL_MS);
216    }
217
218    function initInstance(root) {
219        initNav(root);
220        initLigasPanel(root);
221        initLigaFilter(root);
222
223        if (root.dataset.agenda) {
224            loadAgenda(root);
225            initAutoRefresh(root, loadAgenda);
226        } else {
227            initTabs(root);
228            loadMatches(root, true);
229            initAutoRefresh(root, loadMatches);
230        }
231    }
232
233    document.addEventListener('DOMContentLoaded', function () {
234        document.querySelectorAll('.fp-main-container').forEach(initInstance);
235    });
236})();

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.