1/* 2--- 3 4name: Class 5 6description: Contains the Class Function for easily creating, extending, and implementing reusable Classes. 7 8license: MIT-style license. 9 10requires: [Array, String, Function, Number] 11 12provides: Class 13 14... 15*/ 16 17(function(){ 18 19var Class = this.Class = new Type('Class', function(params){ 20 if (instanceOf(params, Function)) params = {initialize: params}; 21 22 var newClass = function(){ 23 reset(this); 24 if (newClass.$prototyping) return this; 25 this.$caller = null; 26 var value = (this.initialize) ? this.initialize.apply(this, arguments) : this; 27 this.$caller = this.caller = null; 28 return value; 29 }.extend(this).implement(params); 30 31 newClass.$constructor = Class; 32 newClass.prototype.$constructor = newClass; 33 newClass.prototype.parent = parent; 34 35 return newClass; 36}); 37 38var 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); 45}; 46 47var reset = function(object){ 48 for (var key in object){ 49 var value = object[key]; 50 switch (typeOf(value)){ 51 case 'object': 52 var F = function(){}; 53 F.prototype = value; 54 object[key] = reset(new F); 55 break; 56 case 'array': object[key] = value.clone(); break; 57 } 58 } 59 return object; 60}; 61 62var 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; 70 return result; 71 }.extend({$owner: self, $origin: method, $name: key}); 72 return wrapper; 73}; 74 75var 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; 79 } 80 81 if (typeOf(value) == 'function'){ 82 if (value.$hidden) return this; 83 this.prototype[key] = (retain) ? value : wrap(this, key, value); 84 } else { 85 Object.merge(this.prototype, key, value); 86 } 87 88 return this; 89}; 90 91var getInstance = function(klass){ 92 klass.$prototyping = true; 93 var proto = new klass; 94 delete klass.$prototyping; 95 return proto; 96}; 97 98Class.implement('implement', implement.overloadSetter()); 99 100Class.Mutators = { 101 102 Extends: function(parent){ 103 this.parent = parent; 104 this.prototype = getInstance(parent); 105 }, 106 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); 111 }, this); 112 } 113}; 114 115})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.