2007-08-04 04:03:51 +00:00
|
|
|
/* Based on Alex Arnell's inheritance implementation. */
|
2007-01-18 22:24:27 +00:00
|
|
|
var Class = {
|
2007-08-04 04:03:51 +00:00
|
|
|
create: function(parent, methods) {
|
2007-08-08 23:19:45 +00:00
|
|
|
if (arguments.length == 1 && !Object.isFunction(parent))
|
2007-08-04 04:03:51 +00:00
|
|
|
methods = parent, parent = null;
|
|
|
|
|
|
|
|
var method = function() {
|
|
|
|
if (!Class.extending) this.initialize.apply(this, arguments);
|
|
|
|
};
|
|
|
|
|
|
|
|
method.superclass = parent;
|
|
|
|
method.subclasses = [];
|
|
|
|
|
|
|
|
if (Object.isFunction(parent)) {
|
|
|
|
Class.extending = true;
|
|
|
|
method.prototype = new parent();
|
|
|
|
method.prototype.constructor = method;
|
|
|
|
|
|
|
|
parent.subclasses.push(method);
|
|
|
|
|
|
|
|
delete Class.extending;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (methods) Class.extend(method, methods);
|
|
|
|
|
|
|
|
return method;
|
|
|
|
},
|
|
|
|
|
|
|
|
extend: function(destination, source) {
|
|
|
|
for (var name in source) Class.inherit(destination, source, name);
|
|
|
|
return destination;
|
|
|
|
},
|
|
|
|
|
|
|
|
inherit: function(destination, source, name) {
|
|
|
|
var prototype = destination.prototype, ancestor = prototype[name],
|
|
|
|
descendant = source[name];
|
|
|
|
if (ancestor && Object.isFunction(descendant) &&
|
|
|
|
descendant.argumentNames().first() == "$super") {
|
|
|
|
var method = descendant, descendant = ancestor.wrap(method);
|
|
|
|
Object.extend(descendant, {
|
|
|
|
valueOf: function() { return method },
|
|
|
|
toString: function() { return method.toString() }
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
prototype[name] = descendant;
|
|
|
|
|
|
|
|
if (destination.subclasses && destination.subclasses.length > 0) {
|
|
|
|
for (var i = 0, subclass; subclass = destination.subclasses[i]; i++) {
|
|
|
|
Class.extending = true;
|
|
|
|
Object.extend(subclass.prototype, new destination());
|
|
|
|
subclass.prototype.constructor = subclass;
|
|
|
|
delete Class.extending;
|
|
|
|
Class.inherit(subclass, destination.prototype, name);
|
|
|
|
}
|
2007-01-18 22:24:27 +00:00
|
|
|
}
|
2007-08-04 04:03:51 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
mixin: function(destination, source) {
|
|
|
|
return Object.extend(destination, source);
|
2007-01-18 22:24:27 +00:00
|
|
|
}
|
2007-08-04 04:03:51 +00:00
|
|
|
};
|
2007-01-18 22:24:27 +00:00
|
|
|
|
2007-08-04 04:03:51 +00:00
|
|
|
var Abstract = { };
|
2007-01-18 22:24:27 +00:00
|
|
|
|
|
|
|
Object.extend = function(destination, source) {
|
|
|
|
for (var property in source) {
|
|
|
|
destination[property] = source[property];
|
|
|
|
}
|
|
|
|
return destination;
|
2007-08-04 04:03:51 +00:00
|
|
|
};
|
2007-01-18 22:24:27 +00:00
|
|
|
|
|
|
|
Object.extend(Object, {
|
|
|
|
inspect: function(object) {
|
|
|
|
try {
|
|
|
|
if (object === undefined) return 'undefined';
|
|
|
|
if (object === null) return 'null';
|
|
|
|
return object.inspect ? object.inspect() : object.toString();
|
|
|
|
} catch (e) {
|
|
|
|
if (e instanceof RangeError) return '...';
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2007-03-09 03:23:24 +00:00
|
|
|
toJSON: function(object) {
|
|
|
|
var type = typeof object;
|
2007-08-04 04:03:51 +00:00
|
|
|
switch (type) {
|
2007-03-09 03:23:24 +00:00
|
|
|
case 'undefined':
|
|
|
|
case 'function':
|
|
|
|
case 'unknown': return;
|
|
|
|
case 'boolean': return object.toString();
|
|
|
|
}
|
2007-08-04 04:03:51 +00:00
|
|
|
|
2007-03-09 03:23:24 +00:00
|
|
|
if (object === null) return 'null';
|
|
|
|
if (object.toJSON) return object.toJSON();
|
2007-07-24 18:52:17 +00:00
|
|
|
if (Object.isElement(object)) return;
|
2007-08-04 04:03:51 +00:00
|
|
|
|
2007-03-09 03:23:24 +00:00
|
|
|
var results = [];
|
|
|
|
for (var property in object) {
|
|
|
|
var value = Object.toJSON(object[property]);
|
|
|
|
if (value !== undefined)
|
2007-04-24 02:50:52 +00:00
|
|
|
results.push(property.toJSON() + ': ' + value);
|
2007-03-09 03:23:24 +00:00
|
|
|
}
|
2007-08-04 04:03:51 +00:00
|
|
|
|
2007-04-24 02:50:52 +00:00
|
|
|
return '{' + results.join(', ') + '}';
|
2007-03-09 03:23:24 +00:00
|
|
|
},
|
|
|
|
|
2007-07-24 18:52:17 +00:00
|
|
|
toHTML: function(object) {
|
|
|
|
return object && object.toHTML ? object.toHTML() : String.interpret(object);
|
|
|
|
},
|
|
|
|
|
2007-01-18 22:24:27 +00:00
|
|
|
keys: function(object) {
|
|
|
|
var keys = [];
|
|
|
|
for (var property in object)
|
|
|
|
keys.push(property);
|
|
|
|
return keys;
|
|
|
|
},
|
|
|
|
|
|
|
|
values: function(object) {
|
|
|
|
var values = [];
|
|
|
|
for (var property in object)
|
|
|
|
values.push(object[property]);
|
|
|
|
return values;
|
|
|
|
},
|
|
|
|
|
|
|
|
clone: function(object) {
|
2007-08-04 04:03:51 +00:00
|
|
|
return Object.extend({ }, object);
|
2007-07-24 18:52:17 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
isElement: function(object) {
|
|
|
|
return object && object.nodeType == 1;
|
|
|
|
},
|
|
|
|
|
|
|
|
isArray: function(object) {
|
|
|
|
return object && object.constructor === Array;
|
2007-08-04 04:03:51 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
isFunction: function(object) {
|
|
|
|
return typeof object == "function";
|
2007-08-08 23:19:45 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
isString: function(object) {
|
|
|
|
return typeof object == "string";
|
|
|
|
},
|
|
|
|
|
|
|
|
isNumber: function(object) {
|
|
|
|
return typeof object == "number";
|
|
|
|
},
|
|
|
|
|
|
|
|
isUndefined: function(object) {
|
|
|
|
return typeof object == "undefined";
|
2007-01-18 22:24:27 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2007-04-29 05:37:07 +00:00
|
|
|
Object.extend(Function.prototype, {
|
2007-07-30 04:38:20 +00:00
|
|
|
argumentNames: function() {
|
|
|
|
var names = this.toString().match(/^function\s*\((.*?)\)/)[1].split(",").invoke("strip");
|
|
|
|
return names.length == 1 && !names[0] ? [] : names;
|
|
|
|
},
|
|
|
|
|
2007-04-29 05:37:07 +00:00
|
|
|
bind: function() {
|
2007-07-09 18:55:58 +00:00
|
|
|
if (arguments.length < 2 && arguments[0] === undefined) return this;
|
2007-04-29 05:37:07 +00:00
|
|
|
var __method = this, args = $A(arguments), object = args.shift();
|
|
|
|
return function() {
|
|
|
|
return __method.apply(object, args.concat($A(arguments)));
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
bindAsEventListener: function() {
|
|
|
|
var __method = this, args = $A(arguments), object = args.shift();
|
|
|
|
return function(event) {
|
2007-05-01 04:19:46 +00:00
|
|
|
return __method.apply(object, [event || window.event].concat(args));
|
2007-04-29 05:37:07 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
curry: function() {
|
2007-07-09 18:55:58 +00:00
|
|
|
if (!arguments.length) return this;
|
2007-04-29 05:37:07 +00:00
|
|
|
var __method = this, args = $A(arguments);
|
|
|
|
return function() {
|
|
|
|
return __method.apply(this, args.concat($A(arguments)));
|
|
|
|
}
|
|
|
|
},
|
2007-01-18 22:24:27 +00:00
|
|
|
|
2007-04-29 05:37:07 +00:00
|
|
|
delay: function() {
|
|
|
|
var __method = this, args = $A(arguments), timeout = args.shift() * 1000;
|
|
|
|
return window.setTimeout(function() {
|
|
|
|
return __method.apply(__method, args);
|
|
|
|
}, timeout);
|
|
|
|
},
|
|
|
|
|
|
|
|
wrap: function(wrapper) {
|
|
|
|
var __method = this;
|
|
|
|
return function() {
|
|
|
|
return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
|
|
|
|
}
|
2007-05-12 04:32:30 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
methodize: function() {
|
|
|
|
if (this._methodized) return this._methodized;
|
|
|
|
var __method = this;
|
|
|
|
return this._methodized = function() {
|
|
|
|
return __method.apply(null, [this].concat($A(arguments)));
|
|
|
|
};
|
2007-01-18 22:24:27 +00:00
|
|
|
}
|
2007-04-29 05:37:07 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
Function.prototype.defer = Function.prototype.delay.curry(0.01);
|
2007-01-18 22:24:27 +00:00
|
|
|
|
2007-03-09 03:23:24 +00:00
|
|
|
Date.prototype.toJSON = function() {
|
|
|
|
return '"' + this.getFullYear() + '-' +
|
|
|
|
(this.getMonth() + 1).toPaddedString(2) + '-' +
|
|
|
|
this.getDate().toPaddedString(2) + 'T' +
|
|
|
|
this.getHours().toPaddedString(2) + ':' +
|
|
|
|
this.getMinutes().toPaddedString(2) + ':' +
|
|
|
|
this.getSeconds().toPaddedString(2) + '"';
|
|
|
|
};
|
|
|
|
|
2007-01-18 22:24:27 +00:00
|
|
|
var Try = {
|
|
|
|
these: function() {
|
|
|
|
var returnValue;
|
|
|
|
|
|
|
|
for (var i = 0, length = arguments.length; i < length; i++) {
|
|
|
|
var lambda = arguments[i];
|
|
|
|
try {
|
|
|
|
returnValue = lambda();
|
|
|
|
break;
|
2007-08-08 23:19:45 +00:00
|
|
|
} catch (e) { }
|
2007-01-18 22:24:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return returnValue;
|
|
|
|
}
|
2007-08-04 04:03:51 +00:00
|
|
|
};
|
2007-01-18 22:24:27 +00:00
|
|
|
|
2007-07-24 16:47:12 +00:00
|
|
|
RegExp.prototype.match = RegExp.prototype.test;
|
|
|
|
|
2007-08-04 07:31:52 +00:00
|
|
|
RegExp.escape = function(str) {
|
|
|
|
return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
|
|
|
|
};
|
|
|
|
|
2007-01-18 22:24:27 +00:00
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
|
2007-08-04 04:03:51 +00:00
|
|
|
var PeriodicalExecuter = Class.create({
|
2007-01-18 22:24:27 +00:00
|
|
|
initialize: function(callback, frequency) {
|
|
|
|
this.callback = callback;
|
|
|
|
this.frequency = frequency;
|
|
|
|
this.currentlyExecuting = false;
|
|
|
|
|
|
|
|
this.registerCallback();
|
|
|
|
},
|
|
|
|
|
|
|
|
registerCallback: function() {
|
|
|
|
this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
|
|
|
|
},
|
|
|
|
|
|
|
|
stop: function() {
|
|
|
|
if (!this.timer) return;
|
|
|
|
clearInterval(this.timer);
|
|
|
|
this.timer = null;
|
|
|
|
},
|
|
|
|
|
|
|
|
onTimerEvent: function() {
|
|
|
|
if (!this.currentlyExecuting) {
|
|
|
|
try {
|
|
|
|
this.currentlyExecuting = true;
|
|
|
|
this.callback(this);
|
|
|
|
} finally {
|
|
|
|
this.currentlyExecuting = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-08-04 04:03:51 +00:00
|
|
|
});
|