/* ,---------------------------------------------------------. / wonderJSON is a lightweight javascript thingy ) / to easily load padded JSON from other domains. / / / ( Ioan Sameli, 04.2006 - 04.2007 / `--\ /--------------------------------------------------´ | / \| ` (")-''-(").___,.~-´'^`-._ \O_ O ) `-. ( ).`-.__.´) (_Y_.)/ ._ ) `._ `. `´-..-´ _,.`--´_,.-_/ /~-`_.´ ,´ (il).-'´ (li).´ ((!.-´ _________________________________________________ ________| |_______ \ | For more informations about all this, check | / \ | the official documentation! (not yet done) | / / |_________________________________________________| \ /__________) (________\ TODO * Check function.apply(arguments) */ // Fake trace function if it doesn't exist yet... if (typeof trace != 'function') trace = function(){}; /***********************/ /*** JSON module ***/ /***********************/ // The delay after wich a JSON request is considered as timed out, in milliseconds var delayTimeoutJSON = 5000; // Ioan Sameli, 10.05.2006 // Call an URL, and set the function that will handle the answer // params (object, optional): To provide the properties as argument wonderJSON = function(params) { // A method that will be called after a timeout if the request doesn't get any answer. this.onTimeOut = function() { // alert('The request ' + this.id + ' seems to have failed!'); } // If some properties have been given as parameter when creating the object, apply them // to the current object. Will override the previously set properties. if (params) for (var i in params) this[i] = params[i]; // To inject HTML code into the target, // rResult (string, optional): Some text or HTML to inject in the target. If null, will empty the target. // sTarget (string, optional): to specify another target than the default rTarget's request property. this.fillTarget = function(rResult, sTarget) { sTarget = sTarget || this.rTarget; if (!sTarget) return; if (e = document.getElementById(sTarget)) e.innerHTML = rResult; else trace('fillTarget: Element ' + sTarget + ' not found \n(' + this.rSource + ')', 'error'); } // Link the current request to another object, so we'll be able to address the request // directly, useful for example with JSON async callback functions. // TODO: maybe we should destroy the object once it's done, to avoid having many useless // expired properties in the parent (causing performance / memory problems ?) this.linkToParent = function(objParent) { // create a new property in the parent, with a unique ID based on the timestamp // Avoid having two similar ID by incrementing if the current ID is already used if (typeof objParent.wj == 'undefined') objParent.wj = {} this.id = new Date().getTime(); while ((typeof objParent.wj[this.id]) != 'undefined') this.id++; // Add the current request object to the parent, add the parent to the current request object objParent.wj[this.id] = this; this.parent = objParent; } // This method will set the function that the JSON result will call. // It can be specified by the argument or generated automatically. // Will return the name of the function (string) this.setJSONCallbackFunctionName = function(nameFunction) { // If no function name, simply return the 'path' to the current request's handleJSON if (! nameFunction) return 'wj[' + this.id + '].handleJSON'; // If a name has been specified in the argument, create a new function linked to the handleJSON var closure = this; window[nameFunction] = function(){closure.handleJSON.apply(closure, arguments);}; // window[nameFunction] = function(){closure.handleJSON((arguments.length > 1) ? arguments : arguments[0]);}; // window[nameFunction] = function(){closure.handleJSON.apply(arguments);}; } this.handleJSON = function() { // First, cancel the timeout warning, the answer is here! this.onTimeOut = function(){}; trace('wonderJSON.'+this.id+': answer received in ' + (new Date().getTime() - this.loadstart) + ' milliseconds, calling onAnswer function.'); // And forward the result to the onAnswer() function // If only one argument, pass it, otherwise, pass all the arguments at once // this.onAnswer((arguments.length > 1) ? arguments : arguments[0]); if (this.onAnswer) this.onAnswer.apply(this, arguments); } // For crossdomain request, include a script that will contain JSON data with a callBack function this.launch = function() { // If there are arguments in rSourceArguments, add them to the URL if (this.rSourceArguments) { var p = ''; for (var i in this.rSourceArguments) { var a = this.rSourceArguments[i]; if (typeof a != 'undefined' && a != null ) p = addParam(i, encodeURIComponent(this.rSourceArguments[i]), p); } this.rSource = this.rSource + '?' + p; } // Set the name of the callback function this.linkToParent(window); this.rCallback = this.setJSONCallbackFunctionName(this.rCallback); // TODO: this is a quite ugly hack! Could be done better. if (this.addCallbackArgument) this.rSource += this.addCallbackArgument + this.rCallback; // "Calling" the JSON by adding a script to the document
loadScript(this.rSource, 'UTF-8'); trace('wonderJSON.'+this.id+': load ' + this.rSource + ''); this.loadstart = new Date().getTime(); // Manage the timeout: call the timeout function with a timeout if the onAnswer function is set var closure = this; if ('function' == typeof this.onAnswer) window.setTimeout(function(){closure.onTimeOut();}, delayTimeoutJSON); } } /****************************/ /*** Useful functions ***/ /****************************/ // Load a javascript file by appending a