190 lines
4.4 KiB
JavaScript
190 lines
4.4 KiB
JavaScript
|
/** 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]();
|
||
|
}
|
||
|
};
|
||
|
};
|