commit 30098218a60d82870cce5b8b674d1b713446a9c1
parent 3d0501dfff01387d08502f1f610b1154415cb20f
Author: Jacob R. Edwards <jacob@jacobedwards.org>
Date: Tue, 6 Aug 2024 15:09:12 -0700
Use Javascript modules
Nothing besides by which name functions are called, and in some
cases where they are defined, should have been changed.
Diffstat:
13 files changed, 168 insertions(+), 160 deletions(-)
diff --git a/files/floorplans/index.html b/files/floorplans/index.html
@@ -3,10 +3,7 @@
<title>Spaceplanner - Floorplans</title>
<link rel="stylesheet" type="text/css" href="/css/main.css">
<link rel="stylesheet" type="text/css" href="./main.css">
- <script src="/lib/api.js" async></script>
- <script src="/lib/bar.js" async></script>
- <script src="/lib/etc.js" async></script>
- <script src="./main.js" async></script>
+ <script type="module" src="./main.js"></script>
</head>
<html>
<h1>Floorplans</h1>
diff --git a/files/floorplans/main.js b/files/floorplans/main.js
@@ -1,7 +1,11 @@
+import * as api from "/lib/api.js"
+import * as etc from "/lib/etc.js"
+
function init() {
- authorize()
- show_bar()
- display_button = document.getElementById("display_method")
+ etc.authorize()
+ etc.bar()
+
+ let display_button = document.getElementById("display_method")
if (!display_button) {
throw new Error("Expected #display_method")
}
@@ -9,7 +13,7 @@ function init() {
display_button.addEventListener("click", toggle_display_method_func(display_button), false)
- api_fetch("GET", "floorplans/" + localStorage.getItem("username"))
+ api.fetch("GET", "floorplans/" + localStorage.getItem("username"))
.then(show_floorplans)
}
@@ -20,16 +24,16 @@ function toggle_display_method_func(button) {
}
function set_display_method(button, method) {
- floorplans = document.getElementById("floorplans")
+ let floorplans = document.getElementById("floorplans")
if (!floorplans) {
throw new Error("expected #floorplans")
}
if (method === "list") {
floorplans.removeAttribute("class")
- other = "grid"
+ var other = "grid"
} else if (method === "grid") {
floorplans.setAttribute("class", "grid")
- other = "list"
+ var other = "list"
} else {
throw new Error("Invalid method")
}
@@ -40,29 +44,29 @@ function set_display_method(button, method) {
function edit_floorplan_func(item, floorplan) {
return function() {
- set_error("Edit not implemented", item)
+ etc.error("Edit not implemented", item)
}
}
function delete_floorplan_func(item, floorplan) {
return function() {
- api_fetch("DELETE", "floorplans/" + floorplan.user + "/" + floorplan.name)
+ api.fetch("DELETE", "floorplans/" + floorplan.user + "/" + floorplan.name)
.then(function() {
item.parentElement.remove()
})
.catch(function(err) {
- set_error("Unable to delete floorplan: " + err, item)
+ etc.error("Unable to delete floorplan: " + err, item)
})
}
}
function create_floorplan(floorplan) {
- root = document.createElement("div")
+ let root = document.createElement("div")
root.setAttribute("class", "floorplan")
- aside = document.createElement("aside")
+ let aside = document.createElement("aside")
- button = document.createElement("input")
+ let button = document.createElement("input")
button.addEventListener("click", edit_floorplan_func(root, floorplan), false)
button.type = "image"
button.src = "/icons/create-outline.svg"
@@ -82,19 +86,19 @@ function create_floorplan(floorplan) {
root.append(aside)
- header = document.createElement("header")
- heading = document.createElement("h2")
+ let header = document.createElement("header")
+ let heading = document.createElement("h2")
header.append(heading)
- link = document.createElement("a")
+ let link = document.createElement("a")
heading.append(link)
if (floorplan.synopsis) {
- synopsis = document.createElement("span")
+ let synopsis = document.createElement("span")
synopsis.setAttribute("class", "synopsis")
synopsis.appendChild(document.createTextNode(floorplan.synopsis))
header.append(synopsis)
}
if (floorplan.address) {
- address = document.createElement("address")
+ let address = document.createElement("address")
address.appendChild(document.createTextNode(floorplan.address))
header.append(address)
}
@@ -104,7 +108,7 @@ function create_floorplan(floorplan) {
root.append(header)
if (floorplan.user != localStorage.getItem("username")) {
- footer = document.createElement("footer")
+ let footer = document.createElement("footer")
// TODO: Link to user page, when it exists
footer.append(document.createTextNode("By " + floorplan.user))
root.append(footer)
@@ -114,16 +118,16 @@ function create_floorplan(floorplan) {
}
function show_floorplans(floorplans) {
- list = document.getElementById("floorplans")
+ let list = document.getElementById("floorplans")
if (!list) {
throw new Error("expected #floorplans")
}
- for (i in floorplans) {
- item = document.createElement("li")
+ for (let i in floorplans) {
+ let item = document.createElement("li")
item.append(create_floorplan(floorplans[i]))
list.append(item)
}
}
-window.onload = handle_wrap(init)
+window.onload = etc.handle_wrap(init)
diff --git a/files/lib/api.js b/files/lib/api.js
@@ -1,8 +1,8 @@
-let api_proto = "http"
-let api_host = "api.spaceplanner.app"
-let api_version = "v0"
+const proto = "http"
+const host = "api.spaceplanner.app"
+const version = "v0"
-function api_verify_response(response) {
+function verify_response(response) {
let type = response.headers.get("Content-Type")
if (type != "application/json; charset=utf-8") {
return Promise.reject(new Error("API returned unacceptable format: " + type))
@@ -11,11 +11,11 @@ function api_verify_response(response) {
}
}
-function api_parse_response(response) {
+function parse_response(response) {
return response.json()
}
-function api_status(response) {
+function status(response) {
// response.code is from appleboy's golang JWT LoginHandler
// May figure out how to change in the future
if (response.code >= 200 || response.code < 300) {
@@ -32,55 +32,56 @@ function api_status(response) {
}
function api_fetch(method, endpoint, body) {
- params = { "method": method, "headers": { "Content-Type": "application/json" } };
-
- let token = api_token()
- if (api_authorized_duration(token) > 0) {
- params["headers"]["Authorization"] = "Bearer " + token
+ let params = { "method": method, "headers": { "Content-Type": "application/json" } };
+ let t = token()
+ if (authorized_duration(t) > 0) {
+ params["headers"]["Authorization"] = "Bearer " + t
}
if (body) {
params["body"] = JSON.stringify(body)
}
- return fetch(api_proto + "://" + api_host + "/" + api_version + "/" + endpoint, params)
- .then(api_verify_response)
- .then(api_parse_response)
- .then(api_status)
+ return fetch(proto + "://" + host + "/" + version + "/" + endpoint, params)
+ .then(verify_response)
+ .then(parse_response)
+ .then(status)
}
-function api_refresh_token() {
+export { api_fetch as fetch }
+
+export function refresh_token() {
api_fetch("GET", "tokens/refresh")
.then(function(resp) {
- api_update_token(resp.token)
+ update_token(resp.token)
})
}
-function api_update_token(token) {
- console.log("api_update_token(" + token + ")")
- if (!token) {
+export function update_token(t) {
+ console.log("update_token(" + t + ")")
+ if (!t) {
localStorage.removeItem("token")
localStorage.removeItem("username")
} else {
- localStorage.setItem("token", token)
- localStorage.setItem("username", api_token_payload(token)["id"])
+ localStorage.setItem("token", t)
+ localStorage.setItem("username", token_payload(t)["id"])
}
}
-function api_token() {
+export function token() {
let t = localStorage.getItem("token")
- console.log("api_token() > " + t)
+ console.debug("token() > " + t)
return t
}
-function api_token_payload(token) {
- if (!token) {
- token = api_token()
- if (!token) {
- return token
+export function token_payload(t) {
+ if (!t) {
+ t = token()
+ if (!t) {
+ return t
}
}
- let a = token.split('.')
+ let a = t.split('.')
if (a.length != 3) {
throw new Error("Invalid token")
}
@@ -89,8 +90,8 @@ function api_token_payload(token) {
// Returns seconds until authorization expires, or negative the
// number of seconds it has been expired.
-function api_authorized_duration(token) {
- let payload = api_token_payload(token)
+export function authorized_duration(t) {
+ let payload = token_payload(t)
if (!payload) {
return -1
}
@@ -98,6 +99,6 @@ function api_authorized_duration(token) {
return payload["exp"] - (Date.now() / 1000)
}
-function api_logged_in() {
- return api_authorized_duration() > 0
+export function logged_in() {
+ return authorized_duration() > 0
}
diff --git a/files/lib/bar.js b/files/lib/bar.js
@@ -1,38 +0,0 @@
-function link(name, href) {
- let a = document.createElement("a")
- a.href = href
- a.appendChild(document.createTextNode(name))
- return a
-}
-
-function additem(list, element) {
- let i = document.createElement("li")
- i.appendChild(element)
- list.append(i)
-}
-
-function show_bar(on) {
- if (!on) {
- on = document.querySelector("body")
- }
-
- let nav = document.createElement("nav")
- let left = document.createElement("ul")
- nav.appendChild(left)
- let right = document.createElement("ul")
- nav.appendChild(right)
-
- if (!api_logged_in()) {
- additem(right, link("Login", "/login"))
- } else {
- let jwt_payload = api_token_payload()
- let li = document.createElement("li")
- li.appendChild(document.createTextNode("Welcome "))
- li.appendChild(link(jwt_payload["id"], "/settings"))
- left.appendChild(li)
- additem(right, link("Floorplans", "/floorplans"))
- additem(right, link("Logout", "/logout"))
- }
-
- on.prepend(nav)
-}
diff --git a/files/lib/etc.js b/files/lib/etc.js
@@ -1,5 +1,46 @@
-function authorize() {
- if (api_authorized_duration() <= 0) {
+import * as api from "/lib/api.js"
+
+function link(name, href) {
+ let a = document.createElement("a")
+ a.href = href
+ a.appendChild(document.createTextNode(name))
+ return a
+}
+
+function additem(list, element) {
+ let i = document.createElement("li")
+ i.appendChild(element)
+ list.append(i)
+}
+
+export function bar(on) {
+ if (!on) {
+ on = document.querySelector("body")
+ }
+
+ let nav = document.createElement("nav")
+ let left = document.createElement("ul")
+ nav.appendChild(left)
+ let right = document.createElement("ul")
+ nav.appendChild(right)
+
+ if (!api.logged_in()) {
+ additem(right, link("Login", "/login"))
+ } else {
+ let jwt_payload = api.token_payload()
+ let li = document.createElement("li")
+ li.appendChild(document.createTextNode("Welcome "))
+ li.appendChild(link(jwt_payload["id"], "/settings"))
+ left.appendChild(li)
+ additem(right, link("Floorplans", "/floorplans"))
+ additem(right, link("Logout", "/logout"))
+ }
+
+ on.prepend(nav)
+}
+
+export function authorize() {
+ if (api.authorized_duration() <= 0) {
// Maybe add a parameter which has /login redirect
// back to the page that was trying to be accessed
window.location.href = "/login"
@@ -12,7 +53,7 @@ function delete_element_func(element) {
}
}
-function set_error(message, on) {
+export function error(message, on) {
if (!on) {
on = document.body
}
@@ -40,13 +81,13 @@ function set_error(message, on) {
}
}
-function handle_wrap(func, on) {
+export function handle_wrap(func, on) {
return function() {
try {
func()
}
catch(err) {
- set_error("There was an issue with the page: " + err, on)
+ error("There was an issue with the page: " + err, on)
}
}
}
diff --git a/files/login/index.html b/files/login/index.html
@@ -2,9 +2,7 @@
<head>
<title>Spaceplanner Login</title>
<link rel="stylesheet" type="text/css" href="/css/main.css">
- <script src="/lib/api.js" async></script>
- <script src="/lib/etc.js" async></script>
- <script src="./main.js" async></script>
+ <script type="module" src="./main.js"></script>
</head>
<html>
<h1>Login</h1>
diff --git a/files/login/main.js b/files/login/main.js
@@ -1,19 +1,22 @@
+import * as api from "/lib/api.js"
+import * as etc from "/lib/etc.js"
+
let default_page = "/floorplans"
function handle_token(resp) {
- api_update_token(resp.token)
+ api.update_token(resp.token)
window.location.href = default_page
}
function login(username, password, err_callback) {
- api_fetch("POST", "tokens", { "username": username, "password": password })
+ api.fetch("POST", "tokens", { "username": username, "password": password })
.then(handle_token)
.catch(err_callback)
return false;
}
function init() {
- if (api_authorized_duration() > 0) {
+ if (api.authorized_duration() > 0) {
window.location.href = default_page
}
@@ -30,9 +33,9 @@ function init() {
login_form.onsubmit = function () {
return login(
username_input.value, password_input.value,
- function (error) { return set_error(error, login_form) }
+ function (error) { return etc.error(error, login_form) }
);
};
}
-window.onload = handle_wrap(init)
+window.onload = etc.handle_wrap(init)
diff --git a/files/logout/index.html b/files/logout/index.html
@@ -2,9 +2,7 @@
<head>
<title>Spaceplanner Logout</title>
<link rel="stylesheet" type="text/css" href="/css/main.css">
- <script src="/lib/api.js" async></script>
- <script src="/lib/etc.js" async></script>
- <script src="./main.js" async></script>
+ <script type="module" src="./main.js"></script>
</head>
<html>
<h1>Logout</h1>
diff --git a/files/logout/main.js b/files/logout/main.js
@@ -1,8 +1,11 @@
let default_page = "/"
+import * as api from "/lib/api.js"
+import * as etc from "/lib/etc.js"
+
function init() {
- api_update_token(null)
+ api.update_token(null)
window.location.href = default_page
}
-window.onload = handle_wrap(init)
+window.onload = etc.handle_wrap(init)
diff --git a/files/register/index.html b/files/register/index.html
@@ -2,9 +2,7 @@
<head>
<title>Spaceplanner - Register</title>
<link rel="stylesheet" type="text/css" href="/css/main.css">
- <script src="/lib/api.js" async></script>
- <script src="/lib/etc.js" async></script>
- <script src="./main.js" async></script>
+ <script src="./main.js"></script>
</head>
<html>
<h1>Create New Account</h1>
diff --git a/files/register/main.js b/files/register/main.js
@@ -1,18 +1,21 @@
-default_page = "/floorplans"
+import * as api from "/lib/api.js"
+import * as etc from "/lib/etc.js"
+
+let default_page = "/floorplans"
function handle_creation(resp) {
window.location.href = "/login"
}
function register(username, password, err_callback) {
- api_fetch("POST", "users", { "username": username, "password": password })
+ api.fetch("POST", "users", { "username": username, "password": password })
.then(handle_creation)
.catch(err_callback)
return false;
}
function init() {
- if (api_authorized_duration() > 0) {
+ if (api.authorized_duration() > 0) {
// Maybe don't do this?
window.location.href = default_page
}
@@ -30,9 +33,9 @@ function init() {
form.onsubmit = function () {
return register(
username_input.value, password_input.value,
- function (error) { return set_error(error, form) }
+ function (error) { return etc.error(error, form) }
);
};
}
-window.onload = handle_wrap(init)
+window.onload = etc.handle_wrap(init)
diff --git a/files/settings/index.html b/files/settings/index.html
@@ -2,10 +2,7 @@
<head>
<title>Spaceplanner - Settings</title>
<link rel="stylesheet" type="text/css" href="/css/main.css">
- <script src="/lib/api.js" async></script>
- <script src="/lib/bar.js" async></script>
- <script src="/lib/etc.js" async></script>
- <script src="./main.js" async></script>
+ <script type="module" src="./main.js"></script>
</head>
<html>
<h1>Settings</h1>
diff --git a/files/settings/main.js b/files/settings/main.js
@@ -1,44 +1,47 @@
+import * as api from "/lib/api.js"
+import * as etc from "/lib/etc.js"
+
function init() {
- authorize()
- show_bar()
+ etc.authorize()
+ etc.bar()
main()
}
function main() {
- errfunc = function(err) { set_error("Unable to get settings: " + err, document.querySelector("#settings")) }
- api_fetch("GET", "settings")
+ let errfunc = function(err) { etc.error("Unable to get settings: " + err, document.querySelector("#settings")) }
+ api.fetch("GET", "settings")
.then(function(params) {
- api_fetch("GET", "users/" + localStorage.getItem("username") + "/settings")
+ api.fetch("GET", "users/" + localStorage.getItem("username") + "/settings")
.then(function(current) {
show_settings(current, params)
})
})
.catch(errfunc)
- profile = document.createElement("h2")
+ let profile = document.createElement("h2")
profile.appendChild(document.createTextNode("Profile"))
document.body.append(profile)
- del = delete_form()
+ let del = delete_form()
del.onsubmit = delete_user
document.body.append(del)
}
function delete_form() {
- form = document.createElement("form")
+ let form = document.createElement("form")
form.id = "delete_user_form"
- label = document.createElement("label")
+ let label = document.createElement("label")
label.setAttribute("for", "delete_user_confirm")
label.appendChild(document.createTextNode("Confirm "))
form.append(label)
- check = document.createElement("input")
+ let check = document.createElement("input")
check.id = "delete_user_confirm"
check.type = "checkbox"
check.setAttribute("required", true)
form.append(check)
- submit = document.createElement("input")
+ let submit = document.createElement("input")
submit.type = "submit"
submit.value = "Delete User"
form.append(submit)
@@ -49,31 +52,31 @@ function delete_form() {
}
function delete_user() {
- api_fetch("DELETE", "users/" + localStorage.getItem("username"))
+ api.fetch("DELETE", "users/" + localStorage.getItem("username"))
.then(function() {
- api_update_token(null)
+ api.update_token(null)
document.location.href = "/"
})
- .catch(function(err) { set_error("Unable to delete user: " + err, document.getElementById("#delete_form")) })
+ .catch(function(err) { etc.error("Unable to delete user: " + err, document.getElementById("#delete_form")) })
return false
}
function show_settings(current, params) {
- form = document.createElement("form")
+ let form = document.createElement("form")
form.id = "settings"
- list = document.createElement("ul")
+ let list = document.createElement("ul")
form.append(list)
for (name in params) {
- id = name + "_setting"
- item = document.createElement("li")
+ let id = name + "_setting"
+ let item = document.createElement("li")
- label = document.createElement("label")
+ let label = document.createElement("label")
label.setAttribute("for", id)
label.appendChild(document.createTextNode(name[0].toUpperCase() + name.substring(1) + " "))
item.append(label)
- input = create_input(name, params[name], current[name])
+ let input = create_input(name, params[name], current[name])
input.id = id
item.append(input)
@@ -88,37 +91,37 @@ function show_settings(current, params) {
list.append(item)
}
- submit = document.createElement("input")
+ let submit = document.createElement("input")
submit.value = "Update"
submit.type = "submit"
form.append(submit)
form.onsubmit = function () { return update_settings(current, params) }
- current_form = document.querySelector("#settings")
+ let current_form = document.querySelector("#settings")
current_form.replaceWith(form)
}
function update_settings(current, params) {
- settings = Array.from(document.querySelectorAll("form#settings > ul > li > input"))
- patch = []
- for (name in settings) {
- newvalue = settings[name].value
+ let settings = Array.from(document.querySelectorAll("form#settings > ul > li > input"))
+ let patch = []
+ for (let name in settings) {
+ let newvalue = settings[name].value
if (params.default && newvalue == params.default)
continue
- oldvalue = current[name]
+ let oldvalue = current[name]
if (oldvalue && newvalue == oldvalue)
continue
patch.push({ op: "add", path: settings[name].name, value: newvalue })
}
- api_fetch("PATCH", "users/" + localStorage.getItem("username") + "/settings", patch)
- .catch(function(err) { set_error("Unable to update settings: " + err) })
+ api.fetch("PATCH", "users/" + localStorage.getItem("username") + "/settings", patch)
+ .catch(function(err) { etc.error("Unable to update settings: " + err) })
return false
}
function create_input(name, setting, current_value) {
- input = document.createElement("input")
+ let input = document.createElement("input")
if (setting.type == "string") {
input.type = "text"
} else {
@@ -133,4 +136,4 @@ function create_input(name, setting, current_value) {
return input
}
-window.onload = handle_wrap(init)
+window.onload = etc.handle_wrap(init)