1 //require <jquery.packed.js> 2 3 /** 4 * @class 5 * @name XataJax 6 * @description A class that includes utility methods that are needed for 7 * loading scripts and manipulating the environment. 8 */ 9 XataJax = {}; 10 11 (function(){ 12 XataJax.Exception = Exception; 13 XataJax.proxy = proxy; 14 XataJax.extend = extend; 15 XataJax.instanceOf = instanceOf; 16 XataJax.publicAPI = publicAPI; 17 XataJax.findConstructor = findConstructor; 18 XataJax.ready = ready; 19 XataJax.main = main; 20 XataJax.load = load; 21 22 var $ = jQuery; 23 24 25 function Exception(o){ 26 /** 27 """ 28 Exception.__properties__ = XataJax.doc.getProperties(publicProperties); 29 """ 30 */ 31 32 /** 33 * @type {String} 34 */ 35 var message = ''; 36 37 /** 38 * @type {int} 39 */ 40 var code = 0; 41 42 var publicProperties = { 43 message: message, 44 code: code, 45 toString: function(){ 46 return this.getMessage(); 47 } 48 }; 49 50 $.extend(this, publicProperties); 51 52 if ( typeof(o) == 'string' ){ 53 this.message = o; 54 } else if ( typeof(o) == 'object' ){ 55 $.extend(this, o); 56 } 57 } 58 59 var Exception_publicAPI = { 60 getMessage: Exception_getMessage, 61 getCode: Exception_getCode 62 }; 63 64 Exception.prototype = Exception_publicAPI; 65 Exception.prototype.constructor = Exception; 66 67 /** 68 * Gets the exception's message. 69 * @returns {String} The message 70 */ 71 function Exception_getMessage(){ return this.message;} 72 73 /** 74 * Gets the exception's code. 75 * @returns {int} The code 76 */ 77 function Exception_getCode(){ return this.code;} 78 79 /** 80 * Keeps track of error codes. 81 */ 82 XataJax.errorcodes = {}; 83 84 /** 85 * Pointer to next error code. 86 */ 87 XataJax.nextErrorCode = nextErrorCode; 88 89 var nextCode = 1; 90 function nextErrorCode(){ 91 return nextCode++; 92 } 93 94 /** 95 * Proxies all of the methods of a class to that "this" 96 * refers to obj. 97 * 98 * @param 1 {Object} The class that we want to proxy. 99 * @param 2 {Object} The object that we want as "this" context. 100 * @returns {Object} Copy of the class that uses obj as this context. 101 */ 102 function proxy(cls, obj){ 103 var out = {}; 104 for ( var i in obj){ 105 if ( typeof(obj[i]) == 'function' ){ 106 out[i] = $.proxy(obj[i], cls); 107 } else { 108 out[i] = obj[i]; 109 } 110 } 111 return out; 112 113 } 114 115 /** 116 * Checks of obj is an instance of cls 117 * @param 1 {Object} The object that we are checking. 118 * @param 2 {Object} The class that we are checking the object against. 119 */ 120 function instanceOf(obj, cls){ 121 if ( obj == null || typeof(obj) != 'object' ) return false; 122 if ( cls == obj.constructor ){ 123 return true; 124 } 125 if ( typeof(obj._super) != 'undefined' ){ 126 for ( var i=0; i<obj._super.length; i++){ 127 var curr = obj._super[i]; 128 if ( typeof(curr.instanceOf) == 'function' && curr.instanceOf(cls) ){ 129 return true; 130 } else if ( curr.constructor == cls ){ 131 return true; 132 } 133 } 134 } 135 return false; 136 } 137 138 139 /** 140 * Causes the target object to extend from the source object. This is similar to 141 * jQuery.extend but goes further by proxying all of the methods so that the 142 * context of each method of the super classes correctly point to the target class. 143 * This builds a _super array of parent objects so that we can keep track of which 144 * objects inherit from which parent objects so we can build a class heirarchy. 145 * 146 * @param 1 {Object} target The child object. 147 * @param 2 {Object} the parent object. 148 */ 149 function extend(target, source){ 150 var _super = proxy(target, source); 151 _super.constructor = source.constructor; 152 var oldConstructor = target.constructor; 153 $.extend(target, _super); 154 target.constructor = oldConstructor; 155 if ( typeof(target._super) == 'undefined' ){ 156 target._super = []; 157 } 158 159 160 161 162 target._super.push(_super); 163 target.getSuper = function(cls){ 164 for ( var i=0; i<target._super.length; i++ ){ 165 //alert('Checking if is '+target._super[i].constructor.prototype); 166 //alert(target._super[i].constructor ); 167 if ( (typeof(cls) == 'undefined') || (target._super[i].constructor == cls) ){ 168 return target._super[i]; 169 } 170 } 171 return null; 172 }; 173 174 target.instanceOf = function(obj){ 175 return instanceOf(this, obj); 176 }; 177 178 if ( typeof(target.init) == 'function' ){ 179 target.init(); 180 } 181 182 } 183 184 /** 185 * Defines the public API for a class. 186 * @param 1 {Object} The object instance to which we are adding 187 * the properties. 188 * @param 2 {Object} The properties for the object. Can be methods or functions. 189 */ 190 function publicAPI(obj, properties){ 191 $.extend(obj, properties); 192 } 193 194 195 196 /** 197 * Finds a constructor based on an absolute dot notation path. 198 * e.g. XataJax.ui.tk.Component 199 * @param {String} path 200 */ 201 function findConstructor(path){ 202 var parts = path.split('.'); 203 var pkg = window; 204 while ( parts.length > 0 ){ 205 206 pkg = pkg[parts.shift()]; 207 if ( !pkg ){ 208 return null; 209 } 210 } 211 return pkg; 212 } 213 214 215 var readyFuncs = []; 216 var mainLoaded = false; 217 function ready(func){ 218 if ( func == undefined ) return main(function(){}); 219 if ( mainLoaded ){ 220 func(); 221 } else { 222 readyFuncs.push(func); 223 } 224 } 225 226 function main(func){ 227 mainLoaded=true; 228 $.each(readyFuncs, function(){ 229 this(); 230 }); 231 readyFuncs = []; 232 func(); 233 234 } 235 236 /** 237 * @function 238 * @name load 239 * @memberOf XataJax 240 * @description Loads a namespace, object, or class using its fully-qualified 241 * name. If the namespace hasn't been created yet, this will create it. If it 242 * has already been created, it just returns the existing namespace. 243 * 244 * @param {String} The name of a namespace. 245 * @returns {Object} The namespace. 246 * 247 * @example 248 * // require <xataface/IO.js> 249 * // Load the IO class so we can use it 250 * var IO = XataJax.load('xataface.IO'); 251 * 252 */ 253 function load(/*String*/ ns){ 254 var parts = ns.split('.'); 255 var context = window; 256 while ( parts.length > 0 ){ 257 var part = parts.shift(); 258 if ( typeof(context[part]) == 'undefined' ) context[part] = {}; 259 context = context[part]; 260 } 261 return context; 262 } 263 264 265 266 267 })();