* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-var DEP_UI = {}; (function () { with (DEP_UI) {
+var DEP_UI = {}; (function () {
/*----- Utility functions and classes -------------------------------------*/
-DEP_UI.debug = function(msg) {
+function debug(msg) {
/* Write the string MSG to the `trace' element, if there is one. */
var e = elt('trace');
if (e !== null) e.textContent += msg;
}
+DEP_UI.debug = debug;
- DEP_UI.trap = function(what, func) {
+function trap(what, func) {
try {
func();
} catch (e) {
throw e;
}
}
+DEP_UI.trap = trap;
-DEP_UI.elt = function (id) {
+function elt(id) {
/* Find and return the element with the given ID. */
return document.getElementById(id);
}
+DEP_UI.elt = elt;
-DEP_UI.add_elt_class = function (elt, cls) {
+function add_elt_class(elt, cls) {
/* Add the class name CLS to element ELT's `class' attribute. */
if (!elt.className.match('\\b' + cls + '\\b'))
elt.className += ' ' + cls
}
+DEP_UI.add_elt_class = add_elt_class;
-DEP_UI.rm_elt_class = function (elt, cls) {
+function rm_elt_class(elt, cls) {
/* Remove the class name CLS from element ELT's `class' attribute. */
elt.className = elt.className.replace(
new RegExp ('\\s*\\b' + cls + '\\b\\s*'), ' ');
}
+DEP_UI.rm_elt_class = rm_elt_class;
/* A gadget which can arrange to perform an idempotent action (the FUNC
* argument) again `soon'.
*/
-DEP_UI.Soon = function (func) {
+function Soon(func) {
this.timer = null;
this.func = func;
}
this.timer = setTimeout(function () { me.func(); }, 50);
}
};
+DEP.Soon = Soon;
/*----- Conversion machinery ----------------------------------------------*/
/* An exception, thrown if a conversion function doesn't like what it
* sees.
*/
-DEP_UI.BadValue = new DEP.Tag('BadValue');
+BadValue = new DEP.Tag('BadValue'); DEP.BadValue = BadValue;
-DEP_UI.convert_to_numeric = function (string) {
+function convert_to_numeric(string) {
/* Convert the argument STRING to a number. */
if (!string.match('\\S')) throw BadValue;
if (n !== n) throw BadValue;
return n;
}
+DEP_UI.convert_to_numeric = convert_to_numeric;
-DEP_UI.convert_from_numeric = function (num) {
+function convert_from_numeric(num) {
/* Convert the argument number NUM to a string, in a useful way. */
return num.toFixed(3);
}
+DEP_UI.convert_from_numeric = convert_from_numeric;
/*----- User interface functions ------------------------------------------*/
/* A list of input fields which might need periodic kicking. */
var KICK_INPUT_FIELDS = [];
-DEP_UI.input_field = function (id, dep, convert) {
+function input_field(id, dep, convert) {
/* Bind an input field (with the given ID) to a DEP, converting the user's
* input with the CONVERT function.
*/
// Arrange to update the dep `shortly after' updates.
var soon = new Soon(kick);
- function kick_soon () { soon.kick(); }
+ function kick_soon() { soon.kick(); }
e.addEventListener('click', kick_soon, false);
e.addEventListener('blur', kick_soon, false);
e.addEventListener('keypress', kick_soon, false);
// such functions to be run periodically just in case.
KICK_INPUT_FIELDS.push(kick);
}
+DEP_UI.input_field = input_field;
-DEP_UI.input_radio = function (id, dep) {
+function input_radio(id, dep) {
/* Bind a radio button (with the given ID) to a DEP. When the user frobs
* the button, set the dep to the element's `value' attribute.
*/
var e = elt(id);
- function kick () {
+ function kick() {
// Make sure we're actually chosen. We get called periodically
// regardless of user input.
if (e.checked) dep.set_value(e.value);
// Arrange to update the dep `shortly after' updates.
var soon = new Soon(kick);
- function kick_soon () { soon.kick(); }
+ function kick_soon() { soon.kick(); }
e.addEventListener('click', kick_soon, false);
e.addEventListener('changed', kick_soon, false);
// but let's be on the safe side.
KICK_INPUT_FIELDS.push(kick);
}
+DEP_UI.input_radio = input_radio;
-DEP_UI.output_field = function (id, dep, convert) {
+function output_field(id, dep, convert) {
/* Bind a DEP to an output element (given by ID), converting the dep's
* value using the CONVERT function.
*/
dep.add_listener(kicked);
kicked();
}
+DEP_UI.output_field = output_field;
/*----- Periodic maintenance ----------------------------------------------*/
window.addEventListener('load', kick_all, false);
/*----- That's all, folks -------------------------------------------------*/
-} })();
+})();
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-var DEP = { }; (function () { with (DEP) {
+var DEP = { }; (function () {
/*----- Utility functions and classes -------------------------------------*/
-DEP.dolist = function (list, func) {
+function dolist(list, func) {
/* Apply FUNC to each element of LIST, discarding the results.
*
* JavaScript's looping iterates over indices rather than values, which is
var i;
for (i in list) func(list[i]);
}
+DEP.dolist = dolist;
function eql(x, y) {
/* A standard equality function, suitable for detecting changes to `Dep'
* that the set of Tags is basically determined by the static structure of
* the program.
*/
-DEP.Tag = function (what) {
+function Tag(what) {
this.what = what;
}
Tag.prototype = {
toString: function () { return '#{Tag ' + this.what + '}'; }
}
+DEP.Tag = Tag;
/* A Generation is like a Tag, except that it's expected that a program will
* manufacture Generations repeatedly, and perhaps use them to determine
* whether an object is `up-to-date' in some sense.
*/
-DEP.Generation = function (what) {
+function Generation(what) {
this.what = what;
this.seq = Generation._next++;
}
/*----- Exceptions --------------------------------------------------------*/
-DEP.CircularDependency = new Tag('CircularDependency');
-DEP.BusyRecomputing = new Tag('BusyRecomputing');
+CircularDependency = new Tag('CircularDependency');
+DEP.CircularDependency = CircularDependency;
+
+BusyRecomputing = new Tag('BusyRecomputing');
+DEP.BusyRecomputing = BusyRecomputing;
/*----- Main code ---------------------------------------------------------*/
* causes that `Dep' to become bad in turn.
*/
-DEP.Dep = function (value, maybefunc) {
+function Dep(value, maybefunc) {
/* Initialize a new `Dep' object.
*
* Handling of the arguments is a little fiddly. If two arguments are
}
}
+DEP.Dep = Dep;
Dep._seq = 0; // Next sequence number to allocate.
Dep.prototype = {
}
};
-DEP.orelse = function (thunk, errthunk) {
+function orelse(thunk, errthunk) {
/* Call THUNK. If it succeeds, then return its result. If THUNK
* reads a bad dep then call ERRTHINK and return its result instead.
*/
else throw e;
}
}
+DEP.orelse = orelse;
-DEP.bad = function () {
+function bad() {
/* For use in a value-function: make the dep be bad. */
throw BAD;
}
+DEP.bad = bad;
function recompute_pending() {
/* Recompute any pending dependencies.
}
}
-DEP.with_frozen = function (body, delay) {
+function with_frozen(body, delay) {
/* Call BODY with dependencies frozen.
*
* If the BODY function changes any dep values (using D.set_value(...))
break;
}
}
+DEP.with_frozen = with_frozen;
/*----- That's all, folks -------------------------------------------------*/
-} })();
+})();