From 205a36008672c7137e9190f243a9ba137d679e11 Mon Sep 17 00:00:00 2001
From: xengineering <me@xengineering.eu>
Date: Sun, 23 Apr 2023 22:01:50 +0200
Subject: Replace JavaScript on edit page by form

This is actually possible when using <textarea> instead of <pre>. With
this change the recipe server has full support for browsers without
JavaScript.
---
 data/templates/recipe_edit.html | 17 ++++++-----------
 handler.go                      | 31 ++++++++++++++++---------------
 2 files changed, 22 insertions(+), 26 deletions(-)

diff --git a/data/templates/recipe_edit.html b/data/templates/recipe_edit.html
index fc1d74c..6ef41f8 100644
--- a/data/templates/recipe_edit.html
+++ b/data/templates/recipe_edit.html
@@ -14,18 +14,13 @@
 		</header>
 
 		<main>
-			<pre contenteditable="true" id="editor">{{.Text}}</pre>
-			<button onclick="save()">save</button>
-			<a href="/recipe?id={{.Id}}"><button>back</button></a>
+			<form action="/recipe/edit" method="POST">
+				<input type="hidden" name="id" value="{{.Id}}" />
+				<textarea style="resize:none;font-family:monospace, monospace;font-size: 1rem;" rows="18" wrap="soft" name="text">{{.Text}}</textarea>
+				<button type="submit">save</button>
+				<a href="/recipe?id={{.Id}}"><button type="button">cancel</button></a>
+			</form>
 			{{ template "footer.html" }}
 		</main>
-
-		<script>
-			function save() {
-				const xhttp = new XMLHttpRequest();
-				xhttp.open("POST", "/recipe/edit?id={{.Id}}", true);
-				xhttp.send(document.getElementById('editor').innerText);
-			}
-		</script>
 	</body>
 </html>
diff --git a/handler.go b/handler.go
index ceb0e08..e2d2183 100644
--- a/handler.go
+++ b/handler.go
@@ -37,7 +37,7 @@ func recipeGet(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	data := struct{
+	data := struct {
 		Id     string
 		Recipe recipe
 	}{idStr, rec}
@@ -67,7 +67,7 @@ func recipeEditGet(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	recipe := struct{
+	recipe := struct {
 		Id    string
 		Title string
 		Text  string
@@ -78,12 +78,17 @@ func recipeEditGet(w http.ResponseWriter, r *http.Request) {
 
 func recipeEditPost(w http.ResponseWriter, r *http.Request) {
 
-	ids := r.URL.Query()["id"]
-	if len(ids) != 1 {
-		http.Error(w, "Exactly 1 'id' URL parameter expected.", 400)
-		return
+	r.ParseForm()
+
+	for _, v := range []string{"id", "text"} {
+		if len(r.Form[v]) != 1 {
+			http.Error(w, "Exactly 1 '"+v+"' form parameter expected.", 400)
+			return
+		}
 	}
-	idStr := ids[0]
+
+	idStr := r.Form["id"][0]
+	buffer := r.Form["text"][0]
 
 	idRegex := regexp.MustCompile(VALID_ID_REGEX)
 	if !(idRegex.MatchString(idStr)) {
@@ -91,17 +96,13 @@ func recipeEditPost(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	buffer, err := ioutil.ReadAll(r.Body)
-	if err != nil {
-		http.Error(w, "Could not read request body.", 400)
-		return
-	}
-
 	textpath := filepath.Join(config.Data, "recipes", idStr, "text")
-	err = ioutil.WriteFile(textpath, buffer, 0644)
+	err := ioutil.WriteFile(textpath, []byte(buffer), 0644)
 	if err != nil {
 		http.Error(w, "Could not save new text for recipe.", 500)
 	}
+
+	http.Redirect(w, r, "/recipe?id="+idStr, 303)
 }
 
 func recipeConfirmDeletionGet(w http.ResponseWriter, r *http.Request) {
@@ -112,7 +113,7 @@ func recipeConfirmDeletionGet(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	ServeTemplate(w, "recipe_confirm_deletion.html", struct{Id string}{ids[0]})
+	ServeTemplate(w, "recipe_confirm_deletion.html", struct{ Id string }{ids[0]})
 }
 
 func recipeConfirmDeletionPost(w http.ResponseWriter, r *http.Request) {
-- 
cgit v1.2.3-70-g09d2