/** * This file is part of Haketilo. * * Function: Showing and error/info/confirmation dialog. * * Copyright (C) 2022 Wojtek Kosior * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * As additional permission under GNU GPL version 3 section 7, you * may distribute forms of that code without the copy of the GNU * GPL normally required by section 4, provided you include this * license notice and, in case of non-source distribution, a URL * through which recipients can access the Corresponding Source. * If you modify file(s) with this exception, you may extend this * exception to your version of the file(s), but you are not * obligated to do so. If you do not wish to do so, delete this * exception statement from your version. * * As a special exception to the GPL, any HTML file which merely * makes function calls to this code, and for that purpose * includes it by reference shall be deemed a separate work for * copyright law purposes. If you modify this code, you may extend * this exception to your version of the code, but you are not * obligated to do so. If you do not wish to do so, delete this * exception statement from your version. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * I, Wojtek Kosior, thereby promise not to sue for violation of this file's * license. Although I request that you do not make use of this code in a * proprietary program, I am not going to enforce this in court. */ #FROM html/DOM_helpers.js IMPORT clone_template, Showable function make(on_dialog_show, on_dialog_hide) { const dialog_context = clone_template("dialog"); dialog_context.queue = []; Showable.call(dialog_context, on_dialog_show, on_dialog_hide); for (const [id, val] of [["yes", true], ["no", false], ["ok", undefined]]) { const but = dialog_context[`${id}_but`]; but.haketilo_dialog_result = val; but.addEventListener("click", e => close_dialog(dialog_context, e)); } return dialog_context; } #EXPORT make function close_dialog(dialog_context, event) { if ((event && event.target.parentElement.classList.contains("hide")) || dialog_context.queue.length === 0) return; const [[shown_buts_id, msg, resolve]] = dialog_context.queue.splice(0, 1); if (dialog_context.queue.length > 0) { process_queue_item(dialog_context); } else { dialog_context.hide(); } resolve(event ? event.target.haketilo_dialog_result : undefined); } #EXPORT close_dialog AS close function process_queue_item(dialog_context) { const [shown_buts_id, msg, resolve] = dialog_context.queue[0]; [...dialog_context.msg.childNodes].forEach(n => n.remove()); dialog_context.msg.append(...msg); for (const buts_id of ["ask_buts", "conf_buts"]) { const action = buts_id === shown_buts_id ? "remove" : "add"; dialog_context[buts_id].classList[action]("hide"); } } async function show_dialog(dialog_context, shown_buts_id, msg) { let resolve; const result_prom = new Promise(cb => resolve = cb); dialog_context.queue.push([shown_buts_id, msg, resolve]); if (dialog_context.show()) process_queue_item(dialog_context); return await result_prom; } const error = (ctx, ...msg) => show_dialog(ctx, "conf_buts", msg); #EXPORT error /* info() and error() are the same for now, we might later change that. */ const info = error; #EXPORT info const ask = (ctx, ...msg) => show_dialog(ctx, "ask_buts", msg); #EXPORT ask const loader = (ctx, ...msg) => show_dialog(ctx, null, msg); #EXPORT loader