(function () { 'use strict'; // ── Track setIntervals so navigation can clear them ─────────────────────── const _origSetInterval = window.setInterval.bind(window); const _origClearInterval = window.clearInterval.bind(window); let _intervals = []; window.setInterval = function (fn, ms, ...args) { const id = _origSetInterval(fn, ms, ...args); _intervals.push(id); return id; }; function clearTrackedIntervals() { _intervals.forEach(id => _origClearInterval(id)); _intervals = []; } // ── Cleanup state left behind by the outgoing page ──────────────────────── function cleanupPage() { clearTrackedIntervals(); // DataTables 2.x if (window.DataTable) { try { DataTable.tables({ api: true }).destroy(); } catch (_) {} } // Dropzone if (window.Dropzone) { try { [...Dropzone.instances].forEach(dz => dz.destroy()); } catch (_) {} } // Bootstrap modals – hide any open one and remove leftover backdrops document.querySelectorAll('.modal.show').forEach(el => { try { bootstrap.Modal.getInstance(el)?.hide(); } catch (_) {} }); document.querySelectorAll('.modal-backdrop').forEach(el => el.remove()); document.body.classList.remove('modal-open'); document.body.style.removeProperty('padding-right'); } function swapPageModals(doc) { document.querySelectorAll('[data-ajax-modal="true"]').forEach(el => el.remove()); doc.querySelectorAll('body > .modal').forEach(old => { const wrapper = document.createElement('div'); wrapper.innerHTML = old.outerHTML; const modal = wrapper.firstElementChild; if (!modal) return; modal.setAttribute('data-ajax-modal', 'true'); document.body.appendChild(modal); }); } // ── Per-page inline