1/** 2 * Classy - classy classes for JavaScript 3 * 4 * :copyright: (c) 2010 by Armin Ronacher. 5 * :license: BSD. 6 */ 7 8;(function(undefined) { 9 var 10 CLASSY_VERSION = '1.3', 11 root = this, 12 old_class = Class, 13 disable_constructor = false; 14 15 /* we check if $super is in use by a class if we can. But first we have to 16 check if the JavaScript interpreter supports that. This also matches 17 to false positives later, but that does not do any harm besides slightly 18 slowing calls down. */ 19 var probe_super = (function(){$super();}).toString().indexOf('$super') > 0; 20 function usesSuper(obj) { 21 return !probe_super || /\B\$super\b/.test(obj.toString()); 22 } 23 24 /* helper function to set the attribute of something to a value or 25 removes it if the value is undefined. */ 26 function setOrUnset(obj, key, value) { 27 if (value === undefined) 28 delete obj[key]; 29 else 30 obj[key] = value; 31 } 32 33 /* gets the own property of an object */ 34 function getOwnProperty(obj, name) { 35 return Object.prototype.hasOwnProperty.call(obj, name) 36 ? obj[name] : undefined; 37 } 38 39 /* instanciate a class without calling the constructor */ 40 function cheapNew(cls) { 41 disable_constructor = true; 42 var rv = new cls; 43 disable_constructor = false; 44 return rv; 45 } 46 47 /* the base class we export */ 48 var Class = function() {}; 49 50 /* restore the global Class name and pass it to a function. This allows 51 different versions of the classy library to be used side by side and 52 in combination with other libraries. */ 53 Class.$noConflict = function() { 54 try { 55 setOrUnset(root, 'Class', old_class); 56 } 57 catch (e) { 58 // fix for IE that does not support delete on window 59 root.Class = old_class; 60 } 61 return Class; 62 }; 63 64 /* what version of classy are we using? */ 65 Class.$classyVersion = CLASSY_VERSION; 66 67 /* extend functionality */ 68 Class.$extend = function(properties) { 69 var super_prototype = this.prototype; 70 71 /* disable constructors and instanciate prototype. Because the 72 prototype can't raise an exception when created, we are safe 73 without a try/finally here. */ 74 var prototype = cheapNew(this); 75 76 /* copy all properties of the includes over if there are any */ 77 if (properties.__include__) 78 for (var i = 0, n = properties.__include__.length; i != n; ++i) { 79 var mixin = properties.__include__[i]; 80 for (var name in mixin) { 81 var value = getOwnProperty(mixin, name); 82 if (value !== undefined) 83 prototype[name] = mixin[name]; 84 } 85 } 86 87 /* copy all properties over to the new prototype */ 88 for (var name in properties) { 89 var value = getOwnProperty(properties, name); 90 if (name === '__include__' || 91 name === '__classvars__' || 92 value === undefined) 93 continue; 94 95 prototype[name] = typeof value === 'function' && usesSuper(value) ? 96 (function(meth, name) { 97 return function() { 98 var old_super = getOwnProperty(this, '$super'); 99 this.$super = super_prototype[name]; 100 try { 101 return meth.apply(this, arguments); 102 } 103 finally { 104 setOrUnset(this, '$super', old_super); 105 } 106 }; 107 })(value, name) : value 108 } 109 110 /* dummy constructor */ 111 var rv = function() { 112 if (disable_constructor) 113 return; 114 var proper_this = root === this ? cheapNew(arguments.callee) : this; 115 if (proper_this.__init__) 116 proper_this.__init__.apply(proper_this, arguments); 117 proper_this.$class = rv; 118 return proper_this; 119 } 120 121 /* copy all class vars over of any */ 122 if (properties.__classvars__) 123 for (var key in properties.__classvars__) { 124 var value = getOwnProperty(properties.__classvars__, key); 125 if (value !== undefined) 126 rv[key] = value; 127 } 128 129 /* copy prototype and constructor over, reattach $extend and 130 return the class */ 131 rv.prototype = prototype; 132 rv.constructor = rv; 133 rv.$extend = Class.$extend; 134 rv.$withData = Class.$withData; 135 return rv; 136 }; 137 138 /* instanciate with data functionality */ 139 Class.$withData = function(data) { 140 var rv = cheapNew(this); 141 for (var key in data) { 142 var value = getOwnProperty(data, key); 143 if (value !== undefined) 144 rv[key] = value; 145 } 146 return rv; 147 }; 148 149 /* export the class */ 150 root.Class = Class; 151})();
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.