Files
site/WESP_REL/static/js/kiosk-calibration.js
2026-07-17 12:57:18 +03:00

171 lines
5.4 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Модальное окно «Калибровка»: 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 = `
<div class="kiosk-calibration-panel kiosk-calibration-panel--${panelTheme}" role="dialog" aria-modal="true" aria-labelledby="kioskCalibrationTitle">
<div class="kiosk-calibration-head">
<h2 class="kiosk-calibration-title" id="kioskCalibrationTitle">Калибровка весов</h2>
<button type="button" class="kiosk-calibration-close" id="kioskCalibrationClose">Закрыть</button>
</div>
<iframe
id="kioskCalibrationFrame"
class="kiosk-calibration-frame"
title="Калибровка весов"
></iframe>
</div>
`;
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 };
})();