From 87110fe7944e0d5d56b7d4d4fd08006c5dbc9d5f Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Sat, 15 Feb 2025 11:18:16 +0300 Subject: [PATCH 1/4] Move demo site generation into separate file --- Makefile | 6 +----- generate-website.sh | 10 ++++++++++ 2 files changed, 11 insertions(+), 5 deletions(-) create mode 100755 generate-website.sh diff --git a/Makefile b/Makefile index a1aeac0..42a4165 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,6 @@ all: totp.html totp.xpi totp.html: form.html README.md totp.js form.js form-tweaks.js - set -e; exec >$@; \ - grep -v '^\n'; \ - sed 's/totp\.js/#source/' README.md; \ - printf '\n%s\n\n' '' "$$(cat form.js form-tweaks.js)" \ - ' id=source style="display: block; white-space: pre; font-family: monospace; overflow: auto"' "$$(cat totp.js)" + ./generate-website.sh > totp.html xpi_sources = manifest.json form.html form.js totp.js totp.png totp.xpi: $(xpi_sources) rm -f $@ diff --git a/generate-website.sh b/generate-website.sh new file mode 100755 index 0000000..b63aa57 --- /dev/null +++ b/generate-website.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# Generates totp.html for https://turistu.github.io/totp.html + +set -e + +grep -v '^\n' +sed 's/totp\.js/#source/' README.md +printf '\n%s\n\n' '' "$(cat form.js form-tweaks.js)" \ + ' id=source style="display: block; white-space: pre; font-family: monospace; overflow: auto"' "$(cat totp.js)" From f79577d4b21791c2e6d9d7f1d4234e55856a5b70 Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Sat, 15 Feb 2025 12:01:31 +0300 Subject: [PATCH 2/4] Close html tags to move \n' '' "$(cat form.js form-tweaks.js)" \ - ' id=source style="display: block; white-space: pre; font-family: monospace; overflow: auto"' "$(cat totp.js)" +# insert form.js form-tweaks.js as scripts, and totp.js as listing +printf '\n' "$(cat form.js form-tweaks.js)" +printf '\n' \ + 'id=source style="display: block; white-space: pre; font-family: monospace; overflow: auto"' "$(cat totp.js)" From a12f21d5125998f9d2ef17f00a65707065ed2cb6 Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Sat, 15 Feb 2025 12:26:56 +0300 Subject: [PATCH 3/4] Explain what FORM.className set does --- form.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/form.js b/form.js index d066088..453bdec 100644 --- a/form.js +++ b/form.js @@ -30,4 +30,6 @@ SHOW.checked = false; SHOW.onchange = e => KEY.type = SHOW.checked ? 'text': 'password'; CODE.onclick = e => copy('copy failed'); FORM.onsubmit = e => e.preventDefault(); +// add class="popup" when html code is called from panel button +// view-source:moz-extension://xxxxxxxx/form.html#popup FORM.className = document.location.hash.substr(1); From b7ff90127dc10cb10556c84041bf9579b797445a Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Sat, 15 Feb 2025 14:48:52 +0300 Subject: [PATCH 4/4] Move generate() function into a class This allows to add multiple forms --- form.js | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/form.js b/form.js index 453bdec..7470a0a 100644 --- a/form.js +++ b/form.js @@ -1,7 +1,25 @@ -async function generate(){ - try { CODE.value = await totp(KEY.value); copy('click to copy', true) } - catch(e){ KEY.setCustomValidity(ERROR.value = e) } +class TOTPForm { + constructor(GENERATE, CODE, KEY, ERROR) { + this.code = CODE + this.key = KEY + this.error = ERROR + + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this#bound_methods_in_classes + this.generate = this.generate.bind(this) + + GENERATE.onclick = this.generate + } + + async generate() { + try { + this.code.value = await totp(this.key.value); + copy('click to copy', true) + } catch(e) { + this.key.setCustomValidity(this.error.value = e) + } + } } + function touchscreen(){ return matchMedia('(pointer:coarse)').matches } @@ -19,12 +37,13 @@ async function copy(emsg, select){ } }catch(e){ CODE.title = emsg } } -GENERATE.onclick = generate; + +const totpWrapper = new TOTPForm(GENERATE, CODE, KEY, ERROR); KEY.oninput = function(){ KEY.setCustomValidity(''); ERROR.value = KEY.checkValidity() ? '' : Error('only A..Z, 2..7 and spaces allowed'); - if(KEY !== document.activeElement) generate(); + if(KEY !== document.activeElement) totpWrapper.generate(); } SHOW.checked = false; SHOW.onchange = e => KEY.type = SHOW.checked ? 'text': 'password';