128 lines
5.4 KiB
JavaScript
128 lines
5.4 KiB
JavaScript
(() => {
|
|
"use strict";
|
|
|
|
const state = { open: false, returnFocus: null, backgroundInert: [] };
|
|
|
|
function currentWorkbenchTheme() {
|
|
return document.documentElement.dataset.glassTheme === "light" ? "light" : "dark";
|
|
}
|
|
|
|
function syncWorkbenchTheme(frame) {
|
|
frame?.contentWindow?.postMessage({
|
|
type: "cognitive-agent:theme-change",
|
|
theme: currentWorkbenchTheme(),
|
|
}, window.location.origin);
|
|
}
|
|
|
|
function setBackgroundInert(inert) {
|
|
const layer = document.querySelector("#firmwareWorkbenchLayer");
|
|
if (!layer) return;
|
|
if (inert) {
|
|
state.backgroundInert = [...document.body.children]
|
|
.filter((element) => element !== layer && !["SCRIPT", "STYLE", "LINK"].includes(element.tagName))
|
|
.map((element) => ({ element, wasInert: element.hasAttribute("inert") }));
|
|
state.backgroundInert.forEach(({ element }) => element.toggleAttribute("inert", true));
|
|
return;
|
|
}
|
|
state.backgroundInert.forEach(({ element, wasInert }) => element.toggleAttribute("inert", wasInert));
|
|
state.backgroundInert = [];
|
|
}
|
|
|
|
function setOpen(open) {
|
|
const next = Boolean(open);
|
|
const layer = document.querySelector("#firmwareWorkbenchLayer");
|
|
const trigger = document.querySelector("#firmwareWorkbenchToggle");
|
|
if (!layer || !trigger || state.open === next) return;
|
|
state.open = next;
|
|
trigger.classList.toggle("active", next);
|
|
trigger.setAttribute("aria-pressed", String(next));
|
|
trigger.setAttribute("aria-expanded", String(next));
|
|
trigger.setAttribute("aria-label", next ? "关闭座椅固件开发工作台" : "打开座椅固件开发工作台");
|
|
trigger.title = next ? "关闭座椅固件开发工作台" : "打开座椅固件开发工作台";
|
|
if (next) {
|
|
state.returnFocus = document.activeElement;
|
|
layer.hidden = false;
|
|
layer.inert = false;
|
|
layer.dataset.open = "true";
|
|
setBackgroundInert(true);
|
|
requestAnimationFrame(() => document.querySelector("#firmwareWorkbenchClose")?.focus());
|
|
} else {
|
|
layer.dataset.open = "false";
|
|
layer.inert = true;
|
|
layer.hidden = true;
|
|
setBackgroundInert(false);
|
|
const target = state.returnFocus instanceof HTMLElement && state.returnFocus.isConnected
|
|
? state.returnFocus
|
|
: trigger;
|
|
state.returnFocus = null;
|
|
target.focus();
|
|
}
|
|
}
|
|
|
|
function mount() {
|
|
const dock = document.querySelector("#v2PanelControlDock");
|
|
if (!dock || document.querySelector("#firmwareWorkbenchToggle")) return false;
|
|
|
|
const trigger = document.createElement("button");
|
|
trigger.id = "firmwareWorkbenchToggle";
|
|
trigger.className = "firmware-workbench-toggle v2-panel-control-button";
|
|
trigger.type = "button";
|
|
trigger.setAttribute("aria-controls", "firmwareWorkbenchLayer");
|
|
trigger.setAttribute("aria-pressed", "false");
|
|
trigger.setAttribute("aria-expanded", "false");
|
|
trigger.setAttribute("aria-label", "打开座椅固件开发工作台");
|
|
trigger.title = "打开座椅固件开发工作台";
|
|
trigger.innerHTML = '<i data-lucide="blocks"></i><span class="visually-hidden">座椅固件开发工作台</span>';
|
|
|
|
const layer = document.createElement("div");
|
|
layer.id = "firmwareWorkbenchLayer";
|
|
layer.className = "firmware-workbench-layer";
|
|
layer.hidden = true;
|
|
layer.inert = true;
|
|
layer.setAttribute("role", "dialog");
|
|
layer.setAttribute("aria-modal", "true");
|
|
layer.setAttribute("aria-labelledby", "firmwareWorkbenchTitle");
|
|
layer.innerHTML = `
|
|
<section class="firmware-workbench-page">
|
|
<header class="firmware-workbench-header">
|
|
<div class="firmware-workbench-heading">
|
|
<span><i data-lucide="blocks"></i></span>
|
|
<h2 id="firmwareWorkbenchTitle">座椅固件开发工作台</h2>
|
|
</div>
|
|
<button id="firmwareWorkbenchClose" type="button" aria-label="关闭座椅固件开发工作台" title="关闭"><i data-lucide="x"></i></button>
|
|
</header>
|
|
<iframe class="firmware-workbench-frame" title="座椅固件开发工作台"></iframe>
|
|
</section>`;
|
|
|
|
dock.append(trigger);
|
|
document.body.append(layer);
|
|
const frame = document.querySelector(".firmware-workbench-frame", layer);
|
|
frame.src = `/firmware-workbench.html?embedded=1&theme=${currentWorkbenchTheme()}`;
|
|
frame.addEventListener("load", () => syncWorkbenchTheme(frame));
|
|
window.addEventListener("cognitive-agent:theme-change", () => syncWorkbenchTheme(frame));
|
|
new MutationObserver(() => syncWorkbenchTheme(frame)).observe(document.documentElement, {
|
|
attributes: true,
|
|
attributeFilter: ["data-glass-theme"],
|
|
});
|
|
trigger.addEventListener("click", () => setOpen(!state.open));
|
|
document.querySelector("#firmwareWorkbenchClose", layer).addEventListener("click", () => setOpen(false));
|
|
layer.addEventListener("click", (event) => { if (event.target === layer) setOpen(false); });
|
|
document.addEventListener("keydown", (event) => {
|
|
if (state.open && event.key === "Escape") {
|
|
event.preventDefault();
|
|
setOpen(false);
|
|
}
|
|
});
|
|
window.lucide?.createIcons({ attrs: { "aria-hidden": "true" } });
|
|
return true;
|
|
}
|
|
|
|
if (!mount()) {
|
|
const observer = new MutationObserver(() => {
|
|
if (mount()) observer.disconnect();
|
|
});
|
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
window.setTimeout(() => observer.disconnect(), 15000);
|
|
}
|
|
})();
|