diff --git a/package.json b/package.json index a969d0a..9352210 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "main": "src/index.mjs", "scripts": { "test": "echo \"No tests have been implemented yet\"", - "build": "node src/static/esbuild.mjs" + "build": "node src/static/esbuild.mjs", + "watch": "ESBUILD_WATCH=yes node src/static/esbuild.mjs" }, "repository": { "type": "git", diff --git a/src/static/app.css b/src/static/app.css index 9a994fc..37c5bec 100644 --- a/src/static/app.css +++ b/src/static/app.css @@ -89,14 +89,18 @@ nav { padding: 0.5em 0.75em; } .nav-items a { - display: block; + display: flex; + align-items: center; + gap: 0 0.5em; + color: inherit; text-decoration: none; } -.nav-items .fa { - margin: 0.1em 0.25em 0.1em 0.1em; +.nav-items span:last-child { flex: 1; } +.nav-items .fa:not(.fa-stack):not(.fa-stack-1x):not(.fa-stack-2x):not(.fa-stack-3x) { font-size: 200%; - vertical-align: middle; + width: 1em; + height: 1em; } diff --git a/src/static/app.mjs b/src/static/app.mjs index e2628ce..b6d3f7e 100644 --- a/src/static/app.mjs +++ b/src/static/app.mjs @@ -7,7 +7,6 @@ import GlobalUI from './js/ui/GlobalUI.mjs'; import TableView from './js/ui/TableView.mjs'; window.addEventListener("load", async (_event) => { - const el_version = document.querySelector(".version"); const el_table = document.querySelector("main"); globalThis.sysquery = new SystemQueryClient(); @@ -17,7 +16,7 @@ window.addEventListener("load", async (_event) => { tableview: new TableView(el_table), } - await ui.init(); + await globalThis.sysui.ui.init(); globalThis.sysquery_router.navigate_current_hash(); diff --git a/src/static/esbuild.mjs b/src/static/esbuild.mjs index 95be10f..12a87a2 100755 --- a/src/static/esbuild.mjs +++ b/src/static/esbuild.mjs @@ -7,8 +7,12 @@ import crypto from 'crypto'; import esbuild from 'esbuild'; +import log from '../lib/io/NamespacedLog.mjs'; const l = log("esbuild"); + const __dirname = import.meta.url.slice(7, import.meta.url.lastIndexOf("/")); +const outdir = path.resolve(__dirname, "../static-dist"); + /** * Hashes the contents of a file. * @ref https://stackoverflow.com/a/44643479/1460422 @@ -29,33 +33,7 @@ function hash_file(hashName, path) { }); } -(async () => { - "use strict"; - - const outdir = path.resolve(__dirname, "../static-dist"); - - const result = await esbuild.build({ - entryPoints: [ - "./app.mjs", - "./app.css" - ].map(filepath => path.resolve(__dirname, filepath)), - outdir, - bundle: true, - minify: true, - sourcemap: true, - treeShaking: true, - loader: { - ".html": "text", - ".svg": "file", - ".woff2": "file", - ".woff": "file", - ".eot": "file", - ".ttf": "file", - } - }); - if(result.errors.length > 0 || result.warnings.length > 0) - console.log(result); - +async function do_html() { // We *would* use SHA3 here, but we need to use SHA2 for subresource integrity let algorithm = "sha256"; let css_hash = await hash_file(algorithm, path.join(outdir, "app.css")); @@ -70,6 +48,49 @@ function hash_file(hashName, path) { // TODO: Use fs.promises.copyFile() for index.html here, and also maybe find & replace for css/js filenames that we can then randomise? await fs.promises.writeFile(path.join(outdir, "index.html"), html); +} + + +(async () => { + "use strict"; + const result = await esbuild.build({ + entryPoints: [ + "./app.mjs", + "./app.css" + ].map(filepath => path.resolve(__dirname, filepath)), + outdir, + bundle: true, + minify: true, + sourcemap: true, + treeShaking: true, + watch: typeof process.env.ESBUILD_WATCH === "undefined" ? false : { + async onRebuild(error, _result) { + if(error) { + l.error(error); + return; + } + + if(result.errors.length > 0 || result.warnings.length > 0) + console.log(result); + + await do_html(); + + l.log(`Build successful`); + } + }, + loader: { + ".html": "text", + ".svg": "file", + ".woff2": "file", + ".woff": "file", + ".eot": "file", + ".ttf": "file", + } + }); + if(result.errors.length > 0 || result.warnings.length > 0) + console.log(result); + + await do_html(); // console.log(await esbuild.analyzeMetafile(result.metafile)); })(); diff --git a/src/static/index.html b/src/static/index.html index c1d3510..d733f5c 100644 --- a/src/static/index.html +++ b/src/static/index.html @@ -16,7 +16,7 @@
  • - Settings + settings
  • diff --git a/src/static/js/tabledefs/cpu_live.mjs b/src/static/js/tabledefs/cpu_live.mjs index a99cc1b..336fbc4 100644 --- a/src/static/js/tabledefs/cpu_live.mjs +++ b/src/static/js/tabledefs/cpu_live.mjs @@ -4,7 +4,7 @@ import human_filesize from '../misc/human_filesize.mjs'; export default { name: "CPU", - icon: microchip, + icon: "microchip", items: [ { name: "Frequency (GHz)", diff --git a/src/static/js/ui/GlobalUI.mjs b/src/static/js/ui/GlobalUI.mjs index 2ea10f7..c44a00e 100644 --- a/src/static/js/ui/GlobalUI.mjs +++ b/src/static/js/ui/GlobalUI.mjs @@ -14,6 +14,8 @@ class GlobalUI { async init() { const status = await globalThis.sysquery.status(); + const el_version = document.querySelector(".version"); + // 1: Update version display el_version.replaceChildren( document.createTextNode(status.version) @@ -31,7 +33,14 @@ class GlobalUI { // Generate new dynamic navigation items const result = document.createDocumentFragment(); for(const table_name of status.tables) { - result.append(...this.emel(`li>a[href=#table/?]>${forkawesome_emel(tabledefs[table_name].icon)}+{?}`, { + console.log(`[nav] new dynamic item ${table_name}, def`, tabledefs[table_name]); + const icondef = typeof tabledefs[table_name] === "undefined" + ? "question-circle" + : tabledefs[table_name].icon; + + const emel_icon = forkawesome_emel(icondef); + console.log(`emel_icon`, emel_icon); + result.append(this.emel(`li>a[href=#table/?]>${emel_icon}+span{?}`, { placeholders: [ table_name, table_name ] })); } diff --git a/src/static/js/ui/forkawesome_emel.mjs b/src/static/js/ui/forkawesome_emel.mjs index 2535e38..afa7fde 100644 --- a/src/static/js/ui/forkawesome_emel.mjs +++ b/src/static/js/ui/forkawesome_emel.mjs @@ -1,10 +1,10 @@ "use strict"; -export default function(def) { +export default function(def, fixed_width=true) { if(typeof def === "string") - return `span.fa.fa-${def}`; + return `span[class="fa fa-${def}${fixed_width?` fa-fw`:``}"]`; if(def instanceof Array) - return def.map(el, i => `span.fa.fa-${el}.fa-stack-${def.length-i}x`).join(`+`); + return `(span[class="fa-stack${fixed_width?` fa-fw`:``}"]>${def.map((el, i) => `span[class="fa fa-${el} fa-stack-${def.length-i}x${fixed_width?` fa-fw`:``}"]`).join(`+`)})`; throw new Error(`Error: Expected def of type string or Array, but got variable of type ${typeof def}`); }