From 2e406f4480f528829a0a849aab9d6d46ab5d94ae Mon Sep 17 00:00:00 2001 From: Magnus Hoff Date: Fri, 24 Nov 2017 17:04:36 +0100 Subject: [PATCH] Handle authorization problems when saving article with JS --- assets/script.js | 91 +++++++++++++++++++++++++++++++++++------------- assets/style.css | 23 ++++++++++++ 2 files changed, 89 insertions(+), 25 deletions(-) diff --git a/assets/script.js b/assets/script.js index 5b5686f..30e781b 100644 --- a/assets/script.js +++ b/assets/script.js @@ -20,6 +20,38 @@ function isEdited(form) { return false; } +function loginDialog(loginUrl) { + const loginDialogHtml = ""; + + const dialog = document.createElement("div"); + dialog.className = "modal-block"; + dialog.innerHTML = loginDialogHtml; + + const loginLink = dialog.querySelector("a"); + const dismiss = dialog.querySelector("button"); + + loginLink.setAttribute("href", loginUrl); + + document.body.appendChild(dialog); + loginLink.focus(); + + function remove() { + document.body.removeChild(dialog); + } + + return new Promise((resolve, reject) => { + loginLink.addEventListener("click", () => { + remove(); + resolve(); + }); + + dismiss.addEventListener("click", () => { + remove(); + resolve(); + }); + }); +} + let hasBeenOpen = false; function openEditor() { const container = document.querySelector(".container"); @@ -53,6 +85,7 @@ function openEditor() { const body = queryArgsFromForm(form); textarea.disabled = true; + // TODO Disable other interaction as well: title editor, cancel and OK buttons fetch( form.getAttribute("action"), @@ -65,39 +98,47 @@ function openEditor() { credentials: "same-origin", } ).then(response => { + if ((response.status === 401) && (response.headers.has("location"))) { + return loginDialog(response.headers.get("location")) + .then(() => { + textarea.disabled = false; + }); + } + if (!response.ok) throw new Error("Unexpected status code (" + response.status + ")"); - return response.json(); - }).then(result => { - // Update url-bar, page title and footer - window.history.replaceState(null, result.title, result.slug == "" ? "." : result.slug); - document.querySelector("title").textContent = result.title; - lastUpdated.innerHTML = result.last_updated; - lastUpdated.classList.remove("missing"); + return response.json() + .then(result => { + // Update url-bar, page title and footer + window.history.replaceState(null, result.title, result.slug == "" ? "." : result.slug); + document.querySelector("title").textContent = result.title; + lastUpdated.innerHTML = result.last_updated; + lastUpdated.classList.remove("missing"); - // Update body: - rendered.innerHTML = result.rendered; + // Update body: + rendered.innerHTML = result.rendered; - form.elements.title.value = result.title; - shadow.value = textarea.value = result.body; + form.elements.title.value = result.title; + shadow.value = textarea.value = result.body; - // Update form: - form.elements.base_revision.value = result.revision; - for (const element of form.elements) { - element.defaultValue = element.value; - } + // Update form: + form.elements.base_revision.value = result.revision; + for (const element of form.elements) { + element.defaultValue = element.value; + } - if (!result.conflict) { - container.classList.remove('edit'); - } + if (!result.conflict) { + container.classList.remove('edit'); + } - textarea.disabled = false; - autosizeTextarea(textarea, shadow); + textarea.disabled = false; + autosizeTextarea(textarea, shadow); - if (result.conflict) { - alert("Your edit came into conflict with another change and has not been saved.\n" + - "Please resolve the merge conflict and save again."); - } + if (result.conflict) { + alert("Your edit came into conflict with another change and has not been saved.\n" + + "Please resolve the merge conflict and save again."); + } + }); }).catch(err => { textarea.disabled = false; console.error(err); diff --git a/assets/style.css b/assets/style.css index 002c345..0ff1b01 100644 --- a/assets/style.css +++ b/assets/style.css @@ -431,6 +431,29 @@ input[type="search"] { background: #ceb; } +.modal-block { + position: fixed; + left: 0; + right: 0; + top: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.6); +} + +.popup { + position: fixed; + + width: 300px; + left: calc(50% - 150px); + + height: 150px; + top: calc(50% - 75px); + + text-align: center; + background: #eee; + box-shadow: 2px 2px 8px rgba(0,0,0, 0.25); +} + @media print { @page { margin: 25mm;