github.com/nicgrayson/terraform@v0.4.3-0.20150415203910-c4de50829380/website/source/assets/javascripts/lib/Base.js (about) 1 /* 2 Based on Base.js 1.1a (c) 2006-2010, Dean Edwards 3 Updated to pass JSHint and converted into a module by Kenneth Powers 4 License: http://www.opensource.org/licenses/mit-license.php 5 */ 6 /*global define:true module:true*/ 7 /*jshint eqeqeq:true*/ 8 (function (name, global, definition) { 9 if (typeof module !== 'undefined') { 10 module.exports = definition(); 11 } else if (typeof define !== 'undefined' && typeof define.amd === 'object') { 12 define(definition); 13 } else { 14 global[name] = definition(); 15 } 16 })('Base', this, function () { 17 // Base Object 18 var Base = function () {}; 19 20 // Implementation 21 Base.extend = function (_instance, _static) { // subclass 22 var extend = Base.prototype.extend; 23 // build the prototype 24 Base._prototyping = true; 25 var proto = new this(); 26 extend.call(proto, _instance); 27 proto.base = function () { 28 // call this method from any other method to invoke that method's ancestor 29 }; 30 delete Base._prototyping; 31 // create the wrapper for the constructor function 32 //var constructor = proto.constructor.valueOf(); //-dean 33 var constructor = proto.constructor; 34 var klass = proto.constructor = function () { 35 if (!Base._prototyping) { 36 if (this._constructing || this.constructor === klass) { // instantiation 37 this._constructing = true; 38 constructor.apply(this, arguments); 39 delete this._constructing; 40 } else if (arguments[0] !== null) { // casting 41 return (arguments[0].extend || extend).call(arguments[0], proto); 42 } 43 } 44 }; 45 // build the class interface 46 klass.ancestor = this; 47 klass.extend = this.extend; 48 klass.forEach = this.forEach; 49 klass.implement = this.implement; 50 klass.prototype = proto; 51 klass.toString = this.toString; 52 klass.valueOf = function (type) { 53 return (type === 'object') ? klass : constructor.valueOf(); 54 }; 55 extend.call(klass, _static); 56 // class initialization 57 if (typeof klass.init === 'function') klass.init(); 58 return klass; 59 }; 60 61 Base.prototype = { 62 extend: function (source, value) { 63 if (arguments.length > 1) { // extending with a name/value pair 64 var ancestor = this[source]; 65 if (ancestor && (typeof value === 'function') && // overriding a method? 66 // the valueOf() comparison is to avoid circular references 67 (!ancestor.valueOf || ancestor.valueOf() !== value.valueOf()) && /\bbase\b/.test(value)) { 68 // get the underlying method 69 var method = value.valueOf(); 70 // override 71 value = function () { 72 var previous = this.base || Base.prototype.base; 73 this.base = ancestor; 74 var returnValue = method.apply(this, arguments); 75 this.base = previous; 76 return returnValue; 77 }; 78 // point to the underlying method 79 value.valueOf = function (type) { 80 return (type === 'object') ? value : method; 81 }; 82 value.toString = Base.toString; 83 } 84 this[source] = value; 85 } else if (source) { // extending with an object literal 86 var extend = Base.prototype.extend; 87 // if this object has a customized extend method then use it 88 if (!Base._prototyping && typeof this !== 'function') { 89 extend = this.extend || extend; 90 } 91 var proto = { 92 toSource: null 93 }; 94 // do the "toString" and other methods manually 95 var hidden = ['constructor', 'toString', 'valueOf']; 96 // if we are prototyping then include the constructor 97 for (var i = Base._prototyping ? 0 : 1; i < hidden.length; i++) { 98 var h = hidden[i]; 99 if (source[h] !== proto[h]) 100 extend.call(this, h, source[h]); 101 } 102 // copy each of the source object's properties to this object 103 for (var key in source) { 104 if (!proto[key]) extend.call(this, key, source[key]); 105 } 106 } 107 return this; 108 } 109 }; 110 111 // initialize 112 Base = Base.extend({ 113 constructor: function () { 114 this.extend(arguments[0]); 115 } 116 }, { 117 ancestor: Object, 118 version: '1.1', 119 forEach: function (object, block, context) { 120 for (var key in object) { 121 if (this.prototype[key] === undefined) { 122 block.call(context, object[key], key, object); 123 } 124 } 125 }, 126 implement: function () { 127 for (var i = 0; i < arguments.length; i++) { 128 if (typeof arguments[i] === 'function') { 129 // if it's a function, call it 130 arguments[i](this.prototype); 131 } else { 132 // add the interface using the extend method 133 this.prototype.extend(arguments[i]); 134 } 135 } 136 return this; 137 }, 138 toString: function () { 139 return String(this.valueOf()); 140 } 141 }); 142 143 // Return Base implementation 144 return Base; 145 });