1/* SKNAU Unit Head portal â form behaviour shared by login / forgot / reset pages. 2 Works on its own; unit-auth-motion.js only adds animation on top. */ 3(function () { 4 // Show / hide password (any .toggle-pw with aria-controls="<input id>") 5 document.querySelectorAll('.toggle-pw[aria-controls]').forEach(function (btn) { 6 var input = document.getElementById(btn.getAttribute('aria-controls')); 7 if (!input) return; 8 btn.addEventListener('click', function () { 9 var show = input.type === 'password'; 10 input.type = show ? 'text' : 'password'; 11 btn.setAttribute('aria-pressed', String(show)); 12 btn.setAttribute('aria-label', show ? 'Hide password' : 'Show password'); 13 btn.querySelector('i').className = show ? 'fas fa-eye-slash' : 'fas fa-eye'; 14 input.focus(); 15 }); 16 }); 17 18 // Caps Lock warning: <input data-caps="hintId"> 19 document.querySelectorAll('input[data-caps]').forEach(function (input) { 20 var hint = document.getElementById(input.dataset.caps); 21 if (!hint) return; 22 function check(e) { 23 var on = e.getModifierState && e.getModifierState('CapsLock'); 24 hint.classList.toggle('show', !!on); 25 hint.querySelector('span').textContent = on ? 'Caps Lock is on' : ''; 26 } 27 input.addEventListener('keydown', check); 28 input.addEventListener('keyup', check); 29 input.addEventListener('blur', function () { hint.classList.remove('show'); }); 30 }); 31 32 // Forms with data-auth: friendly checks, then a loading state on the submit button 33 document.querySelectorAll('form[data-auth]').forEach(function (form) { 34 var btn = form.querySelector('button[type=submit]'); 35 var label = btn && btn.querySelector('.label'); 36 var idle = label ? label.textContent : ''; 37 38 form.querySelectorAll('.input').forEach(function (el) { 39 el.addEventListener('input', function () { 40 form.querySelectorAll('.input[aria-invalid]').forEach(function (x) { x.removeAttribute('aria-invalid'); }); 41 }); 42 }); 43 44 form.addEventListener('submit', function (e) { 45 var bad = null; 46 form.querySelectorAll('.input[required]').forEach(function (el) { 47 if (!bad && (!el.value.trim() || !el.checkValidity())) bad = el; 48 }); 49 // Page-specific checks (e.g. password rules on the reset page) return the field to fix, or null 50 if (!bad && typeof window.authExtraCheck === 'function') bad = window.authExtraCheck(form); 51 if (bad) { 52 e.preventDefault(); 53 bad.setAttribute('aria-invalid', 'true'); 54 bad.focus(); 55 if (window.__shake) window.__shake(bad.closest('.control') || bad); 56 return; 57 } 58 if (btn) { 59 btn.disabled = true; 60 btn.classList.add('loading'); 61 if (label) label.textContent = btn.dataset.busy || 'Please waitâ¦'; 62 } 63 }); 64 65 // Coming back with the browser's Back button must not leave the button stuck 66 window.addEventListener('pageshow', function () { 67 if (!btn) return; 68 btn.disabled = false; btn.classList.remove('loading'); 69 if (label) label.textContent = idle; 70 }); 71 }); 72})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.