75 lines
3.6 KiB
JavaScript
75 lines
3.6 KiB
JavaScript
/* Без JavaScript все схемы остаются видимыми, ссылки открывают исходные иллюстрации. */
|
|
"use strict";
|
|
|
|
const tabs = Array.from(document.querySelectorAll('[role="tab"]'));
|
|
const panels = tabs.map((tab) => document.getElementById(tab.getAttribute("aria-controls")));
|
|
const tabList = document.querySelector(".diagram-tabs");
|
|
|
|
// Выбор схемы синхронизирует видимость, фокус и состояние доступности.
|
|
function selectDiagram(index) {
|
|
tabs.forEach((tab, position) => {
|
|
const selected = position === index;
|
|
tab.setAttribute("aria-selected", String(selected));
|
|
tab.tabIndex = selected ? 0 : -1;
|
|
panels[position].hidden = !selected;
|
|
});
|
|
console.debug("[VibeChat] Выбрана схема:", panels[index].id);
|
|
}
|
|
|
|
tabs.forEach((tab, index) => {
|
|
panels[index].setAttribute("role", "tabpanel");
|
|
panels[index].setAttribute("aria-labelledby", tab.id);
|
|
panels[index].tabIndex = 0;
|
|
tab.addEventListener("click", () => selectDiagram(index));
|
|
tab.addEventListener("keydown", (event) => {
|
|
let next = index;
|
|
if (event.key === "ArrowRight") next = (index + 1) % tabs.length;
|
|
else if (event.key === "ArrowLeft") next = (index + tabs.length - 1) % tabs.length;
|
|
else if (event.key === "Home") next = 0;
|
|
else if (event.key === "End") next = tabs.length - 1;
|
|
else return;
|
|
event.preventDefault();
|
|
selectDiagram(next);
|
|
tabs[next].focus();
|
|
});
|
|
});
|
|
selectDiagram(0);
|
|
tabList.hidden = false;
|
|
document.getElementById("network").classList.add("tabs-ready");
|
|
|
|
const dialog = document.querySelector(".image-dialog");
|
|
const dialogImage = dialog.querySelector(".dialog-image");
|
|
|
|
if (typeof dialog.showModal === "function") {
|
|
document.querySelectorAll("[data-enlarge]").forEach((link) => {
|
|
link.addEventListener("click", (event) => {
|
|
if (event.ctrlKey || event.metaKey || event.shiftKey || event.altKey) return;
|
|
event.preventDefault();
|
|
const source = link.querySelector("img");
|
|
dialogImage.src = source.src;
|
|
dialogImage.alt = source.alt;
|
|
dialog.showModal();
|
|
dialog.querySelector(".dialog-image-wrap").scrollLeft = 0;
|
|
console.debug("[VibeChat] Открыта увеличенная схема:", link.getAttribute("href"));
|
|
});
|
|
});
|
|
dialog.querySelector(".dialog-close").addEventListener("click", () => dialog.close());
|
|
dialog.addEventListener("click", (event) => {
|
|
const bounds = dialog.getBoundingClientRect();
|
|
const outside = event.clientX < bounds.left || event.clientX > bounds.right
|
|
|| event.clientY < bounds.top || event.clientY > bounds.bottom;
|
|
if (event.target === dialog && outside) dialog.close();
|
|
});
|
|
dialog.addEventListener("close", () => console.debug("[VibeChat] Увеличенная схема закрыта"));
|
|
} else {
|
|
console.warn("[VibeChat] Просмотр в диалоге недоступен; схемы открываются по обычным ссылкам");
|
|
}
|
|
|
|
document.querySelectorAll("img").forEach((image) => {
|
|
image.addEventListener("error", () => console.error("[VibeChat] Не удалось загрузить иллюстрацию:", image.src));
|
|
if (image.getAttribute("src") && image.complete && !image.naturalWidth) {
|
|
console.error("[VibeChat] Иллюстрация недоступна:", image.src);
|
|
}
|
|
});
|
|
console.info("[VibeChat] Презентация готова; схем:", tabs.length);
|