77 lines
3.2 KiB
JavaScript
77 lines
3.2 KiB
JavaScript
"use strict";
|
|
|
|
(function (global) {
|
|
const queue = [];
|
|
let active = null;
|
|
|
|
function ensureDialog() {
|
|
let dialog = document.getElementById("gameConfirmDialog");
|
|
if (dialog) return dialog;
|
|
dialog = document.createElement("div");
|
|
dialog.id = "gameConfirmDialog";
|
|
dialog.className = "field-dialog game-confirm-dialog hidden";
|
|
dialog.setAttribute("role", "alertdialog");
|
|
dialog.setAttribute("aria-modal", "true");
|
|
dialog.setAttribute("aria-labelledby", "gameConfirmDialogTitle");
|
|
dialog.setAttribute("aria-describedby", "gameConfirmDialogMessage");
|
|
dialog.innerHTML = `
|
|
<div class="field-dialog-panel game-confirm-panel">
|
|
<h2 id="gameConfirmDialogTitle"></h2>
|
|
<p id="gameConfirmDialogMessage" class="field-dialog-lead game-confirm-message"></p>
|
|
<div class="field-dialog-actions game-confirm-actions">
|
|
<button class="btn" data-game-dialog-cancel type="button"></button>
|
|
<button class="btn primary" data-game-dialog-confirm type="button"></button>
|
|
</div>
|
|
</div>`;
|
|
document.body.appendChild(dialog);
|
|
dialog.addEventListener("click", event => {
|
|
if (!active) return;
|
|
if (event.target === dialog || event.target.closest("[data-game-dialog-cancel]")) settle(false);
|
|
else if (event.target.closest("[data-game-dialog-confirm]")) settle(true);
|
|
});
|
|
document.addEventListener("keydown", event => {
|
|
if (!active || dialog.classList.contains("hidden")) return;
|
|
if (event.key === "Escape") { event.preventDefault(); event.stopImmediatePropagation?.(); settle(false); }
|
|
}, true);
|
|
return dialog;
|
|
}
|
|
|
|
function pump() {
|
|
if (active || !queue.length) return;
|
|
active = queue.shift();
|
|
const dialog = ensureDialog();
|
|
const title = dialog.querySelector("#gameConfirmDialogTitle");
|
|
const message = dialog.querySelector("#gameConfirmDialogMessage");
|
|
const confirmButton = dialog.querySelector("[data-game-dialog-confirm]");
|
|
const cancelButton = dialog.querySelector("[data-game-dialog-cancel]");
|
|
if (title) title.textContent = active.options.title || "\u78ba\u8a8d";
|
|
if (message) message.textContent = active.options.message || "";
|
|
if (confirmButton) {
|
|
confirmButton.textContent = active.options.confirmText || "\u5b9f\u884c";
|
|
confirmButton.classList.toggle("danger", Boolean(active.options.danger));
|
|
confirmButton.classList.toggle("primary", !active.options.danger);
|
|
}
|
|
if (cancelButton) cancelButton.textContent = active.options.cancelText || "\u30ad\u30e3\u30f3\u30bb\u30eb";
|
|
dialog.classList.remove("hidden");
|
|
global.setTimeout(() => confirmButton?.focus?.(), 0);
|
|
}
|
|
|
|
function settle(accepted) {
|
|
if (!active) return;
|
|
const current = active;
|
|
active = null;
|
|
document.getElementById("gameConfirmDialog")?.classList.add("hidden");
|
|
current.restoreFocus?.focus?.();
|
|
current.resolve(Boolean(accepted));
|
|
global.setTimeout(pump, 0);
|
|
}
|
|
|
|
function confirm(options = {}) {
|
|
return new Promise(resolve => {
|
|
queue.push({ options: { ...options }, resolve, restoreFocus: document.activeElement || null });
|
|
pump();
|
|
});
|
|
}
|
|
|
|
global.TarinaiGameDialogs = Object.freeze({ confirm });
|
|
})(typeof window !== "undefined" ? window : globalThis);
|