/** This function defines the Base class, from which all other classes are inherited. * The Base class defines a somewhat sound framework for inheritance. */ Base = function () { if (arguments.length) { if (this == window) { Base.prototype.extend.call(arguments[0], arguments.callee.prototype); } else { this.extend(arguments[0]); } } }; /** This class property lists the functions to be called when the page * containing the code is first loaded. */ Base.initialisers = new Array(); /** This class property lists the functions to be called when the page * containing the code is unloaded. */ Base.destructors = new Array(); /** This class method adds a function to the list of initialisers. */ Base.registerInitialiser = function (initialiser) { Base.initialisers.push(initialiser); }; /** This class method adds a function to the list of destructors. */ Base.registerDestructor = function (destructor) { Base.destructors.push(destructor); }; Base.prototype = { /** The extend() method adds a set of methods and properties to an existing object. * @param addition an object containing the methods and properties to add. * @returns the extended object. */ extend: function (addition) { var _o = Base.prototype.overload; var _p = { toSource: null }; var _l = ['toString', 'valueOf']; if (Base._inherits) { _l.push('constructor'); } for (var i in _l) { var _n = _l[i]; if (addition[_n] != _p[_n]) { _o.call(this, _n, addition[_n]); _p[_n] = addition[_n]; } } for (var i in addition) { if (_p[i]) { continue; } if (addition[i] instanceof Function) { _o.call(this, i, addition[i]); } else { this[i] = addition[i]; } } return this; }, /** The overload() method overloads a single method in an object; it * creates a new function that sets this.base to the old value then * calls the new code. * @param name the name of the method to be overloaded. * @param value the Function object for the new method. * @returns the value for the overloaded method. */ overload: function (name, value) { if (value == this[name] || name == 'base') { return; } var _v = value, _ov = this[name]; value = function () { var _b = this.base; this.base = _ov; var _r = _v.apply(this, arguments); this.base = _b; return _r; }; value.valueOf = function() { return _v; }; value.toString = function () { return String(_v); }; return this[name] = value; } }; /** This class property stores the list of namespaces to preserve when onunload is called. */ Base._preserve = new Array(); /** This static method is used to define class inheritance. * @param members an object containing the new methods and properties to be added or overloaded. * @param cMembers an object containing the methods and properties to be added as static members. * @param name a string indicating the namespace this object is supposed to define; it is used * to preserve namespaces from being deleted before the onunload() handler. * @return the object corresponding to the newly created class. */ Base.inherits = function (members, cMembers, name) { if (!members) { members = { }; } var _e = Base.prototype.extend; var _b = this; Base._inherits = true; var _p = new _b; _e.call(_p, members); delete Base._inherits; var _c = _p.constructor; _p.constructor = this; var _cl = function() { this.base = _b; if (!Base._inherits) { _c.apply(this, arguments); } this.constructor = _cl; delete this.base; }; _cl.inherits = this.inherits; _cl.toString = function() { return String(_c); }; _cl.prototype = _p; if (!cMembers) { cMembers = { }; } _e.call(_cl, cMembers); if (cMembers["onLoad"] instanceof Function) { Base.registerInitialiser(_cl["onLoad"]); } if (cMembers["onUnload"] instanceof Function) { Base.registerDestructor(_cl["onUnload"]); } if (name && name != "") { Base._preserve[name] = _cl; } return _cl; }; /** Set the page's onload() handler. */ window.onload = function () { var _b = Base; for (var i in _b.initialisers) { if (typeof _b.initialisers[i] == 'undefined') { continue; } _b.initialisers[i](); } /** Set the page's onunload() handler. */ window.onunload = function () { Base = _b; for (var i in _b._preserve) { eval(i + " = _b._preserve[i]"); } for (var i = _b.destructors.length - 1; i >= 0; i--) { _b.destructors[i](); } }; };