use GODEBUG=embedfollowsymlinks=1 to support symlinked web src files
This commit is contained in:
1 parent
98790dbe3b
commit
5c658db34e
94 files changed
+11
-14
No files matched your search
@@ -0,0 +1,130 @@
|
||||
/**
|
||||
* Spawn modal dialog from template node. Assumes the following structure:
|
||||
* <template>
|
||||
* <dialog>
|
||||
* <p id="prompt"></p>
|
||||
* <div id="body">
|
||||
* <form id="form"> ... </form>
|
||||
* </div>
|
||||
* <div id="controls">
|
||||
* <button value="..." form="form"
|
||||
* <button value="..." form="form"
|
||||
* ...
|
||||
* </div>
|
||||
* </dialog>
|
||||
* </template>
|
||||
* Where prompt is the modal dialog's prompt or header,
|
||||
* body contains an optional form or other information,
|
||||
* and controls contains a series of buttons which controls the form
|
||||
*/
|
||||
export function dialog (template, onclose = async (_result, _form) => { }) {
|
||||
const dialog = template.content.querySelector("dialog").cloneNode(true);
|
||||
document.body.append(dialog);
|
||||
dialog.addEventListener("close", async () => {
|
||||
const formElem = dialog.querySelector("form");
|
||||
const formData = formElem ? new FormData(formElem) : null;
|
||||
await onclose(dialog.returnValue, formData);
|
||||
formElem.reset();
|
||||
dialog.close();
|
||||
dialog.parentElement.removeChild(dialog);
|
||||
});
|
||||
if (!dialog.querySelector("form")) {
|
||||
for (const control of dialog.querySelector("#controls").childNodes) {
|
||||
control.addEventListener("click", async (e) => {
|
||||
e.preventDefault();
|
||||
dialog.close(e.target.value);
|
||||
});
|
||||
}
|
||||
}
|
||||
document.body.append(dialog);
|
||||
dialog.showModal();
|
||||
return dialog;
|
||||
}
|
||||
|
||||
class ErrorDialog extends HTMLElement {
|
||||
shadowRoot = null;
|
||||
dialog = null;
|
||||
errors = null;
|
||||
|
||||
constructor () {
|
||||
super();
|
||||
this.shadowRoot = this.attachShadow({ mode: "open" });
|
||||
this.shadowRoot.innerHTML = `
|
||||
<link rel="stylesheet" href="websrc/modules/w3.css">
|
||||
<link rel="stylesheet" href="websrc/css/style.css">
|
||||
<link rel="stylesheet" href="websrc/css/form.css">
|
||||
<style>
|
||||
#errors {
|
||||
margin-bottom: 0;
|
||||
max-height: 20lh;
|
||||
min-height: 20lh;
|
||||
overflow-y: scroll;
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
}
|
||||
#errors * {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
<dialog class="w3-container w3-card w3-border-0">
|
||||
<form method="dialog">
|
||||
<p class="w3-large" id="prompt">Error</p>
|
||||
<div id="errors" class="flex column"></div>
|
||||
<div class="w3-center" id="controls">
|
||||
<button class="w3-button w3-margin" type="submit" value="ok">OK</button>
|
||||
<button class="w3-button w3-margin" type="submit" value="copy">Copy</button>
|
||||
</div>
|
||||
</form>
|
||||
</dialog>
|
||||
`;
|
||||
this.dialog = this.shadowRoot.querySelector("dialog");
|
||||
this.errors = this.shadowRoot.querySelector("#errors");
|
||||
|
||||
for (const control of this.shadowRoot.querySelector("#controls").childNodes) {
|
||||
control.addEventListener("click", async (e) => {
|
||||
e.preventDefault();
|
||||
this.dialog.close(e.target.value);
|
||||
});
|
||||
}
|
||||
|
||||
this.dialog.addEventListener("close", () => {
|
||||
if (this.dialog.returnValue === "copy") {
|
||||
let errors = "";
|
||||
for (const error of this.errors.childNodes) {
|
||||
errors += `${error.innerText}\n`;
|
||||
}
|
||||
navigator.clipboard.writeText(errors);
|
||||
}
|
||||
this.dialog.close();
|
||||
});
|
||||
}
|
||||
|
||||
appendError (error) {
|
||||
error = `${(new Date()).toUTCString()}: ${error}`;
|
||||
const p = document.createElement("p");
|
||||
p.innerText = error;
|
||||
this.errors.appendChild(p);
|
||||
}
|
||||
|
||||
showModal () {
|
||||
this.dialog.showModal();
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("error-dialog", ErrorDialog);
|
||||
|
||||
export function error (message) {
|
||||
let dialog = document.querySelector("error-dialog");
|
||||
if (dialog === null) {
|
||||
dialog = document.createElement("error-dialog");
|
||||
document.body.append(dialog);
|
||||
dialog.appendError(message);
|
||||
dialog.showModal();
|
||||
}
|
||||
else {
|
||||
dialog.appendError(message);
|
||||
dialog.showModal();
|
||||
}
|
||||
return dialog;
|
||||
}
|
||||
Reference in new issue
Block a user