From a5b2f39c5d1eef23586ccfb43cbe51616d455ec3 Mon Sep 17 00:00:00 2001 From: David Carley Date: Fri, 2 Sep 2022 01:08:11 +0000 Subject: [PATCH] Removed jQuery --- .eslintrc.yml | 3 +- src/js/admin-general-view.js | 25 +++++++-------- src/js/api.js | 23 +++++++++---- src/js/app.js | 41 +++++++++--------------- src/js/control-view.js | 6 ++-- src/js/gcode-viewer.js | 48 ++++++++++++---------------- src/js/main.js | 4 +-- src/js/modbus.js | 26 +++++++-------- src/js/path-viewer.js | 14 ++++---- src/pug/index.pug | 1 - src/svelte-components/src/lib/api.ts | 8 ++--- 11 files changed, 95 insertions(+), 104 deletions(-) diff --git a/.eslintrc.yml b/.eslintrc.yml index 09a55b7..a57215b 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -16,7 +16,6 @@ globals: Vue: readonly THREE: readonly SvelteComponents: readonly - $: readonly Clusterize: readonly SockJS: readonly rules: @@ -80,3 +79,5 @@ rules: - error template-curly-spacing: - error + require-await: + - error diff --git a/src/js/admin-general-view.js b/src/js/admin-general-view.js index e707721..b639260 100644 --- a/src/js/admin-general-view.js +++ b/src/js/admin-general-view.js @@ -1,6 +1,7 @@ "use strict"; const api = require("./api"); +const utils = require("./utils"); const merge = require("lodash.merge"); const config_defaults = require("../resources/onefinity_defaults.json"); @@ -34,10 +35,7 @@ module.exports = { }, restore_config: function () { - // If we don't reset the form the browser may cache file if name is same - // even if contents have changed - $(".restore-config")[0].reset(); - $(".restore-config input").click(); + utils.clickFileInput("restore-config"); }, restore: function (e) { @@ -51,8 +49,9 @@ module.exports = { let config; try { config = JSON.parse(target.result); - } catch (ex) { - api.alert("Invalid config file"); + } catch (error) { + console.error("Invalid config file:", error); + alert("Invalid config file"); return; } @@ -64,7 +63,8 @@ module.exports = { message: "Configuration restored" }); } catch (error) { - api.alert("Restore failed", error); + console.error("Restore failed:", error); + alert("Restore failed"); } }; @@ -86,9 +86,9 @@ module.exports = { title: "Success", message: "Configuration restored" }); - } catch (err) { - api.alert("Restore failed"); - console.error("Restore failed", err); + } catch (error) { + console.error("Restore failed:", error); + alert("Restore failed"); } }, @@ -101,10 +101,7 @@ module.exports = { }, upload_firmware: function () { - // If we don't reset the form the browser may cache file if name is same - // even if contents have changed - $(".upload-firmware")[0].reset(); - $(".upload-firmware input").click(); + utils.clickFileInput("upload-firmware"); }, upload: function (e) { diff --git a/src/js/api.js b/src/js/api.js index 507f9de..f5b7490 100644 --- a/src/js/api.js +++ b/src/js/api.js @@ -1,17 +1,28 @@ "use strict"; -async function callApi(method, url, body) { +async function callApi(method, url, data) { try { + const headers = {}; + let body = undefined; + + if (data) { + if (data instanceof FormData) { + body = data; + } else { + headers["Content-Type"] = "application/json; charset=utf-8"; + body = JSON.stringify(data); + } + } + const response = await fetch(`/api/${url}`, { method, - headers: { - "Content-Type": "application/json" - }, - body + headers, + body, + cache: "no-cache", }); if (response.ok) { - return response.json(); + return await response.json(); } throw new Error(await response.text()); diff --git a/src/js/app.js b/src/js/app.js index 2913150..65eb143 100644 --- a/src/js/app.js +++ b/src/js/app.js @@ -225,7 +225,7 @@ module.exports = new Vue({ }, ready: function () { - $(window).on("hashchange", this.parse_hash); + window.onhashchange = () => this.parse_hash(); this.connect(); SvelteComponents.registerControllerMethods({ @@ -268,37 +268,25 @@ module.exports = new Vue({ try { await api.put("upgrade"); this.firmwareUpgrading = true; - } catch (err) { - api.alert("Error during upgrade."); - console.error("Error during upgrade", err); + } catch (error) { + console.error("Error during upgrade:", error); + alert("Error during upgrade"); } }, - upload_confirmed: function () { + upload_confirmed: async function () { this.confirmUpload = false; const form = new FormData(); form.append("firmware", this.firmware); - $.ajax({ - url: "/api/firmware/update", - type: "PUT", - data: form, - cache: false, - contentType: false, - processData: false, - }) - .success( - function () { - this.firmwareUpgrading = true; - }.bind(this) - ) - .error( - function (err) { - api.alert("Firmware update failed"); - console.error("Firmware update failed", err); - }.bind(this) - ); + try { + await api.put("firmware/update", form); + this.firmwareUpgrading = true; + } catch (error) { + console.error("Firmware update failed:", error); + alert("Firmware update failed"); + } }, show_upgrade: function () { @@ -418,7 +406,8 @@ module.exports = new Vue({ await api.put("config/save", this.config); this.modified = false; } catch (error) { - api.alert("Save failed", error); + console.error("Save failed:", error); + alert("Save failed"); } }, @@ -434,7 +423,7 @@ module.exports = new Vue({ // Acknowledge messages if (this.state.messages.length) { const id = this.state.messages.slice(-1)[0].id; - api.put("message/" + id + "/ack"); + api.put(`message/${id}/ack`); } }, }, diff --git a/src/js/control-view.js b/src/js/control-view.js index ebd76eb..fbd3a8e 100644 --- a/src/js/control-view.js +++ b/src/js/control-view.js @@ -1,6 +1,7 @@ "use strict"; const api = require("./api"); +const utils = require("./utils"); const cookie = require("./cookie")("bbctrl-"); module.exports = { @@ -338,10 +339,7 @@ module.exports = { }, open: function () { - // If we don't reset the form the browser may cache file if name is same - // even if contents have changed - $(".gcode-file-input")[0].reset(); - $(".gcode-file-input input").click(); + utils.clickFileInput("gcode-file-input"); }, upload: async function (e) { diff --git a/src/js/gcode-viewer.js b/src/js/gcode-viewer.js index f26d1d3..dd50e57 100644 --- a/src/js/gcode-viewer.js +++ b/src/js/gcode-viewer.js @@ -17,8 +17,7 @@ module.exports = { return { empty: true, file: "", - line: -1, - scrolling: false + line: -1 }; }, @@ -40,8 +39,8 @@ module.exports = { ready: function () { this.clusterize = new Clusterize({ rows: [], - scrollElem: $(this.$el).find(".clusterize-scroll")[0], - contentElem: $(this.$el).find(".clusterize-content")[0], + scrollElem: this.$el.querySelector(".clusterize-scroll"), + contentElem: this.$el.querySelector(".clusterize-content"), no_data_text: "GCode view...", callbacks: {clusterChanged: this.highlight} }); @@ -66,7 +65,7 @@ module.exports = { return; } - const response = await fetch(`/api/file/${file}?${Math.random()}`); + const response = await fetch(`/api/file/${file}`, { cache: "no-cache" }); const text = await response.text(); if (text.length > 20e6) { @@ -101,14 +100,21 @@ module.exports = { }, highlight: function () { - let e = $(this.$el).find(".highlight"); - if (e.length) { - e.removeClass("highlight"); + const highlights = this.$el.querySelectorAll(".highlight"); + for (const highlight of highlights) { + highlight.className = (highlight.className || "") + .split(" ") + .filter(c => c !== "highlight") + .join(" "); } - e = $(this.$el).find(`.ln${this.line}`); - if (e.length) { - e.addClass("highlight"); + const lines = this.$el.querySelectorAll(`.ln${this.line}`); + for (const line of lines) { + line.className = (line.className || "") + .split(" ") + .filter(c => c !== "highlight") + .concat(["highlight"]) + .join(" "); } }, @@ -133,26 +139,14 @@ module.exports = { line = totalLines; } - const e = $(this.$el).find(".clusterize-scroll"); + const scroll = this.$el.querySelector(".clusterize-scroll"); - const lineHeight = e[0].scrollHeight / totalLines; - const linesPerPage = Math.floor(e[0].clientHeight / lineHeight); - const current = e[0].scrollTop / lineHeight; + const lineHeight = scroll.scrollHeight / totalLines; + const linesPerPage = Math.floor(scroll.clientHeight / lineHeight); const target = line - 1 - Math.floor(linesPerPage / 2); // Update scroll position - if (!this.scrolling) { - if (target < current - 20 || current + 20 < target) { - e[0].scrollTop = target * lineHeight; - } else { - this.scrolling = true; - e.animate({scrollTop: target * lineHeight}, { - complete: function () { - this.scrolling = false; - }.bind(this) - }); - } - } + scroll.scrollTop = target * lineHeight; Vue.nextTick(this.highlight); } diff --git a/src/js/main.js b/src/js/main.js index fa76c38..15bf67c 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -39,7 +39,7 @@ function uuid(length) { return s; } -$(function () { +window.onload = function () { if (typeof cookie_get("client-id") == "undefined") { cookie_set("client-id", uuid(), 10000); } @@ -145,4 +145,4 @@ $(function () { // Vue app require("./app"); -}); +}; diff --git a/src/js/modbus.js b/src/js/modbus.js index cc09260..f5d45d8 100644 --- a/src/js/modbus.js +++ b/src/js/modbus.js @@ -1,7 +1,7 @@ "use strict"; // Must match modbus.c -const exports = { +const constants = { DISCONNECTED: 0, OK: 1, CRC: 2, @@ -9,15 +9,15 @@ const exports = { TIMEDOUT: 4 }; -exports.status_to_string = - function (status) { - switch (status) { - case exports.OK: return "Ok"; - case exports.CRC: return "CRC error"; - case exports.INVALID: return "Invalid response"; - case exports.TIMEDOUT: return "Timedout"; - default: return "Disconnected"; - } - }; - -module.exports = exports; +module.exports = { + ...constants, + status_to_string: function (status) { + switch (status) { + case constants.OK: return "Ok"; + case constants.CRC: return "CRC error"; + case constants.INVALID: return "Invalid response"; + case constants.TIMEDOUT: return "Timedout"; + default: return "Disconnected"; + } + } +}; diff --git a/src/js/path-viewer.js b/src/js/path-viewer.js index fba2396..4fdeaba 100644 --- a/src/js/path-viewer.js +++ b/src/js/path-viewer.js @@ -26,7 +26,7 @@ module.exports = { computed: { target: function () { - return $(this.$el).find(".path-viewer-content")[0]; + return this.$el.querySelector(".path-viewer-content"); }, webglAvailable: function() { @@ -122,7 +122,7 @@ module.exports = { } async function get(url) { - const response = await fetch(`${url}?${Math.random()}`); + const response = await fetch(`${url}`, { cache: "no-cache" }); const arrayBuffer = await response.arrayBuffer(); return new Float32Array(arrayBuffer); @@ -187,10 +187,12 @@ module.exports = { }, get_dims: function () { - const t = $(this.target); - const width = t.innerWidth(); - const height = t.innerHeight(); - return {width: width, height: height}; + const computedStyle = window.getComputedStyle(this.target); + + return { + width: parseInt(computedStyle.width), + height: parseInt(computedStyle.height) + }; }, update_view: function () { diff --git a/src/pug/index.pug b/src/pug/index.pug index 89eb5a2..4da168d 100644 --- a/src/pug/index.pug +++ b/src/pug/index.pug @@ -173,7 +173,6 @@ html(lang="en") #templates: include ../../build/templates.pug iframe#download-target(style="display:none") - script: include ../static/js/jquery-1.11.3.min.js script: include ../static/js/vue.js script: include ../static/js/sockjs.min.js script: include ../static/js/clusterize.min.js diff --git a/src/svelte-components/src/lib/api.ts b/src/svelte-components/src/lib/api.ts index 56f1d58..42cc851 100644 --- a/src/svelte-components/src/lib/api.ts +++ b/src/svelte-components/src/lib/api.ts @@ -24,18 +24,18 @@ async function doFetch(method: HttpMethod, url: string, data: any, config: Reque } } -export async function GET(url: string, config: RequestInit = {}) { +export function GET(url: string, config: RequestInit = {}) { return doFetch("GET", url, undefined, config); } -export async function PUT(url: string, data: any = undefined, config: RequestInit = {}) { +export function PUT(url: string, data: any = undefined, config: RequestInit = {}) { return doFetch("PUT", url, data, config); } -export async function POST(url: string, data: any = undefined, config: RequestInit = {}) { +export function POST(url: string, data: any = undefined, config: RequestInit = {}) { return doFetch("POST", url, data, config); } -export async function DELETE(url: string, config = {}) { +export function DELETE(url: string, config = {}) { return doFetch("DELETE", url, undefined, config); }