/** * Модальное окно «Калибровка»: iframe с /calibration?embed=1. */ (function () { const LOG = "[WespKioskCalibration]"; const MENU_OVERLAY_ID = "wespKioskMenuOverlay"; function ensureStylesheet() { if (document.getElementById("kioskCalibrationModalCss")) return; const link = document.createElement("link"); link.id = "kioskCalibrationModalCss"; link.rel = "stylesheet"; link.href = "/static/css/kiosk-calibration-modal.css"; document.head.appendChild(link); } function resizeFrame(iframe) { if (!iframe || !iframe.contentDocument) return; try { const doc = iframe.contentDocument; const height = Math.max( doc.body?.scrollHeight || 0, doc.documentElement?.scrollHeight || 0, 320, ); const max = Math.floor(window.innerHeight * 0.82) - 64; iframe.style.height = `${Math.min(height + 4, max)}px`; } catch (e) { console.warn(LOG, "iframe resize", e); } } function createModal(options) { ensureStylesheet(); const opts = options || {}; const zIndex = Number(opts.zIndex) > 0 ? Number(opts.zIndex) : 5000; const light = opts.theme === "light"; const panelTheme = light ? "light" : "dark"; const modal = document.createElement("div"); modal.id = "kioskCalibrationModal"; modal.className = "kiosk-calibration-backdrop"; modal.setAttribute("aria-hidden", "true"); modal.style.zIndex = String(zIndex); modal.innerHTML = ` `; document.body.appendChild(modal); const iframe = modal.querySelector("#kioskCalibrationFrame"); const closeBtn = modal.querySelector("#kioskCalibrationClose"); const panel = modal.querySelector(".kiosk-calibration-panel"); function closeModal() { modal.classList.remove("is-open"); modal.setAttribute("aria-hidden", "true"); try { iframe.src = "about:blank"; iframe.style.height = ""; } catch (e) { console.warn(LOG, "iframe reset", e); } document.removeEventListener("keydown", onKey); } function onKey(e) { if (e.key === "Escape") { e.preventDefault(); closeModal(); } } function openModal() { const menu = document.getElementById(MENU_OVERLAY_ID); if (menu) menu.style.display = "none"; iframe.onload = function () { window.setTimeout(function () { resizeFrame(iframe); }, 50); }; iframe.src = "/calibration?embed=1"; modal.classList.add("is-open"); modal.setAttribute("aria-hidden", "false"); document.addEventListener("keydown", onKey); } closeBtn.addEventListener("click", closeModal); modal.addEventListener("click", function (e) { if (e.target === modal) closeModal(); }); if (panel) { panel.addEventListener("click", function (e) { e.stopPropagation(); }); } return { modal, iframe, openModal, closeModal, resizeFrame }; } function ensureModal(options) { const opts = options || {}; if (!window.__wespKioskCalibrationApi) { window.__wespKioskCalibrationApi = createModal(opts); } else if (Number(opts.zIndex) > 0) { window.__wespKioskCalibrationApi.modal.style.zIndex = String(opts.zIndex); } return window.__wespKioskCalibrationApi; } function openModal(options) { const api = ensureModal(options); const panel = api.modal.querySelector(".kiosk-calibration-panel"); if (panel && options && options.theme) { const dark = options.theme === "dark"; panel.classList.toggle("kiosk-calibration-panel--dark", dark); panel.classList.toggle("kiosk-calibration-panel--light", !dark); } api.openModal(); return api; } function setup(opts) { const options = opts || {}; const linkSel = options.menuLinkSelector || "#calibrationLink"; if (typeof window.WespKioskMenu !== "undefined" && typeof window.WespKioskMenu.ensureOverlay === "function") { window.WespKioskMenu.ensureOverlay(); } const link = document.querySelector(linkSel); if (!link) { console.warn(LOG, "ссылка меню не найдена после ensureOverlay:", linkSel); return {}; } const api = ensureModal(options); if (link.dataset.wespCalibrationBound === "1") { return { openModal: api.openModal, closeModal: api.closeModal }; } link.dataset.wespCalibrationBound = "1"; link.addEventListener( "click", function (e) { if (e.ctrlKey || e.metaKey || e.shiftKey || e.button !== 0) return; if (window.frameElement) return; e.preventDefault(); e.stopPropagation(); api.openModal(); }, true, ); return { openModal: api.openModal, closeModal: api.closeModal }; } window.WespKioskCalibration = { setup, ensureModal, openModal }; })();