chiark / gitweb /
chpwd: Remove redundant user-name check in the SSH-service path.
[chopwood] / chpwd.js
CommitLineData
a2916c06
MW
1/* -*-js-*-
2 *
3 * Common JavaScript code for Chopwood
4 *
5 * (c) 2013 Mark Wooding
6 */
7
8/*----- Licensing notice --------------------------------------------------*
9 *
10 * This file is part of Chopwood: a password-changing service.
11 *
12 * Chopwood is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU Affero General Public License as
14 * published by the Free Software Foundation; either version 3 of the
15 * License, or (at your option) any later version.
16 *
17 * Chopwood is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Affero General Public License for more details.
21 *
22 * You should have received a copy of the GNU Affero General Public
23 * License along with Chopwood; if not, see
24 * <http://www.gnu.org/licenses/>.
25 */
26
27/*----- Some utilities ----------------------------------------------------*/
28
29function elt(id) {
30 /* Return the element with the requested ID. */
31 return document.getElementById(id);
32}
33
34function map(func, list) {
35 /* Apply FUNC to each element of LIST, which may actually be any object;
36 * return a new object mapping the same keys to the images of the values in
37 * the function FUNC.
38 */
39 var i;
40 var out = {};
41 for (i in list) out[i] = func(list[i]);
42 return out;
43}
44
45/*----- Form validation ---------------------------------------------------*/
46
47var FORMS = {};
48/* A map of form names to information about them. Each form is an object
49 * with the following slots:
50 *
51 * * elts: A list of element-ids for the form widgets. These widgets will
52 * be checked periodically to see whether the input data is acceptable.
53 *
54 * * check: A function of no arguments, which returns either `null' if
55 * everything is OK, or an error message as a string.
56 *
57 * Form names aren't just for show. Some element-ids are constructed using
58 * the form name as a base:
59 *
60 * * FORM-whinge: An output element in which to display an error message if
61 * the form's input is unacceptable.
62 *
63 * * FORM-submit: The Submit button, which needs hooking to inhibit
64 * submitting a form with invalid data.
65 */
66
67function check() {
68 /* Check through the various forms to make sure they're filled in OK. If
69 * not, set the `F-whinge' elements, and disable `F-submit'.
70 */
71 var f, form, whinge;
72
73 for (f in FORMS) {
74 form = FORMS[f];
75 we = elt(f + '-whinge');
76 sb = elt(f + '-submit');
77 whinge = form.check();
78 if (sb !== null) sb.disabled = (whinge !== null);
79 if (we !== null) {
80 we.textContent = whinge || 'OK';
81 we.className = whinge === null ? 'whinge' : 'whinge wrong';
82 }
83 }
84
85 // We can't catch all possible change events: in particular, it seems
86 // really hard to capture changes as a result of selections from a menu --
87 // e.g., delete or paste. Accept this, and just recheck periodically.
88 check_again(1000);
89}
90
91var timer = null;
92/* The timer for the periodic validation job. */
93
94function check_again(when) {
95 /* Arrange to check the forms again in WHEN milliseconds. */
96 if (timer !== null) clearTimeout(timer);
97 timer = setTimeout(check, when);
98}
99
100var Q = 0;
101function check_soon(ev) {
102 /* Arrange to check the forms again very soon. */
103 check_again(50);
104}
105
106function check_presubmit(ev, f) {
107 /* Check the form F now, popping up an alert and preventing the event EV if
108 * there's something wrong.
109 */
110 var whinge = FORMS[f].check();
111
112 if (whinge !== null) {
113 ev.preventDefault();
114 alert(whinge);
115 }
116}
117
118function init() {
119 /* Attach event handlers to the various widgets so that we can keep track
120 * of how well things are being filled in.
121 */
122 var f, form, w, e;
123
124 // Start watching for changes.
125 check_soon();
126
127 for (f in FORMS) (function (f, form) {
128
129 // Ugh. We have to lambda-bind `f' here so that we can close over it
130 // properly.
131 for (w in form.elts) {
132 if ((e = elt(f + '-' + form.elts[w])) === null) continue;
eaac44f3
MW
133 e.addEventListener('click', check_soon, false);
134 e.addEventListener('change', check_soon, false);
135 e.addEventListener('keypress', check_soon, false);
136 e.addEventListener('blur', check_soon, false);
a2916c06
MW
137 }
138 if ((e = elt(f + '-submit')) !== null) {
139 e.addEventListener('click', function (ev) {
140 return check_presubmit(ev, f)
eaac44f3 141 }, false);
a2916c06
MW
142 }
143 })(f, FORMS[f]);
144}
145
eaac44f3 146window.addEventListener('load', init, false);
a2916c06
MW
147
148/*----- That's all, folks -------------------------------------------------*/