PageRenderTime 206ms CodeModel.GetById 101ms app.highlight 20ms RepoModel.GetById 81ms app.codeStats 0ms

/ajax/simile-ajax-api.js

http://showslow.googlecode.com/
JavaScript | 282 lines | 226 code | 28 blank | 28 comment | 76 complexity | 3e503c7c2574d1e6b371ae40e3f6e198 MD5 | raw file
  1/*==================================================
  2 *  Simile Ajax API
  3 *==================================================
  4 */
  5
  6if (typeof SimileAjax == "undefined") {
  7    var isCompiled = ("SimileAjax_isCompiled" in window) && window.SimileAjax_isCompiled;
  8
  9    var SimileAjax = {
 10        loaded:                 false,
 11        loadingScriptsCount:    0,
 12        error:                  null,
 13        params:                 { bundle:"true" }
 14    };
 15    
 16    SimileAjax.Platform = new Object();
 17        /*
 18            HACK: We need these 2 things here because we cannot simply append
 19            a <script> element containing code that accesses SimileAjax.Platform
 20            to initialize it because IE executes that <script> code first
 21            before it loads ajax.js and platform.js.
 22        */
 23        
 24    var getHead = function(doc) {
 25        return doc.getElementsByTagName("head")[0];
 26    };
 27    
 28    SimileAjax.findScript = function(doc, substring) {
 29	var scripts=doc.documentElement.getElementsByTagName("script");
 30	for (s=0; s<scripts.length;s++) {
 31            var url = scripts[s].src;
 32            var i = url.indexOf(substring);
 33            if (i >= 0) {
 34                return url;
 35            }
 36	}
 37
 38        var heads = doc.documentElement.getElementsByTagName("head");
 39        for (var h = 0; h < heads.length; h++) {
 40            var node = heads[h].firstChild;
 41            while (node != null) {
 42                if (node.nodeType == 1 && node.tagName.toLowerCase() == "script") {
 43                    var url = node.src;
 44                    var i = url.indexOf(substring);
 45                    if (i >= 0) {
 46                        return url;
 47                    }
 48                }
 49                node = node.nextSibling;
 50            }
 51        }
 52        return null;
 53    };
 54
 55    SimileAjax.includeJavascriptFile = function(doc, url, onerror, charset, callback) {
 56        onerror = onerror || "";
 57        if (doc.body == null) {
 58            try {
 59                var q = "'" + onerror.replace( /'/g, '&apos' ) + "'"; // "
 60                doc.write("<script src='" + url + "' onerror="+ q +
 61                          (charset ? " charset='"+ charset +"'" : "") +
 62                          " type='text/javascript'>"+ onerror + "</script>");
 63                return;
 64            } catch (e) {
 65                // fall through
 66            }
 67        }
 68
 69	var calledBack = false;
 70	var callbackOnce = function() {
 71	    if (callback && !calledBack) {
 72		calledBack=true;
 73		callback();
 74	    }
 75	}
 76        var script = doc.createElement("script");
 77        if (onerror) {
 78            try { script.innerHTML = onerror; } catch(e) {};
 79            script.onerror = function () {onerror(); callbackOnce()};
 80        }
 81	else {
 82	    script.onerror = callbackOnce;
 83	}
 84        if (charset) {
 85            script.setAttribute("charset", charset);
 86        }
 87        script.type = "text/javascript";
 88        script.language = "JavaScript";
 89        script.src = url;
 90	if (callback) 
 91	    script.onload = script.onreadystatechange = function() {
 92		if (!this.readyState || this.readyState == "loaded" || 
 93		    this.readyState == "complete") 
 94		    callbackOnce();
 95	    }       
 96        return getHead(doc).appendChild(script);
 97    };
 98
 99    function includeJavascriptList(doc, urlPrefix, filenames, included, index, callback) {
100        if (!included[index]) { // avoid duplicate callback
101            included[index] = true;
102            if (index<filenames.length) { 
103		var nextCall=function(){
104		    includeJavascriptList(doc, urlPrefix, filenames, 
105					  included, index+1, callback);
106		}
107                SimileAjax.
108		includeJavascriptFile(doc, 
109				      urlPrefix + filenames[index], null, null, 
110				      nextCall);
111	    }
112            else if (callback != null) callback();
113        }
114    }
115    
116    SimileAjax.includeJavascriptFiles = function(doc, urlPrefix, filenames) {
117	if (doc.body == null) {
118            for (var i = 0; i < filenames.length; i++) {
119                SimileAjax.includeJavascriptFile(doc, urlPrefix + filenames[i]);
120            }
121            SimileAjax.loadingScriptsCount += filenames.length;
122            SimileAjax.includeJavascriptFile(doc, SimileAjax.urlPrefix + "scripts/signal.js?" + filenames.length);
123        }
124        else {
125            var included = new Array();
126            for (var i = 0; i < filenames.length; i++) 
127		included[i] = false; 
128
129            if (typeof window.SimileAjax_onLoad == "string") 
130		f = eval(window.SimileAjax_onLoad);
131            else if (typeof window.SimileAjax_onLoad == "function") 
132		f = window.SimileAjax_onLoad;
133
134            window.SimileAjax_onLoad = null;
135            includeJavascriptList(doc, urlPrefix, filenames, included, 0, f);
136        }
137    };
138
139    SimileAjax.includeCssFile = function(doc, url) {
140        if (doc.body == null) {
141            try {
142                doc.write("<link rel='stylesheet' href='" + url + "' type='text/css'/>");
143                return;
144            } catch (e) {
145                // fall through
146            }
147        }
148        
149        var link = doc.createElement("link");
150        link.setAttribute("rel", "stylesheet");
151        link.setAttribute("type", "text/css");
152        link.setAttribute("href", url);
153        getHead(doc).appendChild(link);
154    };
155    SimileAjax.includeCssFiles = function(doc, urlPrefix, filenames) {
156        for (var i = 0; i < filenames.length; i++) {
157            SimileAjax.includeCssFile(doc, urlPrefix + filenames[i]);
158        }
159    };
160    
161    /**
162     * Append into urls each string in suffixes after prefixing it with urlPrefix.
163     * @param {Array} urls
164     * @param {String} urlPrefix
165     * @param {Array} suffixes
166     */
167    SimileAjax.prefixURLs = function(urls, urlPrefix, suffixes) {
168        for (var i = 0; i < suffixes.length; i++) {
169            urls.push(urlPrefix + suffixes[i]);
170        }
171    };
172
173    /**
174     * Parse out the query parameters from a URL
175     * @param {String} url    the url to parse, or location.href if undefined
176     * @param {Object} to     optional object to extend with the parameters
177     * @param {Object} types  optional object mapping keys to value types
178     *        (String, Number, Boolean or Array, String by default)
179     * @return a key/value Object whose keys are the query parameter names
180     * @type Object
181     */
182    SimileAjax.parseURLParameters = function(url, to, types) {
183        to = to || {};
184        types = types || {};
185        
186        if (typeof url == "undefined") {
187            url = location.href;
188        }
189        var q = url.indexOf("?");
190        if (q < 0) {
191            return to;
192        }
193        url = (url+"#").slice(q+1, url.indexOf("#")); // toss the URL fragment
194        
195        var params = url.split("&"), param, parsed = {};
196        var decode = window.decodeURIComponent || unescape;
197        for (var i = 0; param = params[i]; i++) {
198            var eq = param.indexOf("=");
199            var name = decode(param.slice(0,eq));
200            var old = parsed[name];
201            var replacement = decode(param.slice(eq+1));
202            
203            if (typeof old == "undefined") {
204                old = [];
205            } else if (!(old instanceof Array)) {
206                old = [old];
207            }
208            parsed[name] = old.concat(replacement);
209        }
210        for (var i in parsed) {
211            if (!parsed.hasOwnProperty(i)) continue;
212            var type = types[i] || String;
213            var data = parsed[i];
214            if (!(data instanceof Array)) {
215                data = [data];
216            }
217            if (type === Boolean && data[0] == "false") {
218                to[i] = false; // because Boolean("false") === true
219            } else {
220                to[i] = type.apply(this, data);
221            }
222        }
223        return to;
224    };
225    
226    if (!isCompiled) {
227        (function() {
228            var javascriptFiles = [
229                "platform.js",
230                "debug.js",
231                "xmlhttp.js",
232                "json.js",
233                "dom.js",
234                "graphics.js",
235                "date-time.js",
236                "string.js",
237                "html.js",
238                "data-structure.js",
239                "units.js",
240                
241                "ajax.js",
242                "history.js",
243                "window-manager.js",
244                "remoteLog.js"
245            ];
246            var cssFiles = [
247                "graphics.css"
248            ];
249            if (!("jQuery" in window) && !("$" in window)) {
250//                javascriptFiles.unshift("jquery-1.4.2.min.js");
251		SimileAjax.includeJavascriptFile(document, "http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js");
252            }
253            
254
255            if (typeof SimileAjax_urlPrefix == "string") {
256                SimileAjax.urlPrefix = SimileAjax_urlPrefix;
257            } else {
258                var url = SimileAjax.findScript(document, "simile-ajax-api.js");
259                if (url == null) {
260                    SimileAjax.error = new Error("Failed to derive URL prefix for Simile Ajax API code files");
261                    return;
262                }
263
264                SimileAjax.urlPrefix = url.substr(0, url.indexOf("simile-ajax-api.js"));
265                SimileAjax.parseURLParameters(url, SimileAjax.params, { bundle: Boolean });
266            }
267
268
269
270            if (!isCompiled) {
271                if (SimileAjax.params.bundle) {
272                    SimileAjax.includeJavascriptFiles(document, SimileAjax.urlPrefix, [ "simile-ajax-bundle.js" ]);
273                } else {
274                    SimileAjax.includeJavascriptFiles(document, SimileAjax.urlPrefix + "scripts/", javascriptFiles);
275                }
276                SimileAjax.includeCssFiles(document, SimileAjax.urlPrefix + "styles/", cssFiles);
277            }
278            
279            SimileAjax.loaded = true;
280        })();
281    }
282}