From 2392f79aa9c2d07d86dd2800777831f3151a43cb Mon Sep 17 00:00:00 2001
From: Mechiel Lukkien <mechiel@ueber.net>
Date: Mon, 8 Jan 2024 21:59:15 +0100
Subject: [PATCH] for username/email input field in login form, automatically
 resize so also longer addresses are fully visible

feedback from jsfan3 in issue #58, thanks!
---
 webaccount/account.html |  3 +++
 webaccount/account.js   |  3 ++-
 webaccount/account.ts   | 10 +++++++++-
 webmail/webmail.js      |  4 +++-
 webmail/webmail.ts      | 11 ++++++++++-
 5 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/webaccount/account.html b/webaccount/account.html
index c3dfe5c..0ef9545 100644
--- a/webaccount/account.html
+++ b/webaccount/account.html
@@ -26,6 +26,9 @@ fieldset { border: 0; }
 #page.loading { opacity: 0.1; animation: fadeout 1s ease-out; }
 @keyframes fadein { 0% { opacity: 0 } 100% { opacity: 1 } }
 @keyframes fadeout { 0% { opacity: 1 } 100% { opacity: 0.1 } }
+.autosize { display: inline-grid; max-width: 90vw; }
+.autosize.input { grid-area: 1 / 2; }
+.autosize::after { content: attr(data-value); margin-right: 1em; line-height: 0; visibility: hidden; white-space: pre-wrap; overflow-x: hidden; }
 		</style>
 	</head>
 	<body>
diff --git a/webaccount/account.js b/webaccount/account.js
index 2c36194..d5eeda5 100644
--- a/webaccount/account.js
+++ b/webaccount/account.js
@@ -706,6 +706,7 @@ const login = async (reason) => {
 		const origFocus = document.activeElement;
 		let reasonElem;
 		let fieldset;
+		let autosize;
 		let username;
 		let password;
 		const root = dom.div(style({ position: 'absolute', top: 0, right: 0, bottom: 0, left: 0, backgroundColor: '#eee', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: '1', animation: 'fadein .15s ease-in' }), dom.div(reasonElem = reason ? dom.div(style({ marginBottom: '2ex', textAlign: 'center' }), reason) : dom.div(), dom.div(style({ backgroundColor: 'white', borderRadius: '.25em', padding: '1em', boxShadow: '0 0 20px rgba(0, 0, 0, 0.1)', border: '1px solid #ddd', maxWidth: '95vw', overflowX: 'auto', maxHeight: '95vh', overflowY: 'auto', marginBottom: '20vh' }), dom.form(async function submit(e) {
@@ -736,7 +737,7 @@ const login = async (reason) => {
 			finally {
 				fieldset.disabled = false;
 			}
-		}, fieldset = dom.fieldset(dom.h1('Account'), dom.label(style({ display: 'block', marginBottom: '2ex' }), dom.div('Email address', style({ marginBottom: '.5ex' })), username = dom.input(attr.required(''), attr.placeholder('jane@example.org'))), dom.label(style({ display: 'block', marginBottom: '2ex' }), dom.div('Password', style({ marginBottom: '.5ex' })), password = dom.input(attr.type('password'), attr.required(''))), dom.div(style({ textAlign: 'center' }), dom.submitbutton('Login')))))));
+		}, fieldset = dom.fieldset(dom.h1('Account'), dom.label(style({ display: 'block', marginBottom: '2ex' }), dom.div('Email address', style({ marginBottom: '.5ex' })), autosize = dom.span(dom._class('autosize'), username = dom.input(attr.required(''), attr.placeholder('jane@example.org'), function change() { autosize.dataset.value = username.value; }, function input() { autosize.dataset.value = username.value; }))), dom.label(style({ display: 'block', marginBottom: '2ex' }), dom.div('Password', style({ marginBottom: '.5ex' })), password = dom.input(attr.type('password'), attr.required(''))), dom.div(style({ textAlign: 'center' }), dom.submitbutton('Login')))))));
 		document.body.appendChild(root);
 		username.focus();
 	});
diff --git a/webaccount/account.ts b/webaccount/account.ts
index 3521b11..8790661 100644
--- a/webaccount/account.ts
+++ b/webaccount/account.ts
@@ -9,6 +9,7 @@ const login = async (reason: string) => {
 		const origFocus = document.activeElement
 		let reasonElem: HTMLElement
 		let fieldset: HTMLFieldSetElement
+		let autosize: HTMLElement
 		let username: HTMLInputElement
 		let password: HTMLInputElement
 
@@ -52,7 +53,14 @@ const login = async (reason: string) => {
 							dom.label(
 								style({display: 'block', marginBottom: '2ex'}),
 								dom.div('Email address', style({marginBottom: '.5ex'})),
-								username=dom.input(attr.required(''), attr.placeholder('jane@example.org')),
+								autosize=dom.span(dom._class('autosize'),
+									username=dom.input(
+										attr.required(''),
+										attr.placeholder('jane@example.org'),
+										function change() { autosize.dataset.value = username.value },
+										function input() { autosize.dataset.value = username.value },
+									),
+								),
 							),
 							dom.label(
 								style({display: 'block', marginBottom: '2ex'}),
diff --git a/webmail/webmail.js b/webmail/webmail.js
index 7558b6f..4f3b4a7 100644
--- a/webmail/webmail.js
+++ b/webmail/webmail.js
@@ -1362,6 +1362,7 @@ const login = async (reason) => {
 		const origFocus = document.activeElement;
 		let reasonElem;
 		let fieldset;
+		let autosize;
 		let username;
 		let password;
 		const root = dom.div(style({ position: 'absolute', top: 0, right: 0, bottom: 0, left: 0, backgroundColor: '#eee', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: zindexes.login, animation: 'fadein .15s ease-in' }), dom.div(reasonElem = reason ? dom.div(style({ marginBottom: '2ex', textAlign: 'center' }), reason) : dom.div(), dom.div(style({ backgroundColor: 'white', borderRadius: '.25em', padding: '1em', boxShadow: '0 0 20px rgba(0, 0, 0, 0.1)', border: '1px solid #ddd', maxWidth: '95vw', overflowX: 'auto', maxHeight: '95vh', overflowY: 'auto', marginBottom: '20vh' }), dom.form(async function submit(e) {
@@ -1391,7 +1392,7 @@ const login = async (reason) => {
 			finally {
 				fieldset.disabled = false;
 			}
-		}, fieldset = dom.fieldset(dom.h1('Mail'), dom.label(style({ display: 'block', marginBottom: '2ex' }), dom.div('Email address', style({ marginBottom: '.5ex' })), username = dom.input(attr.required(''), attr.placeholder('jane@example.org'))), dom.label(style({ display: 'block', marginBottom: '2ex' }), dom.div('Password', style({ marginBottom: '.5ex' })), password = dom.input(attr.type('password'), attr.required(''))), dom.div(style({ textAlign: 'center' }), dom.submitbutton('Login')))))));
+		}, fieldset = dom.fieldset(dom.h1('Mail'), dom.label(style({ display: 'block', marginBottom: '2ex' }), dom.div('Email address', style({ marginBottom: '.5ex' })), autosize = dom.span(dom._class('autosize'), username = dom.input(attr.required(''), attr.placeholder('jane@example.org'), function change() { autosize.dataset.value = username.value; }, function input() { autosize.dataset.value = username.value; }))), dom.label(style({ display: 'block', marginBottom: '2ex' }), dom.div('Password', style({ marginBottom: '.5ex' })), password = dom.input(attr.type('password'), attr.required(''))), dom.div(style({ textAlign: 'center' }), dom.submitbutton('Login')))))));
 		document.body.appendChild(root);
 		username.focus();
 	});
@@ -2393,6 +2394,7 @@ const compose = (opts) => {
 			// data-value is used for size of ::after css pseudo-element to stretch input field.
 			autosizeElem.dataset.value = inputElem.value;
 		}, function change() {
+			autosizeElem.dataset.value = inputElem.value;
 			fetchRecipientSecurity();
 		}), securityBar = dom.span(dom._class('securitybar'), style({
 			margin: '0 1px',
diff --git a/webmail/webmail.ts b/webmail/webmail.ts
index 3147b5a..717f6de 100644
--- a/webmail/webmail.ts
+++ b/webmail/webmail.ts
@@ -236,6 +236,7 @@ const login = async (reason: string) => {
 		const origFocus = document.activeElement
 		let reasonElem: HTMLElement
 		let fieldset: HTMLFieldSetElement
+		let autosize: HTMLElement
 		let username: HTMLInputElement
 		let password: HTMLInputElement
 		const root = dom.div(
@@ -277,7 +278,14 @@ const login = async (reason: string) => {
 							dom.label(
 								style({display: 'block', marginBottom: '2ex'}),
 								dom.div('Email address', style({marginBottom: '.5ex'})),
-								username=dom.input(attr.required(''), attr.placeholder('jane@example.org')),
+								autosize=dom.span(dom._class('autosize'),
+									username=dom.input(
+										attr.required(''),
+										attr.placeholder('jane@example.org'),
+										function change() { autosize.dataset.value = username.value },
+										function input() { autosize.dataset.value = username.value },
+									),
+								),
 							),
 							dom.label(
 								style({display: 'block', marginBottom: '2ex'}),
@@ -1476,6 +1484,7 @@ const compose = (opts: ComposeOptions) => {
 						autosizeElem.dataset.value = inputElem.value
 					},
 					function change() {
+						autosizeElem.dataset.value = inputElem.value
 						fetchRecipientSecurity()
 					},
 				),