/* * Copyright (C) 2026 Mateusz Gruszczyński @linuxiarz.pl * Source-Available Code / Dual-Licensed. * * Free for non-commercial and evaluation use under terms of BSL/GPLv3. * Commercial or production use requires a valid paid license. * See LICENSE file in repository root for details. */ function ensureDialog() { let dialog = document.querySelector("#system-dialog"); if (dialog) return dialog; dialog = document.createElement("dialog"); dialog.id = "system-dialog"; dialog.className = "app-dialog"; dialog.innerHTML = `
`; document.body.append(dialog); dialog.addEventListener("click", event => { if (event.target === dialog) dialog.close("cancel"); }); return dialog; } export function showMessage(message, { title = "Information", button = "OK" } = {}) { const dialog = ensureDialog(); dialog.querySelector("[data-title]").textContent = title; dialog.querySelector("[data-message]").textContent = message; dialog.querySelector("[data-input-wrap]").hidden = true; dialog.querySelector("[data-cancel]").hidden = true; dialog.querySelector("[data-confirm]").textContent = button; dialog.showModal(); return new Promise(resolve => dialog.addEventListener("close", () => resolve(), { once: true })); } export function askConfirm(message, { title = "Confirm", confirmText = "Confirm", danger = false } = {}) { const dialog = ensureDialog(); dialog.querySelector("[data-title]").textContent = title; dialog.querySelector("[data-message]").textContent = message; dialog.querySelector("[data-input-wrap]").hidden = true; dialog.querySelector("[data-cancel]").hidden = false; const confirm = dialog.querySelector("[data-confirm]"); confirm.textContent = confirmText; confirm.classList.toggle("danger-button", danger); dialog.showModal(); return new Promise(resolve => dialog.addEventListener("close", () => { confirm.classList.remove("danger-button"); resolve(dialog.returnValue === "confirm"); }, { once: true })); } export function askInput({ title, message = "", label, type = "text", autocomplete = "off", minLength, placeholder = "", confirmText = "Continue", bitwardenIgnore = false }) { const dialog = ensureDialog(); dialog.querySelector("[data-title]").textContent = title; dialog.querySelector("[data-message]").textContent = message; const wrap = dialog.querySelector("[data-input-wrap]"); const input = dialog.querySelector("[data-input]"); wrap.hidden = false; dialog.querySelector("[data-input-label]").textContent = label; input.type = type; input.value = ""; input.autocomplete = autocomplete; input.placeholder = placeholder; input.name = type === "password" ? "new-password" : type === "email" ? "email" : "modal-input"; if (bitwardenIgnore) input.setAttribute("data-bwignore", "true"); else input.removeAttribute("data-bwignore"); input.minLength = minLength || 0; dialog.querySelector("[data-cancel]").hidden = false; dialog.querySelector("[data-confirm]").textContent = confirmText; dialog.showModal(); queueMicrotask(() => input.focus()); return new Promise(resolve => dialog.addEventListener("close", () => resolve(dialog.returnValue === "confirm" ? input.value : null), { once: true })); }