6 description: Contains the Class Function for easily creating, extending, and implementing reusable Classes.
8 license: MIT-style license.
10 requires: [Array, String, Function, Number]
19 var Class = this.Class = new Type('Class', function(params){
20 if (instanceOf(params, Function)) params = {initialize: params};
22 var newClass = function(){
24 if (newClass.$prototyping) return this;
26 var value = (this.initialize) ? this.initialize.apply(this, arguments) : this;
27 this.$caller = this.caller = null;
29 }.extend(this).implement(params);
31 newClass.$constructor = Class;
32 newClass.prototype.$constructor = newClass;
33 newClass.prototype.parent = parent;
38 var parent = function(){
39 if (!this.$caller) throw new Error('The method "parent" cannot be called.');
40 var name = this.$caller.$name,
41 parent = this.$caller.$owner.parent,
42 previous = (parent) ? parent.prototype[name] : null;
43 if (!previous) throw new Error('The method "' + name + '" has no parent.');
44 return previous.apply(this, arguments);
47 var reset = function(object){
48 for (var key in object){
49 var value = object[key];
50 switch (typeOf(value)){
54 object[key] = reset(new F);
56 case 'array': object[key] = value.clone(); break;
62 var wrap = function(self, key, method){
63 if (method.$origin) method = method.$origin;
64 var wrapper = function(){
65 if (method.$protected && this.$caller == null) throw new Error('The method "' + key + '" cannot be called.');
66 var caller = this.caller, current = this.$caller;
67 this.caller = current; this.$caller = wrapper;
68 var result = method.apply(this, arguments);
69 this.$caller = current; this.caller = caller;
71 }.extend({$owner: self, $origin: method, $name: key});
75 var implement = function(key, value, retain){
76 if (Class.Mutators.hasOwnProperty(key)){
77 value = Class.Mutators[key].call(this, value);
78 if (value == null) return this;
81 if (typeOf(value) == 'function'){
82 if (value.$hidden) return this;
83 this.prototype[key] = (retain) ? value : wrap(this, key, value);
85 Object.merge(this.prototype, key, value);
91 var getInstance = function(klass){
92 klass.$prototyping = true;
93 var proto = new klass;
94 delete klass.$prototyping;
98 Class.implement('implement', implement.overloadSetter());
102 Extends: function(parent){
103 this.parent = parent;
104 this.prototype = getInstance(parent);
107 Implements: function(items){
108 Array.from(items).each(function(item){
109 var instance = new item;
110 for (var key in instance) implement.call(this, key, instance[key], true);