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 })();