summaryrefslogtreecommitdiff
path: root/js/dojo-1.6/dojox/rpc
diff options
context:
space:
mode:
Diffstat (limited to 'js/dojo-1.6/dojox/rpc')
-rw-r--r--js/dojo-1.6/dojox/rpc/Client.js34
-rw-r--r--js/dojo-1.6/dojox/rpc/Client.xd.js38
-rw-r--r--js/dojo-1.6/dojox/rpc/JsonRPC.js67
-rw-r--r--js/dojo-1.6/dojox/rpc/JsonRPC.xd.js72
-rw-r--r--js/dojo-1.6/dojox/rpc/JsonRest.js463
-rw-r--r--js/dojo-1.6/dojox/rpc/JsonRest.xd.js469
-rw-r--r--js/dojo-1.6/dojox/rpc/OfflineRest.js269
-rw-r--r--js/dojo-1.6/dojox/rpc/OfflineRest.xd.js276
-rw-r--r--js/dojo-1.6/dojox/rpc/ProxiedPath.js41
-rw-r--r--js/dojo-1.6/dojox/rpc/ProxiedPath.xd.js46
-rw-r--r--js/dojo-1.6/dojox/rpc/README56
-rw-r--r--js/dojo-1.6/dojox/rpc/Rest.js153
-rw-r--r--js/dojo-1.6/dojox/rpc/Rest.xd.js157
-rw-r--r--js/dojo-1.6/dojox/rpc/SMDLibrary/dojo-api.smd30
-rw-r--r--js/dojo-1.6/dojox/rpc/SMDLibrary/friendfeed.smd49
-rw-r--r--js/dojo-1.6/dojox/rpc/SMDLibrary/geonames.smd263
-rw-r--r--js/dojo-1.6/dojox/rpc/SMDLibrary/google.smd129
-rw-r--r--js/dojo-1.6/dojox/rpc/SMDLibrary/twitter.smd35
-rw-r--r--js/dojo-1.6/dojox/rpc/SMDLibrary/wikipedia.smd49
-rw-r--r--js/dojo-1.6/dojox/rpc/SMDLibrary/yahoo.smd519
-rw-r--r--js/dojo-1.6/dojox/rpc/Service.js332
-rw-r--r--js/dojo-1.6/dojox/rpc/Service.xd.js337
22 files changed, 3884 insertions, 0 deletions
diff --git a/js/dojo-1.6/dojox/rpc/Client.js b/js/dojo-1.6/dojox/rpc/Client.js
new file mode 100644
index 0000000..67a29cd
--- /dev/null
+++ b/js/dojo-1.6/dojox/rpc/Client.js
@@ -0,0 +1,34 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.rpc.Client"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.rpc.Client"] = true;
+dojo.provide("dojox.rpc.Client");
+
+
+// Provide extra headers for robust client and server communication
+(function() {
+ dojo._defaultXhr = dojo.xhr;
+ dojo.xhr = function(method,args){
+ var headers = args.headers = args.headers || {};
+ // set the client id, this can be used by servers to maintain state information with the
+ // a specific client. Many servers rely on sessions for this, but sessions are shared
+ // between tabs/windows, so this is not appropriate for application state, it
+ // really only useful for storing user authentication
+ headers["Client-Id"] = dojox.rpc.Client.clientId;
+ // set the sequence id. HTTP is non-deterministic, message can arrive at the server
+ // out of order. In complex Ajax applications, it may be more to ensure that messages
+ // can be properly sequenced deterministically. This applies a sequency id to each
+ // XHR request so that the server can order them.
+ headers["Seq-Id"] = dojox._reqSeqId = (dojox._reqSeqId||0)+1;
+ return dojo._defaultXhr.apply(dojo,arguments);
+ }
+})();
+// initiate the client id to a good random number
+dojox.rpc.Client.clientId = (Math.random() + '').substring(2,14) + (new Date().getTime() + '').substring(8,13);
+
+}
diff --git a/js/dojo-1.6/dojox/rpc/Client.xd.js b/js/dojo-1.6/dojox/rpc/Client.xd.js
new file mode 100644
index 0000000..1fab98f
--- /dev/null
+++ b/js/dojo-1.6/dojox/rpc/Client.xd.js
@@ -0,0 +1,38 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.rpc.Client"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.rpc.Client"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.rpc.Client"] = true;
+dojo.provide("dojox.rpc.Client");
+
+
+// Provide extra headers for robust client and server communication
+(function() {
+ dojo._defaultXhr = dojo.xhr;
+ dojo.xhr = function(method,args){
+ var headers = args.headers = args.headers || {};
+ // set the client id, this can be used by servers to maintain state information with the
+ // a specific client. Many servers rely on sessions for this, but sessions are shared
+ // between tabs/windows, so this is not appropriate for application state, it
+ // really only useful for storing user authentication
+ headers["Client-Id"] = dojox.rpc.Client.clientId;
+ // set the sequence id. HTTP is non-deterministic, message can arrive at the server
+ // out of order. In complex Ajax applications, it may be more to ensure that messages
+ // can be properly sequenced deterministically. This applies a sequency id to each
+ // XHR request so that the server can order them.
+ headers["Seq-Id"] = dojox._reqSeqId = (dojox._reqSeqId||0)+1;
+ return dojo._defaultXhr.apply(dojo,arguments);
+ }
+})();
+// initiate the client id to a good random number
+dojox.rpc.Client.clientId = (Math.random() + '').substring(2,14) + (new Date().getTime() + '').substring(8,13);
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/rpc/JsonRPC.js b/js/dojo-1.6/dojox/rpc/JsonRPC.js
new file mode 100644
index 0000000..2d5aabf
--- /dev/null
+++ b/js/dojo-1.6/dojox/rpc/JsonRPC.js
@@ -0,0 +1,67 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.rpc.JsonRPC"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.rpc.JsonRPC"] = true;
+dojo.provide("dojox.rpc.JsonRPC");
+dojo.require("dojox.rpc.Service");
+
+
+
+ function jsonRpcEnvelope(version){
+ return {
+ serialize: function(smd, method, data, options){
+ //not converted to json it self. This will be done, if
+ //appropriate, at the transport level
+
+ var d = {
+ id: this._requestId++,
+ method: method.name,
+ params: data
+ };
+ if(version){
+ d.jsonrpc = version;
+ }
+ return {
+ data: dojo.toJson(d),
+ handleAs:'json',
+ contentType: 'application/json',
+ transport:"POST"
+ };
+ },
+
+ deserialize: function(obj){
+ if ('Error' == obj.name){
+ obj = dojo.fromJson(obj.responseText);
+ }
+ if(obj.error) {
+ var e = new Error(obj.error.message || obj.error);
+ e._rpcErrorObject = obj.error;
+ return e;
+ }
+ return obj.result;
+ }
+ };
+ }
+ dojox.rpc.envelopeRegistry.register(
+ "JSON-RPC-1.0",
+ function(str){
+ return str == "JSON-RPC-1.0";
+ },
+ dojo.mixin({namedParams:false},jsonRpcEnvelope()) // 1.0 will only work with ordered params
+ );
+
+ dojox.rpc.envelopeRegistry.register(
+ "JSON-RPC-2.0",
+ function(str){
+ return str == "JSON-RPC-2.0";
+ },
+ jsonRpcEnvelope("2.0")
+ );
+
+
+}
diff --git a/js/dojo-1.6/dojox/rpc/JsonRPC.xd.js b/js/dojo-1.6/dojox/rpc/JsonRPC.xd.js
new file mode 100644
index 0000000..84e3619
--- /dev/null
+++ b/js/dojo-1.6/dojox/rpc/JsonRPC.xd.js
@@ -0,0 +1,72 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.rpc.JsonRPC"],
+["require", "dojox.rpc.Service"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.rpc.JsonRPC"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.rpc.JsonRPC"] = true;
+dojo.provide("dojox.rpc.JsonRPC");
+dojo.require("dojox.rpc.Service");
+
+
+
+ function jsonRpcEnvelope(version){
+ return {
+ serialize: function(smd, method, data, options){
+ //not converted to json it self. This will be done, if
+ //appropriate, at the transport level
+
+ var d = {
+ id: this._requestId++,
+ method: method.name,
+ params: data
+ };
+ if(version){
+ d.jsonrpc = version;
+ }
+ return {
+ data: dojo.toJson(d),
+ handleAs:'json',
+ contentType: 'application/json',
+ transport:"POST"
+ };
+ },
+
+ deserialize: function(obj){
+ if ('Error' == obj.name){
+ obj = dojo.fromJson(obj.responseText);
+ }
+ if(obj.error) {
+ var e = new Error(obj.error.message || obj.error);
+ e._rpcErrorObject = obj.error;
+ return e;
+ }
+ return obj.result;
+ }
+ };
+ }
+ dojox.rpc.envelopeRegistry.register(
+ "JSON-RPC-1.0",
+ function(str){
+ return str == "JSON-RPC-1.0";
+ },
+ dojo.mixin({namedParams:false},jsonRpcEnvelope()) // 1.0 will only work with ordered params
+ );
+
+ dojox.rpc.envelopeRegistry.register(
+ "JSON-RPC-2.0",
+ function(str){
+ return str == "JSON-RPC-2.0";
+ },
+ jsonRpcEnvelope("2.0")
+ );
+
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/rpc/JsonRest.js b/js/dojo-1.6/dojox/rpc/JsonRest.js
new file mode 100644
index 0000000..5164d8b
--- /dev/null
+++ b/js/dojo-1.6/dojox/rpc/JsonRest.js
@@ -0,0 +1,463 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.rpc.JsonRest"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.rpc.JsonRest"] = true;
+dojo.provide("dojox.rpc.JsonRest");
+dojo.require("dojox.json.ref");
+dojo.require("dojox.rpc.Rest");
+
+
+ var dirtyObjects = [];
+ var Rest = dojox.rpc.Rest;
+ var jr;
+ function resolveJson(service, deferred, value, defaultId){
+ var timeStamp = deferred.ioArgs && deferred.ioArgs.xhr && deferred.ioArgs.xhr.getResponseHeader("Last-Modified");
+ if(timeStamp && Rest._timeStamps){
+ Rest._timeStamps[defaultId] = timeStamp;
+ }
+ var hrefProperty = service._schema && service._schema.hrefProperty;
+ if(hrefProperty){
+ dojox.json.ref.refAttribute = hrefProperty;
+ }
+ value = value && dojox.json.ref.resolveJson(value, {
+ defaultId: defaultId,
+ index: Rest._index,
+ timeStamps: timeStamp && Rest._timeStamps,
+ time: timeStamp,
+ idPrefix: service.servicePath.replace(/[^\/]*$/,''),
+ idAttribute: jr.getIdAttribute(service),
+ schemas: jr.schemas,
+ loader: jr._loader,
+ idAsRef: service.idAsRef,
+ assignAbsoluteIds: true
+ });
+ dojox.json.ref.refAttribute = "$ref";
+ return value;
+ }
+ jr = dojox.rpc.JsonRest={
+ serviceClass: dojox.rpc.Rest,
+ conflictDateHeader: "If-Unmodified-Since",
+ commit: function(kwArgs){
+ // summary:
+ // Saves the dirty data using REST Ajax methods
+
+ kwArgs = kwArgs || {};
+ var actions = [];
+ var alreadyRecorded = {};
+ var savingObjects = [];
+ for(var i = 0; i < dirtyObjects.length; i++){
+ var dirty = dirtyObjects[i];
+ var object = dirty.object;
+ var old = dirty.old;
+ var append = false;
+ if(!(kwArgs.service && (object || old) &&
+ (object || old).__id.indexOf(kwArgs.service.servicePath)) && dirty.save){
+ delete object.__isDirty;
+ if(object){
+ if(old){
+ // changed object
+ var pathParts;
+ if((pathParts = object.__id.match(/(.*)#.*/))){ // it is a path reference
+ // this means it is a sub object, we must go to the parent object and save it
+ object = Rest._index[pathParts[1]];
+ }
+ if(!(object.__id in alreadyRecorded)){// if it has already been saved, we don't want to repeat it
+ // record that we are saving
+ alreadyRecorded[object.__id] = object;
+ if(kwArgs.incrementalUpdates
+ && !pathParts){ // I haven't figured out how we would do incremental updates on sub-objects yet
+ // make an incremental update using a POST
+ var incremental = (typeof kwArgs.incrementalUpdates == 'function' ?
+ kwArgs.incrementalUpdates : function(){
+ incremental = {};
+ for(var j in object){
+ if(object.hasOwnProperty(j)){
+ if(object[j] !== old[j]){
+ incremental[j] = object[j];
+ }
+ }else if(old.hasOwnProperty(j)){
+ // we can't use incremental updates to remove properties
+ return null;
+ }
+ }
+ return incremental;
+ })(object, old);
+ }
+
+ if(incremental){
+ actions.push({method:"post",target:object, content: incremental});
+ }
+ else{
+ actions.push({method:"put",target:object,content:object});
+ }
+ }
+ }else{
+ // new object
+ var service = jr.getServiceAndId(object.__id).service;
+ var idAttribute = jr.getIdAttribute(service);
+ if((idAttribute in object) && !kwArgs.alwaysPostNewItems){
+ // if the id attribute is specified, then we should know the location
+ actions.push({method:"put",target:object, content:object});
+ }else{
+ actions.push({method:"post",target:{__id:service.servicePath},
+ content:object});
+ }
+ }
+ }else if(old){
+ // deleted object
+ actions.push({method:"delete",target:old});
+ }//else{ this would happen if an object is created and then deleted, don't do anything
+ savingObjects.push(dirty);
+ dirtyObjects.splice(i--,1);
+ }
+ }
+ dojo.connect(kwArgs,"onError",function(){
+ if(kwArgs.revertOnError !== false){
+ var postCommitDirtyObjects = dirtyObjects;
+ dirtyObjects = savingObjects;
+ var numDirty = 0; // make sure this does't do anything if it is called again
+ jr.revert(); // revert if there was an error
+ dirtyObjects = postCommitDirtyObjects;
+ }
+ else{
+ dirtyObjects = dirtyObject.concat(savingObjects);
+ }
+ });
+ jr.sendToServer(actions, kwArgs);
+ return actions;
+ },
+ sendToServer: function(actions, kwArgs){
+ var xhrSendId;
+ var plainXhr = dojo.xhr;
+ var left = actions.length;// this is how many changes are remaining to be received from the server
+ var i, contentLocation;
+ var timeStamp;
+ var conflictDateHeader = this.conflictDateHeader;
+ // add headers for extra information
+ dojo.xhr = function(method,args){
+ // keep the transaction open as we send requests
+ args.headers = args.headers || {};
+ // the last one should commit the transaction
+ args.headers['Transaction'] = actions.length - 1 == i ? "commit" : "open";
+ if(conflictDateHeader && timeStamp){
+ args.headers[conflictDateHeader] = timeStamp;
+ }
+ if(contentLocation){
+ args.headers['Content-ID'] = '<' + contentLocation + '>';
+ }
+ return plainXhr.apply(dojo,arguments);
+ };
+ for(i =0; i < actions.length;i++){ // iterate through the actions to execute
+ var action = actions[i];
+ dojox.rpc.JsonRest._contentId = action.content && action.content.__id; // this is used by OfflineRest
+ var isPost = action.method == 'post';
+ timeStamp = action.method == 'put' && Rest._timeStamps[action.content.__id];
+ if(timeStamp){
+ // update it now
+ Rest._timeStamps[action.content.__id] = (new Date()) + '';
+ }
+ // send the content location to the server
+ contentLocation = isPost && dojox.rpc.JsonRest._contentId;
+ var serviceAndId = jr.getServiceAndId(action.target.__id);
+ var service = serviceAndId.service;
+ var dfd = action.deferred = service[action.method](
+ serviceAndId.id.replace(/#/,''), // if we are using references, we need eliminate #
+ dojox.json.ref.toJson(action.content, false, service.servicePath, true)
+ );
+ (function(object, dfd, service){
+ dfd.addCallback(function(value){
+ try{
+ // Implements id assignment per the HTTP specification
+ var newId = dfd.ioArgs.xhr && dfd.ioArgs.xhr.getResponseHeader("Location");
+ //TODO: match URLs if the servicePath is relative...
+ if(newId){
+ // if the path starts in the middle of an absolute URL for Location, we will use the just the path part
+ var startIndex = newId.match(/(^\w+:\/\/)/) && newId.indexOf(service.servicePath);
+ newId = startIndex > 0 ? newId.substring(startIndex) : (service.servicePath + newId).
+ // now do simple relative URL resolution in case of a relative URL.
+ replace(/^(.*\/)?(\w+:\/\/)|[^\/\.]+\/\.\.\/|^.*\/(\/)/,'$2$3');
+ object.__id = newId;
+ Rest._index[newId] = object;
+ }
+ value = resolveJson(service, dfd, value, object && object.__id);
+ }catch(e){}
+ if(!(--left)){
+ if(kwArgs.onComplete){
+ kwArgs.onComplete.call(kwArgs.scope, actions);
+ }
+ }
+ return value;
+ });
+ })(action.content, dfd, service);
+
+ dfd.addErrback(function(value){
+
+ // on an error we want to revert, first we want to separate any changes that were made since the commit
+ left = -1; // first make sure that success isn't called
+ kwArgs.onError.call(kwArgs.scope, value);
+ });
+ }
+ // revert back to the normal XHR handler
+ dojo.xhr = plainXhr;
+
+ },
+ getDirtyObjects: function(){
+ return dirtyObjects;
+ },
+ revert: function(service){
+ // summary:
+ // Reverts all the changes made to JSON/REST data
+ for(var i = dirtyObjects.length; i > 0;){
+ i--;
+ var dirty = dirtyObjects[i];
+ var object = dirty.object;
+ var old = dirty.old;
+ var store = dojox.data._getStoreForItem(object || old);
+
+ if(!(service && (object || old) &&
+ (object || old).__id.indexOf(service.servicePath))){
+ // if we are in the specified store or if this is a global revert
+ if(object && old){
+ // changed
+ for(var j in old){
+ if(old.hasOwnProperty(j) && object[j] !== old[j]){
+ if(store){
+ store.onSet(object, j, object[j], old[j]);
+ }
+ object[j] = old[j];
+ }
+ }
+ for(j in object){
+ if(!old.hasOwnProperty(j)){
+ if(store){
+ store.onSet(object, j, object[j]);
+ }
+ delete object[j];
+ }
+ }
+ }else if(!old){
+ // was an addition, remove it
+ if(store){
+ store.onDelete(object);
+ }
+ }else{
+ // was a deletion, we will add it back
+ if(store){
+ store.onNew(old);
+ }
+ }
+ delete (object || old).__isDirty;
+ dirtyObjects.splice(i, 1);
+ }
+ }
+ },
+ changing: function(object,_deleting){
+ // summary:
+ // adds an object to the list of dirty objects. This object
+ // contains a reference to the object itself as well as a
+ // cloned and trimmed version of old object for use with
+ // revert.
+ if(!object.__id){
+ return;
+ }
+ object.__isDirty = true;
+ //if an object is already in the list of dirty objects, don't add it again
+ //or it will overwrite the premodification data set.
+ for(var i=0; i<dirtyObjects.length; i++){
+ var dirty = dirtyObjects[i];
+ if(object==dirty.object){
+ if(_deleting){
+ // we are deleting, no object is an indicator of deletiong
+ dirty.object = false;
+ if(!this._saveNotNeeded){
+ dirty.save = true;
+ }
+ }
+ return;
+ }
+ }
+ var old = object instanceof Array ? [] : {};
+ for(i in object){
+ if(object.hasOwnProperty(i)){
+ old[i] = object[i];
+ }
+ }
+ dirtyObjects.push({object: !_deleting && object, old: old, save: !this._saveNotNeeded});
+ },
+ deleteObject: function(object){
+ // summary:
+ // deletes an object
+ // object:
+ // object to delete
+ this.changing(object,true);
+ },
+ getConstructor: function(/*Function|String*/service, schema){
+ // summary:
+ // Creates or gets a constructor for objects from this service
+ if(typeof service == 'string'){
+ var servicePath = service;
+ service = new dojox.rpc.Rest(service,true);
+ this.registerService(service, servicePath, schema);
+ }
+ if(service._constructor){
+ return service._constructor;
+ }
+ service._constructor = function(data){
+ // summary:
+ // creates a new object for this table
+ //
+ // data:
+ // object to mixed in
+ var self = this;
+ var args = arguments;
+ var properties;
+ var initializeCalled;
+ function addDefaults(schema){
+ if(schema){
+ addDefaults(schema['extends']);
+ properties = schema.properties;
+ for(var i in properties){
+ var propDef = properties[i];
+ if(propDef && (typeof propDef == 'object') && ("default" in propDef)){
+ self[i] = propDef["default"];
+ }
+ }
+ }
+ if(schema && schema.prototype && schema.prototype.initialize){
+ initializeCalled = true;
+ schema.prototype.initialize.apply(self, args);
+ }
+ }
+ addDefaults(service._schema);
+ if(!initializeCalled && data && typeof data == 'object'){
+ dojo.mixin(self,data);
+ }
+ var idAttribute = jr.getIdAttribute(service);
+ Rest._index[this.__id = this.__clientId =
+ service.servicePath + (this[idAttribute] ||
+ Math.random().toString(16).substring(2,14) + '@' + ((dojox.rpc.Client && dojox.rpc.Client.clientId) || "client"))] = this;
+ if(dojox.json.schema && properties){
+ dojox.json.schema.mustBeValid(dojox.json.schema.validate(this, service._schema));
+ }
+ dirtyObjects.push({object:this, save: true});
+ };
+ return dojo.mixin(service._constructor, service._schema, {load:service});
+ },
+ fetch: function(absoluteId){
+ // summary:
+ // Fetches a resource by an absolute path/id and returns a dojo.Deferred.
+ var serviceAndId = jr.getServiceAndId(absoluteId);
+ return this.byId(serviceAndId.service,serviceAndId.id);
+ },
+ getIdAttribute: function(service){
+ // summary:
+ // Return the ids attribute used by this service (based on it's schema).
+ // Defaults to "id", if not other id is defined
+ var schema = service._schema;
+ var idAttr;
+ if(schema){
+ if(!(idAttr = schema._idAttr)){
+ for(var i in schema.properties){
+ if(schema.properties[i].identity || (schema.properties[i].link == "self")){
+ schema._idAttr = idAttr = i;
+ }
+ }
+ }
+ }
+ return idAttr || 'id';
+ },
+ getServiceAndId: function(/*String*/absoluteId){
+ // summary:
+ // Returns the REST service and the local id for the given absolute id. The result
+ // is returned as an object with a service property and an id property
+ // absoluteId:
+ // This is the absolute id of the object
+ var serviceName = '';
+
+ for(var service in jr.services){
+ if((absoluteId.substring(0, service.length) == service) && (service.length >= serviceName.length)){
+ serviceName = service;
+ }
+ }
+ if (serviceName){
+ return {service: jr.services[serviceName], id:absoluteId.substring(serviceName.length)};
+ }
+ var parts = absoluteId.match(/^(.*\/)([^\/]*)$/);
+ return {service: new jr.serviceClass(parts[1], true), id:parts[2]};
+ },
+ services:{},
+ schemas:{},
+ registerService: function(/*Function*/ service, /*String*/ servicePath, /*Object?*/ schema){
+ // summary:
+ // Registers a service for as a JsonRest service, mapping it to a path and schema
+ // service:
+ // This is the service to register
+ // servicePath:
+ // This is the path that is used for all the ids for the objects returned by service
+ // schema:
+ // This is a JSON Schema object to associate with objects returned by this service
+ servicePath = service.servicePath = servicePath || service.servicePath;
+ service._schema = jr.schemas[servicePath] = schema || service._schema || {};
+ jr.services[servicePath] = service;
+ },
+ byId: function(service, id){
+ // if caching is allowed, we look in the cache for the result
+ var deferred, result = Rest._index[(service.servicePath || '') + id];
+ if(result && !result._loadObject){// cache hit
+ deferred = new dojo.Deferred();
+ deferred.callback(result);
+ return deferred;
+ }
+ return this.query(service, id);
+ },
+ query: function(service, id, args){
+ var deferred = service(id, args);
+
+ deferred.addCallback(function(result){
+ if(result.nodeType && result.cloneNode){
+ // return immediately if it is an XML document
+ return result;
+ }
+ return resolveJson(service, deferred, result, typeof id != 'string' || (args && (args.start || args.count)) ? undefined: id);
+ });
+ return deferred;
+ },
+ _loader: function(callback){
+ // load a lazy object
+ var serviceAndId = jr.getServiceAndId(this.__id);
+ var self = this;
+ jr.query(serviceAndId.service, serviceAndId.id).addBoth(function(result){
+ // if they are the same this means an object was loaded, otherwise it
+ // might be a primitive that was loaded or maybe an error
+ if(result == self){
+ // we can clear the flag, so it is a loaded object
+ delete result.$ref;
+ delete result._loadObject;
+ }else{
+ // it is probably a primitive value, we can't change the identity of an object to
+ // the loaded value, so we will keep it lazy, but define the lazy loader to always
+ // return the loaded value
+ self._loadObject = function(callback){
+ callback(result);
+ };
+ }
+ callback(result);
+ });
+ },
+ isDirty: function(item){
+ // summary
+ // returns true if the item is marked as dirty or true if there are any dirty items
+ if(!item){
+ return !!dirtyObjects.length;
+ }
+ return item.__isDirty;
+ }
+
+ };
+
+}
diff --git a/js/dojo-1.6/dojox/rpc/JsonRest.xd.js b/js/dojo-1.6/dojox/rpc/JsonRest.xd.js
new file mode 100644
index 0000000..1044928
--- /dev/null
+++ b/js/dojo-1.6/dojox/rpc/JsonRest.xd.js
@@ -0,0 +1,469 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.rpc.JsonRest"],
+["require", "dojox.json.ref"],
+["require", "dojox.rpc.Rest"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.rpc.JsonRest"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.rpc.JsonRest"] = true;
+dojo.provide("dojox.rpc.JsonRest");
+dojo.require("dojox.json.ref");
+dojo.require("dojox.rpc.Rest");
+
+
+ var dirtyObjects = [];
+ var Rest = dojox.rpc.Rest;
+ var jr;
+ function resolveJson(service, deferred, value, defaultId){
+ var timeStamp = deferred.ioArgs && deferred.ioArgs.xhr && deferred.ioArgs.xhr.getResponseHeader("Last-Modified");
+ if(timeStamp && Rest._timeStamps){
+ Rest._timeStamps[defaultId] = timeStamp;
+ }
+ var hrefProperty = service._schema && service._schema.hrefProperty;
+ if(hrefProperty){
+ dojox.json.ref.refAttribute = hrefProperty;
+ }
+ value = value && dojox.json.ref.resolveJson(value, {
+ defaultId: defaultId,
+ index: Rest._index,
+ timeStamps: timeStamp && Rest._timeStamps,
+ time: timeStamp,
+ idPrefix: service.servicePath.replace(/[^\/]*$/,''),
+ idAttribute: jr.getIdAttribute(service),
+ schemas: jr.schemas,
+ loader: jr._loader,
+ idAsRef: service.idAsRef,
+ assignAbsoluteIds: true
+ });
+ dojox.json.ref.refAttribute = "$ref";
+ return value;
+ }
+ jr = dojox.rpc.JsonRest={
+ serviceClass: dojox.rpc.Rest,
+ conflictDateHeader: "If-Unmodified-Since",
+ commit: function(kwArgs){
+ // summary:
+ // Saves the dirty data using REST Ajax methods
+
+ kwArgs = kwArgs || {};
+ var actions = [];
+ var alreadyRecorded = {};
+ var savingObjects = [];
+ for(var i = 0; i < dirtyObjects.length; i++){
+ var dirty = dirtyObjects[i];
+ var object = dirty.object;
+ var old = dirty.old;
+ var append = false;
+ if(!(kwArgs.service && (object || old) &&
+ (object || old).__id.indexOf(kwArgs.service.servicePath)) && dirty.save){
+ delete object.__isDirty;
+ if(object){
+ if(old){
+ // changed object
+ var pathParts;
+ if((pathParts = object.__id.match(/(.*)#.*/))){ // it is a path reference
+ // this means it is a sub object, we must go to the parent object and save it
+ object = Rest._index[pathParts[1]];
+ }
+ if(!(object.__id in alreadyRecorded)){// if it has already been saved, we don't want to repeat it
+ // record that we are saving
+ alreadyRecorded[object.__id] = object;
+ if(kwArgs.incrementalUpdates
+ && !pathParts){ // I haven't figured out how we would do incremental updates on sub-objects yet
+ // make an incremental update using a POST
+ var incremental = (typeof kwArgs.incrementalUpdates == 'function' ?
+ kwArgs.incrementalUpdates : function(){
+ incremental = {};
+ for(var j in object){
+ if(object.hasOwnProperty(j)){
+ if(object[j] !== old[j]){
+ incremental[j] = object[j];
+ }
+ }else if(old.hasOwnProperty(j)){
+ // we can't use incremental updates to remove properties
+ return null;
+ }
+ }
+ return incremental;
+ })(object, old);
+ }
+
+ if(incremental){
+ actions.push({method:"post",target:object, content: incremental});
+ }
+ else{
+ actions.push({method:"put",target:object,content:object});
+ }
+ }
+ }else{
+ // new object
+ var service = jr.getServiceAndId(object.__id).service;
+ var idAttribute = jr.getIdAttribute(service);
+ if((idAttribute in object) && !kwArgs.alwaysPostNewItems){
+ // if the id attribute is specified, then we should know the location
+ actions.push({method:"put",target:object, content:object});
+ }else{
+ actions.push({method:"post",target:{__id:service.servicePath},
+ content:object});
+ }
+ }
+ }else if(old){
+ // deleted object
+ actions.push({method:"delete",target:old});
+ }//else{ this would happen if an object is created and then deleted, don't do anything
+ savingObjects.push(dirty);
+ dirtyObjects.splice(i--,1);
+ }
+ }
+ dojo.connect(kwArgs,"onError",function(){
+ if(kwArgs.revertOnError !== false){
+ var postCommitDirtyObjects = dirtyObjects;
+ dirtyObjects = savingObjects;
+ var numDirty = 0; // make sure this does't do anything if it is called again
+ jr.revert(); // revert if there was an error
+ dirtyObjects = postCommitDirtyObjects;
+ }
+ else{
+ dirtyObjects = dirtyObject.concat(savingObjects);
+ }
+ });
+ jr.sendToServer(actions, kwArgs);
+ return actions;
+ },
+ sendToServer: function(actions, kwArgs){
+ var xhrSendId;
+ var plainXhr = dojo.xhr;
+ var left = actions.length;// this is how many changes are remaining to be received from the server
+ var i, contentLocation;
+ var timeStamp;
+ var conflictDateHeader = this.conflictDateHeader;
+ // add headers for extra information
+ dojo.xhr = function(method,args){
+ // keep the transaction open as we send requests
+ args.headers = args.headers || {};
+ // the last one should commit the transaction
+ args.headers['Transaction'] = actions.length - 1 == i ? "commit" : "open";
+ if(conflictDateHeader && timeStamp){
+ args.headers[conflictDateHeader] = timeStamp;
+ }
+ if(contentLocation){
+ args.headers['Content-ID'] = '<' + contentLocation + '>';
+ }
+ return plainXhr.apply(dojo,arguments);
+ };
+ for(i =0; i < actions.length;i++){ // iterate through the actions to execute
+ var action = actions[i];
+ dojox.rpc.JsonRest._contentId = action.content && action.content.__id; // this is used by OfflineRest
+ var isPost = action.method == 'post';
+ timeStamp = action.method == 'put' && Rest._timeStamps[action.content.__id];
+ if(timeStamp){
+ // update it now
+ Rest._timeStamps[action.content.__id] = (new Date()) + '';
+ }
+ // send the content location to the server
+ contentLocation = isPost && dojox.rpc.JsonRest._contentId;
+ var serviceAndId = jr.getServiceAndId(action.target.__id);
+ var service = serviceAndId.service;
+ var dfd = action.deferred = service[action.method](
+ serviceAndId.id.replace(/#/,''), // if we are using references, we need eliminate #
+ dojox.json.ref.toJson(action.content, false, service.servicePath, true)
+ );
+ (function(object, dfd, service){
+ dfd.addCallback(function(value){
+ try{
+ // Implements id assignment per the HTTP specification
+ var newId = dfd.ioArgs.xhr && dfd.ioArgs.xhr.getResponseHeader("Location");
+ //TODO: match URLs if the servicePath is relative...
+ if(newId){
+ // if the path starts in the middle of an absolute URL for Location, we will use the just the path part
+ var startIndex = newId.match(/(^\w+:\/\/)/) && newId.indexOf(service.servicePath);
+ newId = startIndex > 0 ? newId.substring(startIndex) : (service.servicePath + newId).
+ // now do simple relative URL resolution in case of a relative URL.
+ replace(/^(.*\/)?(\w+:\/\/)|[^\/\.]+\/\.\.\/|^.*\/(\/)/,'$2$3');
+ object.__id = newId;
+ Rest._index[newId] = object;
+ }
+ value = resolveJson(service, dfd, value, object && object.__id);
+ }catch(e){}
+ if(!(--left)){
+ if(kwArgs.onComplete){
+ kwArgs.onComplete.call(kwArgs.scope, actions);
+ }
+ }
+ return value;
+ });
+ })(action.content, dfd, service);
+
+ dfd.addErrback(function(value){
+
+ // on an error we want to revert, first we want to separate any changes that were made since the commit
+ left = -1; // first make sure that success isn't called
+ kwArgs.onError.call(kwArgs.scope, value);
+ });
+ }
+ // revert back to the normal XHR handler
+ dojo.xhr = plainXhr;
+
+ },
+ getDirtyObjects: function(){
+ return dirtyObjects;
+ },
+ revert: function(service){
+ // summary:
+ // Reverts all the changes made to JSON/REST data
+ for(var i = dirtyObjects.length; i > 0;){
+ i--;
+ var dirty = dirtyObjects[i];
+ var object = dirty.object;
+ var old = dirty.old;
+ var store = dojox.data._getStoreForItem(object || old);
+
+ if(!(service && (object || old) &&
+ (object || old).__id.indexOf(service.servicePath))){
+ // if we are in the specified store or if this is a global revert
+ if(object && old){
+ // changed
+ for(var j in old){
+ if(old.hasOwnProperty(j) && object[j] !== old[j]){
+ if(store){
+ store.onSet(object, j, object[j], old[j]);
+ }
+ object[j] = old[j];
+ }
+ }
+ for(j in object){
+ if(!old.hasOwnProperty(j)){
+ if(store){
+ store.onSet(object, j, object[j]);
+ }
+ delete object[j];
+ }
+ }
+ }else if(!old){
+ // was an addition, remove it
+ if(store){
+ store.onDelete(object);
+ }
+ }else{
+ // was a deletion, we will add it back
+ if(store){
+ store.onNew(old);
+ }
+ }
+ delete (object || old).__isDirty;
+ dirtyObjects.splice(i, 1);
+ }
+ }
+ },
+ changing: function(object,_deleting){
+ // summary:
+ // adds an object to the list of dirty objects. This object
+ // contains a reference to the object itself as well as a
+ // cloned and trimmed version of old object for use with
+ // revert.
+ if(!object.__id){
+ return;
+ }
+ object.__isDirty = true;
+ //if an object is already in the list of dirty objects, don't add it again
+ //or it will overwrite the premodification data set.
+ for(var i=0; i<dirtyObjects.length; i++){
+ var dirty = dirtyObjects[i];
+ if(object==dirty.object){
+ if(_deleting){
+ // we are deleting, no object is an indicator of deletiong
+ dirty.object = false;
+ if(!this._saveNotNeeded){
+ dirty.save = true;
+ }
+ }
+ return;
+ }
+ }
+ var old = object instanceof Array ? [] : {};
+ for(i in object){
+ if(object.hasOwnProperty(i)){
+ old[i] = object[i];
+ }
+ }
+ dirtyObjects.push({object: !_deleting && object, old: old, save: !this._saveNotNeeded});
+ },
+ deleteObject: function(object){
+ // summary:
+ // deletes an object
+ // object:
+ // object to delete
+ this.changing(object,true);
+ },
+ getConstructor: function(/*Function|String*/service, schema){
+ // summary:
+ // Creates or gets a constructor for objects from this service
+ if(typeof service == 'string'){
+ var servicePath = service;
+ service = new dojox.rpc.Rest(service,true);
+ this.registerService(service, servicePath, schema);
+ }
+ if(service._constructor){
+ return service._constructor;
+ }
+ service._constructor = function(data){
+ // summary:
+ // creates a new object for this table
+ //
+ // data:
+ // object to mixed in
+ var self = this;
+ var args = arguments;
+ var properties;
+ var initializeCalled;
+ function addDefaults(schema){
+ if(schema){
+ addDefaults(schema['extends']);
+ properties = schema.properties;
+ for(var i in properties){
+ var propDef = properties[i];
+ if(propDef && (typeof propDef == 'object') && ("default" in propDef)){
+ self[i] = propDef["default"];
+ }
+ }
+ }
+ if(schema && schema.prototype && schema.prototype.initialize){
+ initializeCalled = true;
+ schema.prototype.initialize.apply(self, args);
+ }
+ }
+ addDefaults(service._schema);
+ if(!initializeCalled && data && typeof data == 'object'){
+ dojo.mixin(self,data);
+ }
+ var idAttribute = jr.getIdAttribute(service);
+ Rest._index[this.__id = this.__clientId =
+ service.servicePath + (this[idAttribute] ||
+ Math.random().toString(16).substring(2,14) + '@' + ((dojox.rpc.Client && dojox.rpc.Client.clientId) || "client"))] = this;
+ if(dojox.json.schema && properties){
+ dojox.json.schema.mustBeValid(dojox.json.schema.validate(this, service._schema));
+ }
+ dirtyObjects.push({object:this, save: true});
+ };
+ return dojo.mixin(service._constructor, service._schema, {load:service});
+ },
+ fetch: function(absoluteId){
+ // summary:
+ // Fetches a resource by an absolute path/id and returns a dojo.Deferred.
+ var serviceAndId = jr.getServiceAndId(absoluteId);
+ return this.byId(serviceAndId.service,serviceAndId.id);
+ },
+ getIdAttribute: function(service){
+ // summary:
+ // Return the ids attribute used by this service (based on it's schema).
+ // Defaults to "id", if not other id is defined
+ var schema = service._schema;
+ var idAttr;
+ if(schema){
+ if(!(idAttr = schema._idAttr)){
+ for(var i in schema.properties){
+ if(schema.properties[i].identity || (schema.properties[i].link == "self")){
+ schema._idAttr = idAttr = i;
+ }
+ }
+ }
+ }
+ return idAttr || 'id';
+ },
+ getServiceAndId: function(/*String*/absoluteId){
+ // summary:
+ // Returns the REST service and the local id for the given absolute id. The result
+ // is returned as an object with a service property and an id property
+ // absoluteId:
+ // This is the absolute id of the object
+ var serviceName = '';
+
+ for(var service in jr.services){
+ if((absoluteId.substring(0, service.length) == service) && (service.length >= serviceName.length)){
+ serviceName = service;
+ }
+ }
+ if (serviceName){
+ return {service: jr.services[serviceName], id:absoluteId.substring(serviceName.length)};
+ }
+ var parts = absoluteId.match(/^(.*\/)([^\/]*)$/);
+ return {service: new jr.serviceClass(parts[1], true), id:parts[2]};
+ },
+ services:{},
+ schemas:{},
+ registerService: function(/*Function*/ service, /*String*/ servicePath, /*Object?*/ schema){
+ // summary:
+ // Registers a service for as a JsonRest service, mapping it to a path and schema
+ // service:
+ // This is the service to register
+ // servicePath:
+ // This is the path that is used for all the ids for the objects returned by service
+ // schema:
+ // This is a JSON Schema object to associate with objects returned by this service
+ servicePath = service.servicePath = servicePath || service.servicePath;
+ service._schema = jr.schemas[servicePath] = schema || service._schema || {};
+ jr.services[servicePath] = service;
+ },
+ byId: function(service, id){
+ // if caching is allowed, we look in the cache for the result
+ var deferred, result = Rest._index[(service.servicePath || '') + id];
+ if(result && !result._loadObject){// cache hit
+ deferred = new dojo.Deferred();
+ deferred.callback(result);
+ return deferred;
+ }
+ return this.query(service, id);
+ },
+ query: function(service, id, args){
+ var deferred = service(id, args);
+
+ deferred.addCallback(function(result){
+ if(result.nodeType && result.cloneNode){
+ // return immediately if it is an XML document
+ return result;
+ }
+ return resolveJson(service, deferred, result, typeof id != 'string' || (args && (args.start || args.count)) ? undefined: id);
+ });
+ return deferred;
+ },
+ _loader: function(callback){
+ // load a lazy object
+ var serviceAndId = jr.getServiceAndId(this.__id);
+ var self = this;
+ jr.query(serviceAndId.service, serviceAndId.id).addBoth(function(result){
+ // if they are the same this means an object was loaded, otherwise it
+ // might be a primitive that was loaded or maybe an error
+ if(result == self){
+ // we can clear the flag, so it is a loaded object
+ delete result.$ref;
+ delete result._loadObject;
+ }else{
+ // it is probably a primitive value, we can't change the identity of an object to
+ // the loaded value, so we will keep it lazy, but define the lazy loader to always
+ // return the loaded value
+ self._loadObject = function(callback){
+ callback(result);
+ };
+ }
+ callback(result);
+ });
+ },
+ isDirty: function(item){
+ // summary
+ // returns true if the item is marked as dirty or true if there are any dirty items
+ if(!item){
+ return !!dirtyObjects.length;
+ }
+ return item.__isDirty;
+ }
+
+ };
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/rpc/OfflineRest.js b/js/dojo-1.6/dojox/rpc/OfflineRest.js
new file mode 100644
index 0000000..25e0446
--- /dev/null
+++ b/js/dojo-1.6/dojox/rpc/OfflineRest.js
@@ -0,0 +1,269 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.rpc.OfflineRest"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.rpc.OfflineRest"] = true;
+dojo.provide("dojox.rpc.OfflineRest");
+dojo.require("dojox.data.ClientFilter");
+dojo.require("dojox.rpc.Rest");
+dojo.require("dojox.storage");
+
+
+// summary:
+// Makes the REST service be able to store changes in local
+// storage so it can be used offline automatically.
+ var Rest = dojox.rpc.Rest;
+ var namespace = "dojox_rpc_OfflineRest";
+ var loaded;
+ var index = Rest._index;
+ dojox.storage.manager.addOnLoad(function(){
+ // now that we are loaded we need to save everything in the index
+ loaded = dojox.storage.manager.available;
+ for(var i in index){
+ saveObject(index[i], i);
+ }
+ });
+ var dontSave;
+ function getStorageKey(key){
+ // returns a key that is safe to use in storage
+ return key.replace(/[^0-9A-Za-z_]/g,'_');
+ }
+ function saveObject(object,id){
+ // save the object into local storage
+
+ if(loaded && !dontSave && (id || (object && object.__id))){
+ dojox.storage.put(
+ getStorageKey(id||object.__id),
+ typeof object=='object'?dojox.json.ref.toJson(object):object, // makeshift technique to determine if the object is json object or not
+ function(){},
+ namespace);
+ }
+ }
+ function isNetworkError(error){
+ // determine if the error was a network error and should be saved offline
+ // or if it was a server error and not a result of offline-ness
+ return error instanceof Error && (error.status == 503 || error.status > 12000 || !error.status); // TODO: Make the right error determination
+ }
+ function sendChanges(){
+ // periodical try to save our dirty data
+ if(loaded){
+ var dirty = dojox.storage.get("dirty",namespace);
+ if(dirty){
+ for (var dirtyId in dirty){
+ commitDirty(dirtyId,dirty);
+ }
+ }
+ }
+ }
+ var OfflineRest;
+ function sync(){
+ OfflineRest.sendChanges();
+ OfflineRest.downloadChanges();
+ }
+ var syncId = setInterval(sync,15000);
+ dojo.connect(document, "ononline", sync);
+ OfflineRest = dojox.rpc.OfflineRest = {
+ turnOffAutoSync: function(){
+ clearInterval(syncId);
+ },
+ sync: sync,
+ sendChanges: sendChanges,
+ downloadChanges: function(){
+
+ },
+ addStore: function(/*data-store*/store,/*query?*/baseQuery){
+ // summary:
+ // Adds a store to the monitored store for local storage
+ // store:
+ // Store to add
+ // baseQuery:
+ // This is the base query to should be used to load the items for
+ // the store. Generally you want to load all the items that should be
+ // available when offline.
+ OfflineRest.stores.push(store);
+ store.fetch({queryOptions:{cache:true},query:baseQuery,onComplete:function(results,args){
+ store._localBaseResults = results;
+ store._localBaseFetch = args;
+ }});
+
+ }
+ };
+ OfflineRest.stores = [];
+ var defaultGet = Rest._get;
+ Rest._get = function(service, id){
+ // We specifically do NOT want the paging information to be used by the default handler,
+ // this is because online apps want to minimize the data transfer,
+ // but an offline app wants the opposite, as much data as possible transferred to
+ // the client side
+ try{
+ // if we are reloading the application with local dirty data in an online environment
+ // we want to make sure we save the changes first, so that we get up-to-date
+ // information from the server
+ sendChanges();
+ if(window.navigator && navigator.onLine===false){
+ // we force an error if we are offline in firefox, otherwise it will silently load it from the cache
+ throw new Error();
+ }
+ var dfd = defaultGet(service, id);
+ }catch(e){
+ dfd = new dojo.Deferred();
+ dfd.errback(e);
+ }
+ var sync = dojox.rpc._sync;
+ dfd.addCallback(function(result){
+ saveObject(result, service._getRequest(id).url);
+ return result;
+ });
+ dfd.addErrback(function(error){
+ if(loaded){
+ // if the storage is loaded, we can go ahead and get the object out of storage
+ if(isNetworkError(error)){
+ var loadedObjects = {};
+ // network error, load from local storage
+ var byId = function(id,backup){
+ if(loadedObjects[id]){
+ return backup;
+ }
+ var result = dojo.fromJson(dojox.storage.get(getStorageKey(id),namespace)) || backup;
+
+ loadedObjects[id] = result;
+ for(var i in result){
+ var val = result[i]; // resolve references if we can
+ id = val && val.$ref;
+ if (id){
+ if(id.substring && id.substring(0,4) == "cid:"){
+ // strip the cid scheme, we should be able to resolve it locally
+ id = id.substring(4);
+ }
+ result[i] = byId(id,val);
+ }
+ }
+ if (result instanceof Array){
+ //remove any deleted items
+ for (i = 0;i<result.length;i++){
+ if (result[i]===undefined){
+ result.splice(i--,1);
+ }
+ }
+ }
+ return result;
+ };
+ dontSave = true; // we don't want to be resaving objects when loading from local storage
+ //TODO: Should this reuse something from dojox.rpc.Rest
+ var result = byId(service._getRequest(id).url);
+
+ if(!result){// if it is not found we have to just return the error
+ return error;
+ }
+ dontSave = false;
+ return result;
+ }
+ else{
+ return error; // server error, let the error propagate
+ }
+ }
+ else{
+ if(sync){
+ return new Error("Storage manager not loaded, can not continue");
+ }
+ // we are not loaded, so we need to defer until we are loaded
+ dfd = new dojo.Deferred();
+ dfd.addCallback(arguments.callee);
+ dojox.storage.manager.addOnLoad(function(){
+ dfd.callback();
+ });
+ return dfd;
+ }
+ });
+ return dfd;
+ };
+ function changeOccurred(method, absoluteId, contentId, serializedContent, service){
+ if(method=='delete'){
+ dojox.storage.remove(getStorageKey(absoluteId),namespace);
+ }
+ else{
+ // both put and post should store the actual object
+ dojox.storage.put(getStorageKey(contentId), serializedContent, function(){
+ },namespace);
+ }
+ var store = service && service._store;
+ // record all the updated queries
+ if(store){
+ store.updateResultSet(store._localBaseResults, store._localBaseFetch);
+ dojox.storage.put(getStorageKey(service._getRequest(store._localBaseFetch.query).url),dojox.json.ref.toJson(store._localBaseResults),function(){
+ },namespace);
+
+ }
+
+ }
+ dojo.addOnLoad(function(){
+ dojo.connect(dojox.data, "restListener", function(message){
+ var channel = message.channel;
+ var method = message.event.toLowerCase();
+ var service = dojox.rpc.JsonRest && dojox.rpc.JsonRest.getServiceAndId(channel).service;
+ changeOccurred(
+ method,
+ channel,
+ method == "post" ? channel + message.result.id : channel,
+ dojo.toJson(message.result),
+ service
+ );
+
+ });
+ });
+ //FIXME: Should we make changes after a commit to see if the server rejected the change
+ // or should we come up with a revert mechanism?
+ var defaultChange = Rest._change;
+ Rest._change = function(method,service,id,serializedContent){
+ if(!loaded){
+ return defaultChange.apply(this,arguments);
+ }
+ var absoluteId = service._getRequest(id).url;
+ changeOccurred(method, absoluteId, dojox.rpc.JsonRest._contentId, serializedContent, service);
+ var dirty = dojox.storage.get("dirty",namespace) || {};
+ if (method=='put' || method=='delete'){
+ // these supersede so we can overwrite anything using this id
+ var dirtyId = absoluteId;
+ }
+ else{
+ dirtyId = 0;
+ for (var i in dirty){
+ if(!isNaN(parseInt(i))){
+ dirtyId = i;
+ }
+ } // get the last dirtyId to make a unique id for non-idempotent methods
+ dirtyId++;
+ }
+ dirty[dirtyId] = {method:method,id:absoluteId,content:serializedContent};
+ return commitDirty(dirtyId,dirty);
+ };
+ function commitDirty(dirtyId, dirty){
+ var dirtyItem = dirty[dirtyId];
+ var serviceAndId = dojox.rpc.JsonRest.getServiceAndId(dirtyItem.id);
+ var deferred = defaultChange(dirtyItem.method,serviceAndId.service,serviceAndId.id,dirtyItem.content);
+ // add it to our list of dirty objects
+ dirty[dirtyId] = dirtyItem;
+ dojox.storage.put("dirty",dirty,function(){},namespace);
+ deferred.addBoth(function(result){
+ if (isNetworkError(result)){
+ // if a network error (offlineness) was the problem, we leave it
+ // dirty, and return to indicate successfulness
+ return null;
+ }
+ // it was successful or the server rejected it, we remove it from the dirty list
+ var dirty = dojox.storage.get("dirty",namespace) || {};
+ delete dirty[dirtyId];
+ dojox.storage.put("dirty",dirty,function(){},namespace);
+ return result;
+ });
+ return deferred;
+ }
+
+ dojo.connect(index,"onLoad",saveObject);
+ dojo.connect(index,"onUpdate",saveObject);
+
+}
diff --git a/js/dojo-1.6/dojox/rpc/OfflineRest.xd.js b/js/dojo-1.6/dojox/rpc/OfflineRest.xd.js
new file mode 100644
index 0000000..62c3800
--- /dev/null
+++ b/js/dojo-1.6/dojox/rpc/OfflineRest.xd.js
@@ -0,0 +1,276 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.rpc.OfflineRest"],
+["require", "dojox.data.ClientFilter"],
+["require", "dojox.rpc.Rest"],
+["require", "dojox.storage"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.rpc.OfflineRest"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.rpc.OfflineRest"] = true;
+dojo.provide("dojox.rpc.OfflineRest");
+dojo.require("dojox.data.ClientFilter");
+dojo.require("dojox.rpc.Rest");
+dojo.require("dojox.storage");
+
+
+// summary:
+// Makes the REST service be able to store changes in local
+// storage so it can be used offline automatically.
+ var Rest = dojox.rpc.Rest;
+ var namespace = "dojox_rpc_OfflineRest";
+ var loaded;
+ var index = Rest._index;
+ dojox.storage.manager.addOnLoad(function(){
+ // now that we are loaded we need to save everything in the index
+ loaded = dojox.storage.manager.available;
+ for(var i in index){
+ saveObject(index[i], i);
+ }
+ });
+ var dontSave;
+ function getStorageKey(key){
+ // returns a key that is safe to use in storage
+ return key.replace(/[^0-9A-Za-z_]/g,'_');
+ }
+ function saveObject(object,id){
+ // save the object into local storage
+
+ if(loaded && !dontSave && (id || (object && object.__id))){
+ dojox.storage.put(
+ getStorageKey(id||object.__id),
+ typeof object=='object'?dojox.json.ref.toJson(object):object, // makeshift technique to determine if the object is json object or not
+ function(){},
+ namespace);
+ }
+ }
+ function isNetworkError(error){
+ // determine if the error was a network error and should be saved offline
+ // or if it was a server error and not a result of offline-ness
+ return error instanceof Error && (error.status == 503 || error.status > 12000 || !error.status); // TODO: Make the right error determination
+ }
+ function sendChanges(){
+ // periodical try to save our dirty data
+ if(loaded){
+ var dirty = dojox.storage.get("dirty",namespace);
+ if(dirty){
+ for (var dirtyId in dirty){
+ commitDirty(dirtyId,dirty);
+ }
+ }
+ }
+ }
+ var OfflineRest;
+ function sync(){
+ OfflineRest.sendChanges();
+ OfflineRest.downloadChanges();
+ }
+ var syncId = setInterval(sync,15000);
+ dojo.connect(document, "ononline", sync);
+ OfflineRest = dojox.rpc.OfflineRest = {
+ turnOffAutoSync: function(){
+ clearInterval(syncId);
+ },
+ sync: sync,
+ sendChanges: sendChanges,
+ downloadChanges: function(){
+
+ },
+ addStore: function(/*data-store*/store,/*query?*/baseQuery){
+ // summary:
+ // Adds a store to the monitored store for local storage
+ // store:
+ // Store to add
+ // baseQuery:
+ // This is the base query to should be used to load the items for
+ // the store. Generally you want to load all the items that should be
+ // available when offline.
+ OfflineRest.stores.push(store);
+ store.fetch({queryOptions:{cache:true},query:baseQuery,onComplete:function(results,args){
+ store._localBaseResults = results;
+ store._localBaseFetch = args;
+ }});
+
+ }
+ };
+ OfflineRest.stores = [];
+ var defaultGet = Rest._get;
+ Rest._get = function(service, id){
+ // We specifically do NOT want the paging information to be used by the default handler,
+ // this is because online apps want to minimize the data transfer,
+ // but an offline app wants the opposite, as much data as possible transferred to
+ // the client side
+ try{
+ // if we are reloading the application with local dirty data in an online environment
+ // we want to make sure we save the changes first, so that we get up-to-date
+ // information from the server
+ sendChanges();
+ if(window.navigator && navigator.onLine===false){
+ // we force an error if we are offline in firefox, otherwise it will silently load it from the cache
+ throw new Error();
+ }
+ var dfd = defaultGet(service, id);
+ }catch(e){
+ dfd = new dojo.Deferred();
+ dfd.errback(e);
+ }
+ var sync = dojox.rpc._sync;
+ dfd.addCallback(function(result){
+ saveObject(result, service._getRequest(id).url);
+ return result;
+ });
+ dfd.addErrback(function(error){
+ if(loaded){
+ // if the storage is loaded, we can go ahead and get the object out of storage
+ if(isNetworkError(error)){
+ var loadedObjects = {};
+ // network error, load from local storage
+ var byId = function(id,backup){
+ if(loadedObjects[id]){
+ return backup;
+ }
+ var result = dojo.fromJson(dojox.storage.get(getStorageKey(id),namespace)) || backup;
+
+ loadedObjects[id] = result;
+ for(var i in result){
+ var val = result[i]; // resolve references if we can
+ id = val && val.$ref;
+ if (id){
+ if(id.substring && id.substring(0,4) == "cid:"){
+ // strip the cid scheme, we should be able to resolve it locally
+ id = id.substring(4);
+ }
+ result[i] = byId(id,val);
+ }
+ }
+ if (result instanceof Array){
+ //remove any deleted items
+ for (i = 0;i<result.length;i++){
+ if (result[i]===undefined){
+ result.splice(i--,1);
+ }
+ }
+ }
+ return result;
+ };
+ dontSave = true; // we don't want to be resaving objects when loading from local storage
+ //TODO: Should this reuse something from dojox.rpc.Rest
+ var result = byId(service._getRequest(id).url);
+
+ if(!result){// if it is not found we have to just return the error
+ return error;
+ }
+ dontSave = false;
+ return result;
+ }
+ else{
+ return error; // server error, let the error propagate
+ }
+ }
+ else{
+ if(sync){
+ return new Error("Storage manager not loaded, can not continue");
+ }
+ // we are not loaded, so we need to defer until we are loaded
+ dfd = new dojo.Deferred();
+ dfd.addCallback(arguments.callee);
+ dojox.storage.manager.addOnLoad(function(){
+ dfd.callback();
+ });
+ return dfd;
+ }
+ });
+ return dfd;
+ };
+ function changeOccurred(method, absoluteId, contentId, serializedContent, service){
+ if(method=='delete'){
+ dojox.storage.remove(getStorageKey(absoluteId),namespace);
+ }
+ else{
+ // both put and post should store the actual object
+ dojox.storage.put(getStorageKey(contentId), serializedContent, function(){
+ },namespace);
+ }
+ var store = service && service._store;
+ // record all the updated queries
+ if(store){
+ store.updateResultSet(store._localBaseResults, store._localBaseFetch);
+ dojox.storage.put(getStorageKey(service._getRequest(store._localBaseFetch.query).url),dojox.json.ref.toJson(store._localBaseResults),function(){
+ },namespace);
+
+ }
+
+ }
+ dojo.addOnLoad(function(){
+ dojo.connect(dojox.data, "restListener", function(message){
+ var channel = message.channel;
+ var method = message.event.toLowerCase();
+ var service = dojox.rpc.JsonRest && dojox.rpc.JsonRest.getServiceAndId(channel).service;
+ changeOccurred(
+ method,
+ channel,
+ method == "post" ? channel + message.result.id : channel,
+ dojo.toJson(message.result),
+ service
+ );
+
+ });
+ });
+ //FIXME: Should we make changes after a commit to see if the server rejected the change
+ // or should we come up with a revert mechanism?
+ var defaultChange = Rest._change;
+ Rest._change = function(method,service,id,serializedContent){
+ if(!loaded){
+ return defaultChange.apply(this,arguments);
+ }
+ var absoluteId = service._getRequest(id).url;
+ changeOccurred(method, absoluteId, dojox.rpc.JsonRest._contentId, serializedContent, service);
+ var dirty = dojox.storage.get("dirty",namespace) || {};
+ if (method=='put' || method=='delete'){
+ // these supersede so we can overwrite anything using this id
+ var dirtyId = absoluteId;
+ }
+ else{
+ dirtyId = 0;
+ for (var i in dirty){
+ if(!isNaN(parseInt(i))){
+ dirtyId = i;
+ }
+ } // get the last dirtyId to make a unique id for non-idempotent methods
+ dirtyId++;
+ }
+ dirty[dirtyId] = {method:method,id:absoluteId,content:serializedContent};
+ return commitDirty(dirtyId,dirty);
+ };
+ function commitDirty(dirtyId, dirty){
+ var dirtyItem = dirty[dirtyId];
+ var serviceAndId = dojox.rpc.JsonRest.getServiceAndId(dirtyItem.id);
+ var deferred = defaultChange(dirtyItem.method,serviceAndId.service,serviceAndId.id,dirtyItem.content);
+ // add it to our list of dirty objects
+ dirty[dirtyId] = dirtyItem;
+ dojox.storage.put("dirty",dirty,function(){},namespace);
+ deferred.addBoth(function(result){
+ if (isNetworkError(result)){
+ // if a network error (offlineness) was the problem, we leave it
+ // dirty, and return to indicate successfulness
+ return null;
+ }
+ // it was successful or the server rejected it, we remove it from the dirty list
+ var dirty = dojox.storage.get("dirty",namespace) || {};
+ delete dirty[dirtyId];
+ dojox.storage.put("dirty",dirty,function(){},namespace);
+ return result;
+ });
+ return deferred;
+ }
+
+ dojo.connect(index,"onLoad",saveObject);
+ dojo.connect(index,"onUpdate",saveObject);
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/rpc/ProxiedPath.js b/js/dojo-1.6/dojox/rpc/ProxiedPath.js
new file mode 100644
index 0000000..568f8c0
--- /dev/null
+++ b/js/dojo-1.6/dojox/rpc/ProxiedPath.js
@@ -0,0 +1,41 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.rpc.ProxiedPath"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.rpc.ProxiedPath"] = true;
+dojo.provide("dojox.rpc.ProxiedPath");
+dojo.require("dojox.rpc.Service");
+
+
+
+dojox.rpc.envelopeRegistry.register(
+ "PROXIED-PATH",function(str){return str == "PROXIED-PATH"},{
+ serialize:function(smd, method, data){
+ var i;
+ var target = dojox.rpc.getTarget(smd, method);
+ if(dojo.isArray(data)){
+ for(i = 0; i < data.length;i++){
+ target += '/' + (data[i] == null ? "" : data[i]);
+ }
+ }else{
+ for(i in data){
+ target += '/' + i + '/' + data[i];
+ }
+ }
+ return {
+ data:'',
+ target: (method.proxyUrl || smd.proxyUrl) + "?url=" + encodeURIComponent(target)
+ };
+ },
+ deserialize:function(results){
+ return results;
+ }
+ }
+);
+
+
+}
diff --git a/js/dojo-1.6/dojox/rpc/ProxiedPath.xd.js b/js/dojo-1.6/dojox/rpc/ProxiedPath.xd.js
new file mode 100644
index 0000000..c916cb8
--- /dev/null
+++ b/js/dojo-1.6/dojox/rpc/ProxiedPath.xd.js
@@ -0,0 +1,46 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.rpc.ProxiedPath"],
+["require", "dojox.rpc.Service"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.rpc.ProxiedPath"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.rpc.ProxiedPath"] = true;
+dojo.provide("dojox.rpc.ProxiedPath");
+dojo.require("dojox.rpc.Service");
+
+
+
+dojox.rpc.envelopeRegistry.register(
+ "PROXIED-PATH",function(str){return str == "PROXIED-PATH"},{
+ serialize:function(smd, method, data){
+ var i;
+ var target = dojox.rpc.getTarget(smd, method);
+ if(dojo.isArray(data)){
+ for(i = 0; i < data.length;i++){
+ target += '/' + (data[i] == null ? "" : data[i]);
+ }
+ }else{
+ for(i in data){
+ target += '/' + i + '/' + data[i];
+ }
+ }
+ return {
+ data:'',
+ target: (method.proxyUrl || smd.proxyUrl) + "?url=" + encodeURIComponent(target)
+ };
+ },
+ deserialize:function(results){
+ return results;
+ }
+ }
+);
+
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/rpc/README b/js/dojo-1.6/dojox/rpc/README
new file mode 100644
index 0000000..af38011
--- /dev/null
+++ b/js/dojo-1.6/dojox/rpc/README
@@ -0,0 +1,56 @@
+-------------------------------------------------------------------------------
+DojoX RPC
+-------------------------------------------------------------------------------
+Version 1.0
+Release date: 07/01/2007
+-------------------------------------------------------------------------------
+Project state:
+yahoo.smd: production (but for old dojo.rpc, not the dojox.service.Rpc)
+Service.js: beta - this will become dojo.rpc.Service eventually and replace
+ the existing rpc system
+JsonRPC.js: beta - plugins for json-rpc for the rpc system
+Rest.js: beta - plugin for REST style services for the rpc system
+JsonRest.js: beta - A module for tracking and persisting changes to JSON objects
+through REST.
+OfflineRest.js: alpha - A module for storing REST changes locally as write-
+back cache for offline and intermittent connection situations
+ProxiedPath.js: beta - plugin for the PATH envelope to work with a simple PHP proxy
+Client.js: alpha - A module for maintaining per page/tab client sessions and
+deterministic message sequencing with a server.
+
+SMDLibrary contains smd files representing external services.
+
+-------------------------------------------------------------------------------
+Project authors
+ Dustin Machi
+ Kris Zyp
+ Revin Guillen
+-------------------------------------------------------------------------------
+Project description
+
+Extra utilities for use with dojo.rpc as well as additional smd descriptions
+for specific services.
+-------------------------------------------------------------------------------
+Dependencies:
+
+Dojo Core (package loader, dojo.rpc).
+-------------------------------------------------------------------------------
+Documentation
+
+See RPC documentation at http://dojotoolkit.org/
+
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/rpc/*
+
+Install into the following directory structure:
+/dojox/rpc/
+
+...which should be at the same level as your Dojo checkout.
+
+The use of the actual utilities varies, but typically additional software
+will be included with dojo.require() and smd files for services can be loaded
+manually with an xhr request or can be provided by url to the service when created
+
diff --git a/js/dojo-1.6/dojox/rpc/Rest.js b/js/dojo-1.6/dojox/rpc/Rest.js
new file mode 100644
index 0000000..0e9a4cf
--- /dev/null
+++ b/js/dojo-1.6/dojox/rpc/Rest.js
@@ -0,0 +1,153 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.rpc.Rest"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.rpc.Rest"] = true;
+dojo.provide("dojox.rpc.Rest");
+
+
+// Note: This doesn't require dojox.rpc.Service, and if you want it you must require it
+// yourself, and you must load it prior to dojox.rpc.Rest.
+
+// summary:
+// This provides a HTTP REST service with full range REST verbs include PUT,POST, and DELETE.
+// description:
+// A normal GET query is done by using the service directly:
+// | var restService = dojox.rpc.Rest("Project");
+// | restService("4");
+// This will do a GET for the URL "/Project/4".
+// | restService.put("4","new content");
+// This will do a PUT to the URL "/Project/4" with the content of "new content".
+// You can also use the SMD service to generate a REST service:
+// | var services = dojox.rpc.Service({services: {myRestService: {transport: "REST",...
+// | services.myRestService("parameters");
+//
+// The modifying methods can be called as sub-methods of the rest service method like:
+// | services.myRestService.put("parameters","data to put in resource");
+// | services.myRestService.post("parameters","data to post to the resource");
+// | services.myRestService['delete']("parameters");
+ if(dojox.rpc && dojox.rpc.transportRegistry){
+ // register it as an RPC service if the registry is available
+ dojox.rpc.transportRegistry.register(
+ "REST",
+ function(str){return str == "REST";},
+ {
+ getExecutor : function(func,method,svc){
+ return new dojox.rpc.Rest(
+ method.name,
+ (method.contentType||svc._smd.contentType||"").match(/json|javascript/), // isJson
+ null,
+ function(id, args){
+ var request = svc._getRequest(method,[id]);
+ request.url= request.target + (request.data ? '?'+ request.data : '');
+ if(args && (args.start >= 0 || args.count >= 0)){
+ request.headers = request.headers || {};
+ request.headers.Range = "items=" + (args.start || '0') + '-' +
+ (("count" in args && args.count != Infinity) ?
+ (args.count + (args.start || 0) - 1) : '');
+ }
+ return request;
+ }
+ );
+ }
+ }
+ );
+ }
+ var drr;
+
+ function index(deferred, service, range, id){
+ deferred.addCallback(function(result){
+ if(deferred.ioArgs.xhr && range){
+ // try to record the total number of items from the range header
+ range = deferred.ioArgs.xhr.getResponseHeader("Content-Range");
+ deferred.fullLength = range && (range=range.match(/\/(.*)/)) && parseInt(range[1]);
+ }
+ return result;
+ });
+ return deferred;
+ }
+ drr = dojox.rpc.Rest = function(/*String*/path, /*Boolean?*/isJson, /*Object?*/schema, /*Function?*/getRequest){
+ // summary:
+ // Creates a REST service using the provided path.
+ var service;
+ // it should be in the form /Table/
+ service = function(id, args){
+ return drr._get(service, id, args);
+ };
+ service.isJson = isJson;
+ service._schema = schema;
+ // cache:
+ // This is an object that provides indexing service
+ // This can be overriden to take advantage of more complex referencing/indexing
+ // schemes
+ service.cache = {
+ serialize: isJson ? ((dojox.json && dojox.json.ref) || dojo).toJson : function(result){
+ return result;
+ }
+ };
+ // the default XHR args creator:
+ service._getRequest = getRequest || function(id, args){
+ if(dojo.isObject(id)){
+ id = dojo.objectToQuery(id);
+ id = id ? "?" + id: "";
+ }
+ if(args && args.sort && !args.queryStr){
+ id += (id ? "&" : "?") + "sort("
+ for(var i = 0; i<args.sort.length; i++){
+ var sort = args.sort[i];
+ id += (i > 0 ? "," : "") + (sort.descending ? '-' : '+') + encodeURIComponent(sort.attribute);
+ }
+ id += ")";
+ }
+ var request = {
+ url: path + (id == null ? "" : id),
+ handleAs: isJson ? 'json' : 'text',
+ contentType: isJson ? 'application/json' : 'text/plain',
+ sync: dojox.rpc._sync,
+ headers: {
+ Accept: isJson ? 'application/json,application/javascript' : '*/*'
+ }
+ };
+ if(args && (args.start >= 0 || args.count >= 0)){
+ request.headers.Range = "items=" + (args.start || '0') + '-' +
+ (("count" in args && args.count != Infinity) ?
+ (args.count + (args.start || 0) - 1) : '');
+ }
+ dojox.rpc._sync = false;
+ return request;
+ };
+ // each calls the event handler
+ function makeRest(name){
+ service[name] = function(id,content){
+ return drr._change(name,service,id,content); // the last parameter is to let the OfflineRest know where to store the item
+ };
+ }
+ makeRest('put');
+ makeRest('post');
+ makeRest('delete');
+ // record the REST services for later lookup
+ service.servicePath = path;
+ return service;
+ };
+
+ drr._index={};// the map of all indexed objects that have gone through REST processing
+ drr._timeStamps={};
+ // these do the actual requests
+ drr._change = function(method,service,id,content){
+ // this is called to actually do the put, post, and delete
+ var request = service._getRequest(id);
+ request[method+"Data"] = content;
+ return index(dojo.xhr(method.toUpperCase(),request,true),service);
+ };
+
+ drr._get= function(service,id, args){
+ args = args || {};
+ // this is called to actually do the get
+ return index(dojo.xhrGet(service._getRequest(id, args)), service, (args.start >= 0 || args.count >= 0), id);
+ };
+
+}
diff --git a/js/dojo-1.6/dojox/rpc/Rest.xd.js b/js/dojo-1.6/dojox/rpc/Rest.xd.js
new file mode 100644
index 0000000..ac6002f
--- /dev/null
+++ b/js/dojo-1.6/dojox/rpc/Rest.xd.js
@@ -0,0 +1,157 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.rpc.Rest"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.rpc.Rest"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.rpc.Rest"] = true;
+dojo.provide("dojox.rpc.Rest");
+
+
+// Note: This doesn't require dojox.rpc.Service, and if you want it you must require it
+// yourself, and you must load it prior to dojox.rpc.Rest.
+
+// summary:
+// This provides a HTTP REST service with full range REST verbs include PUT,POST, and DELETE.
+// description:
+// A normal GET query is done by using the service directly:
+// | var restService = dojox.rpc.Rest("Project");
+// | restService("4");
+// This will do a GET for the URL "/Project/4".
+// | restService.put("4","new content");
+// This will do a PUT to the URL "/Project/4" with the content of "new content".
+// You can also use the SMD service to generate a REST service:
+// | var services = dojox.rpc.Service({services: {myRestService: {transport: "REST",...
+// | services.myRestService("parameters");
+//
+// The modifying methods can be called as sub-methods of the rest service method like:
+// | services.myRestService.put("parameters","data to put in resource");
+// | services.myRestService.post("parameters","data to post to the resource");
+// | services.myRestService['delete']("parameters");
+ if(dojox.rpc && dojox.rpc.transportRegistry){
+ // register it as an RPC service if the registry is available
+ dojox.rpc.transportRegistry.register(
+ "REST",
+ function(str){return str == "REST";},
+ {
+ getExecutor : function(func,method,svc){
+ return new dojox.rpc.Rest(
+ method.name,
+ (method.contentType||svc._smd.contentType||"").match(/json|javascript/), // isJson
+ null,
+ function(id, args){
+ var request = svc._getRequest(method,[id]);
+ request.url= request.target + (request.data ? '?'+ request.data : '');
+ if(args && (args.start >= 0 || args.count >= 0)){
+ request.headers = request.headers || {};
+ request.headers.Range = "items=" + (args.start || '0') + '-' +
+ (("count" in args && args.count != Infinity) ?
+ (args.count + (args.start || 0) - 1) : '');
+ }
+ return request;
+ }
+ );
+ }
+ }
+ );
+ }
+ var drr;
+
+ function index(deferred, service, range, id){
+ deferred.addCallback(function(result){
+ if(deferred.ioArgs.xhr && range){
+ // try to record the total number of items from the range header
+ range = deferred.ioArgs.xhr.getResponseHeader("Content-Range");
+ deferred.fullLength = range && (range=range.match(/\/(.*)/)) && parseInt(range[1]);
+ }
+ return result;
+ });
+ return deferred;
+ }
+ drr = dojox.rpc.Rest = function(/*String*/path, /*Boolean?*/isJson, /*Object?*/schema, /*Function?*/getRequest){
+ // summary:
+ // Creates a REST service using the provided path.
+ var service;
+ // it should be in the form /Table/
+ service = function(id, args){
+ return drr._get(service, id, args);
+ };
+ service.isJson = isJson;
+ service._schema = schema;
+ // cache:
+ // This is an object that provides indexing service
+ // This can be overriden to take advantage of more complex referencing/indexing
+ // schemes
+ service.cache = {
+ serialize: isJson ? ((dojox.json && dojox.json.ref) || dojo).toJson : function(result){
+ return result;
+ }
+ };
+ // the default XHR args creator:
+ service._getRequest = getRequest || function(id, args){
+ if(dojo.isObject(id)){
+ id = dojo.objectToQuery(id);
+ id = id ? "?" + id: "";
+ }
+ if(args && args.sort && !args.queryStr){
+ id += (id ? "&" : "?") + "sort("
+ for(var i = 0; i<args.sort.length; i++){
+ var sort = args.sort[i];
+ id += (i > 0 ? "," : "") + (sort.descending ? '-' : '+') + encodeURIComponent(sort.attribute);
+ }
+ id += ")";
+ }
+ var request = {
+ url: path + (id == null ? "" : id),
+ handleAs: isJson ? 'json' : 'text',
+ contentType: isJson ? 'application/json' : 'text/plain',
+ sync: dojox.rpc._sync,
+ headers: {
+ Accept: isJson ? 'application/json,application/javascript' : '*/*'
+ }
+ };
+ if(args && (args.start >= 0 || args.count >= 0)){
+ request.headers.Range = "items=" + (args.start || '0') + '-' +
+ (("count" in args && args.count != Infinity) ?
+ (args.count + (args.start || 0) - 1) : '');
+ }
+ dojox.rpc._sync = false;
+ return request;
+ };
+ // each calls the event handler
+ function makeRest(name){
+ service[name] = function(id,content){
+ return drr._change(name,service,id,content); // the last parameter is to let the OfflineRest know where to store the item
+ };
+ }
+ makeRest('put');
+ makeRest('post');
+ makeRest('delete');
+ // record the REST services for later lookup
+ service.servicePath = path;
+ return service;
+ };
+
+ drr._index={};// the map of all indexed objects that have gone through REST processing
+ drr._timeStamps={};
+ // these do the actual requests
+ drr._change = function(method,service,id,content){
+ // this is called to actually do the put, post, and delete
+ var request = service._getRequest(id);
+ request[method+"Data"] = content;
+ return index(dojo.xhr(method.toUpperCase(),request,true),service);
+ };
+
+ drr._get= function(service,id, args){
+ args = args || {};
+ // this is called to actually do the get
+ return index(dojo.xhrGet(service._getRequest(id, args)), service, (args.start >= 0 || args.count >= 0), id);
+ };
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/rpc/SMDLibrary/dojo-api.smd b/js/dojo-1.6/dojox/rpc/SMDLibrary/dojo-api.smd
new file mode 100644
index 0000000..1b2db85
--- /dev/null
+++ b/js/dojo-1.6/dojox/rpc/SMDLibrary/dojo-api.smd
@@ -0,0 +1,30 @@
+{
+ envelope: "URL",
+ transport: "JSONP",
+ callbackParamName: "callback",
+ services: {
+ get: {
+ target: "http://api.dojotoolkit.org/jsdoc/jsonp",
+ parameters: [
+ { name: "name", type: "string", optional: false },
+ { name: "exact", type: "boolean", optional: true },
+ { name: "recursion", type: "boolean", optional: true },
+ { name: "resource", type: "string", optional: true },
+ { name: "project", type: "string", optional: true },
+ { name: "version", type: "string", optional: true },
+ { name: "attributes", type: "array", optional: true }
+ ]
+ },
+ batch: {
+ target: "http://api.dojotoolkit.org/jsdoc/jsonp/batch",
+ parameters: [
+ { name: "names", type: "array", optional: false },
+ { name: "exact", type: "boolean", optional: true },
+ { name: "recursion", type: "boolean", optional: true },
+ { name: "project", type: "string", optional: true },
+ { name: "version", type: "string", optional: true },
+ { name: "attributes", type: "array", optional: false }
+ ]
+ }
+ }
+} \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/rpc/SMDLibrary/friendfeed.smd b/js/dojo-1.6/dojox/rpc/SMDLibrary/friendfeed.smd
new file mode 100644
index 0000000..a18aa8e
--- /dev/null
+++ b/js/dojo-1.6/dojox/rpc/SMDLibrary/friendfeed.smd
@@ -0,0 +1,49 @@
+{
+ "SMDVersion": "2.0",
+ "id": "http://friendfeed.com/api",
+ "description": "Friendfeed's API - documentation at http://code.google.com/p/friendfeed-api/wiki/ApiDocumentation",
+
+ transport: "JSONP",
+ envelope: "URL",
+
+ additionalParameters: true,
+ parameters: [
+ { name: "format", optional: false, "default": "json" },
+ { name: "service", optional: true },
+ { name: "start", optional: true, type: "integer" },
+ { name: "num", optional: true, type: "integer" }
+ ],
+
+ services: {
+ users: {
+ target: "http://friendfeed.com/api/feed/user",
+ parameters: [
+ { name: "nickname", type: "string", optional: false, "default": "" }
+ ]
+ },
+ entry: {
+ target: "http://friendfeed.com/api/feed/entry",
+ parameters: [
+ { name: "entry_id", type: "string", optional: false, "default": "" }
+ ]
+ },
+ search: {
+ target: "http://friendfeed.com/api/feed/search",
+ parameters: [
+ { name: "q", type: "string", optional: false, "default": "" }
+ ]
+ },
+ url: {
+ target: "http://friendfeed.com/api/feed/url",
+ parameters: [
+ { name: "url", type: "string", optional: false, "default": "" }
+ ]
+ },
+ domain: {
+ target: "http://friendfeed.com/api/feed/domain",
+ parameters: [
+ { name: "domain", type: "string", optional: false, "default":"" }
+ ]
+ }
+ }
+}
diff --git a/js/dojo-1.6/dojox/rpc/SMDLibrary/geonames.smd b/js/dojo-1.6/dojox/rpc/SMDLibrary/geonames.smd
new file mode 100644
index 0000000..04f04db
--- /dev/null
+++ b/js/dojo-1.6/dojox/rpc/SMDLibrary/geonames.smd
@@ -0,0 +1,263 @@
+{
+
+ // JSON REST services provided by geonames.org
+ // adapted from: http://www.geonames.org/export/JSON-webservices.html
+ // http://creativecommons.org/licenses/by/3.0/
+ // INCOMPLETE IMPLEMENTATION
+
+ "SMDVersion":"2.0",
+ "id":"/geonames",
+ "transport":"JSONP",
+ "envelope":"URL",
+ "target": "http://ws.geonames.org/",
+
+ "parameters" : [
+ {name:"type", optional: false, "default":"JSON"}
+ ],
+
+ "services":{
+ getCountryInfo:{
+ // Result : returns info about a country such as name, population, etc.
+ // If country parameter is not specified, that information is returned for
+ // every country
+ "target": "countryInfoJSON",
+ "parameters": [
+ { name: "country", type:"STRING", optional: true },
+ { name: "lang", type:"STRING"}, // default: "en"
+ { name: "maxRows", type:"INTEGER", optional: true } // default: 10
+ ]
+ },
+
+ getCities:{
+ // Result : returns a list of cities and placenames in the bounding box,
+ // ordered by relevancy (capital/population). Placenames close together
+ // are filterered out and only the larger name is included in the resulting list.
+ "target": "citiesJSON",
+ "parameters": [
+ { name: "north", type:"FLOAT"},
+ { name: "south", type:"FLOAT"},
+ { name: "east", type:"FLOAT"},
+ { name: "west", type:"FLOAT"},
+ { name: "lang", type:"STRING"}, // default: "en"
+ { name: "maxRows", type:"INTEGER", optional: true } // deault: 10
+ ]
+ },
+
+ "getQuakes":{
+ // Result : returns a list of earthquakes, ordered by magnitude
+ "target" : "earthquakesJSON",
+ "parameters" : [
+ // bounding box coords:
+ { name: "north", type:"FLOAT" },
+ { name: "south", type:"FLOAT" },
+ { name: "east", type:"FLOAT" },
+ { name: "west", type:"FLOAT" },
+ { name: "date", type:"STRING",optional: true }, // yyyy-MM-dd
+ { name: "minMagniture", type:"INTERGER",optional: true },
+ { name: "maxRows", type:"INTEGER", optional: true } // deault: 10
+ ]
+ },
+
+ "getWeather":{
+ // Weather data is provided in the METAR (METeorological Aerodrome Report) format.
+ // Result : returns a list of weather stations with the most recent weather observation
+ "target" : "weatherJSON",
+ "parameters" : [
+ { name: "north", type:"FLOAT" },
+ { name: "south", type:"FLOAT" },
+ { name: "east", type:"FLOAT" },
+ { name: "west", type:"FLOAT" },
+ { name: "maxRows", type:"INTEGER",optional:true } // deault: 10
+ ]
+ },
+
+ "getWeatherByICAO":{
+ // Result : returns the weather station and the most recent weather observation for the ICAO code
+ "target": "weatherIcaoJSON",
+ "parameters": [
+ { name:"ICAO", type:"STRING" }
+ ]
+ },
+
+ "getWeatherByCoords":{
+ // Result : returns a weather station with the most recent weather observation
+ "target": "findNearByWeatherJSON",
+ "parameters": [
+ { name:"lat", type:"FLOAT" },
+ { name:"lng", type:"FLOAT" }
+ ]
+ },
+
+ "getChildren":{
+ // Returns the children for a given geonameId. The children are the
+ // administrative divisions within an other administrative division.
+ // Like the counties (ADM2) in a state (ADM1) or also the countries
+ // in a continent.
+ "target": "childrenJSON",
+ "parameters": [
+ { name:"geonameId", type:"INTEGER" }
+ ]
+ },
+
+ "getHierarchy":{
+ // Result : returns a list of GeoName records, ordered by hierarchy
+ // level. The top hierarchy (continent) is the first element in the list
+ "target": "hierarchyJSON",
+ "parameters": [
+ { name:"geonameId", type:"INTEGER" }
+ ]
+ },
+
+ "getNeighbours":{
+ // The neighbourhood for US cities. Data provided by Zillow under cc-by-sa license.
+ "target":"neighboursJSON",
+ "parameters": [
+ { name:"geonameId", type:"INTEGER" }
+ //{ name:"lat", type:"FLOAT" },
+ //{ name:"long", type:"FLOAT" }
+ ]
+ },
+
+ "getNeighbourhood":{
+ // returns the neighbourhood for the given latitude/longitude
+ // Example http://ws.geonames.org/neighbourhood?lat=40.78343&lng=-73.96625
+ "target":"neighbourhoodJSON",
+ "parameters":[
+ { name:"lat", type:"FLOAT" },
+ { name:"lng", type:"FLOAT" },
+ { name:"radius", type:"FLOAT" }
+ ]
+ },
+
+ "getSiblings":{
+ // Result : returns a list of GeoNames records that have the same
+ // administrative level and the same father
+ "target":"siblingsJSON",
+ "parameters": [
+ { name:"geonameId", type:"INTEGER" }
+ ]
+ },
+
+ "getCountryCode":{
+ // returns the iso country code for the given latitude/longitude
+ // With the parameter type=xml this service returns an xml document
+ // with iso country code and country name. The optional parameter
+ // lang can be used to specify the language the country name should
+ // be in. JSON output is produced with type=JSON
+ "target":"countryCode",
+ "parameters": [
+ { name:"lat", type:"FLOAT" },
+ { name:"lng", type:"FLOAT" },
+ { name:"lang", type:"STRING",optional:true },
+ { name:"radius", type:"FLOAT" }
+ ]
+ },
+
+ "getCountrySubdivision":{
+ // returns the country and the administrative subdivison (state, province,...) for the given latitude/longitude
+ // Example http://ws.geonames.org/countrySubdivisionJSON?lat=47.03&lng=10.2
+ "target":"countrySubdivisionJSON",
+ "parameters":[
+ { name:"lat", type:"FLOAT" },
+ { name:"long", type:"FLOAT" },
+ { name:"radius", type:"FLOAT" }
+ ]
+ },
+
+ "getWikipediaBoundingBox":{
+ // returns the wikipedia entries within the bounding box as xml document
+ // Example http://ws.geonames.org/wikipediaBoundingBoxJSON?north=44.1&south=-9.9&east=-22.4&west=55.2
+ "target":"wikipediaBoundingBoxJSON",
+ "parameters":[
+ { name: "north", type:"FLOAT" },
+ { name: "south", type:"FLOAT" },
+ { name: "east", type:"FLOAT" },
+ { name: "west", type:"FLOAT" },
+ { name: "lang", type:"STRING",optional:true }, // default: "en"
+ { name: "maxRows", type:"INTEGER",optional:true } // default: 10
+ ]
+ },
+
+ "searchWikipedia":{
+ // returns the wikipedia entries found for the searchterm as xml document
+ // Example http://ws.geonames.org/wikipediaSearchJSON?q=london&maxRows=10
+ "target":"wikipediaSearchJSON",
+ "parameters":[
+ { name: "q", type:"STRING" }, // place name?
+ { name: "title", type:"STRING" }, // optional
+ { name: "lang", type:"FLOAT",optional:true }, // de or en
+ { name: "maxRows", type:"INTEGER",optional:true } // default: 10
+ ]
+ },
+
+ "getTimezone":{
+ // the timezone at the lat/lng with gmt offset (1. January) and dst offset (1. July)
+ "target":"timezoneJSON",
+ "parameters":[
+ { name:"lat", type:"FLOAT" },
+ { name:"lng", type:"FLOAT" }
+ ]
+ },
+
+ "search":{
+ // returns the names found for the searchterm as xml or json document,
+ // the search is using an AND operator
+ "target":"searchJSON",
+ "parameters":[
+ // exhaustive list. see: http://www.geonames.org/export/geonames-search.html
+ { name:"q", type:"STRING" },
+ { name:"name", type:"STRING" },
+ { name:"name_equals", type:"STRING" },
+ // optional:
+ { name:"maxRows", type:"INTEGER",optional:true }, // def: 100, max:1000
+ { name:"startRow", type:"INTEGER",optional:true }, // def: 0
+ { name:"country", type:"STRING",optional:true }, // iso-3166, def: all
+ /* name:"adminCode..." */
+ { name:"featureClass", type:"STRING",optional:true}, // ? multi, enum(a,h,l,p,r,s,t,u,v)
+ { name:"featureCode", type:"STRING",optional:true},
+ { name:"lang", type:"STRING",optional:true}, // iso-636
+ { name:"type", type:"STRING",optional:true}, // xml | json | rdf, def: xml
+ { name:"style", type:"STRING",optional:true }, // SHORT,MEDIUM,LONG,FULL def: MEDIUM
+ { name:"isNamedRequired", type:"BOOLEAN", optional:true }
+ ]
+ },
+
+ "postalCodeLookup":{
+ // returns a list of places for the given postalcode in JSON format
+ // Example http://ws.geonames.org/postalCodeLookupJSON?postalcode=6600&country=AT
+ "target":"postalCodeLookupJSON",
+ "parameters":[
+ { name:"postalcode", type:"STRING" },
+ { name:"country", type:"STRING",optional:true},
+ { name:"maxRows", type:"INTEGER", optional:true }, // def: 20
+ { name:"charset", type:"STRING",optional:true } // def: utf-8
+ ]
+ },
+
+ "postalCodeSearch":{
+ "target":"postalCodeSearchJSON",
+ "parameters":[
+ { name:"postalcode", type:"STRING",optional:true}, // one or the other
+ { name:"placename", type:"STRING",optional:true }, // one or the other
+ { name:"country", type:"STRING",optional:true},
+ { name:"style", type:"STRING",optional:true}, // def: MEDIUM
+ { name:"maxRows", type:"INTEGER",optional:true}, // def: 20
+ { name:"charset", type:"STRING",optional:true} // def: utf-8
+ ]
+ }
+
+ // TODO: implement:
+ // findNearby,
+ // findNearbyPlaceName
+ // findNearbyPostalCodes,
+ // findNearbyStreets,
+ // findNearByWeather
+ // findNearByWikipedia
+ // findNeareastAddress
+ // findNearestInterestion
+ // get
+ // gtop30
+ // srtm3
+
+ } // end services
+}
diff --git a/js/dojo-1.6/dojox/rpc/SMDLibrary/google.smd b/js/dojo-1.6/dojox/rpc/SMDLibrary/google.smd
new file mode 100644
index 0000000..82af928
--- /dev/null
+++ b/js/dojo-1.6/dojox/rpc/SMDLibrary/google.smd
@@ -0,0 +1,129 @@
+{
+ // Google Ajax API SMD as defined by:
+ // http://code.google.com/apis/ajaxsearch/documentation/reference.html
+ // PLEASE Read the Google Terms of Service:
+ // http://code.google.com/apis/ajaxsearch/terms.html
+
+ "SMDVersion": "2.0",
+ "id": "http://ajax.googleapis.com/ajax/services/search/",
+ "description": "Google Ajax API",
+
+ "transport": "JSONP",
+ "envelope": "URL",
+ "additionalParameters": true,
+
+ "parameters": [
+ // the most important param, the search query:
+ { "name": "q", optional: false, "default":"" },
+
+ // Google doesn't require, but appreciates, you using an API key
+ // see: http://code.google.com/apis/ajaxsearch/signup.html
+ // { "name": "key", optional: true, "default": "[enter your key]" },
+
+ // result size: large | small (8 or 4 per page)
+ { "name": "rsz", optional:true, "default": "small" },
+
+ // language selection:
+ { "name": "hl", optional:true, "default": "en" },
+
+ // starting offset
+ { "name": "start", optional:true, "default": 0 },
+
+ { "name": "alt", optional:false, "default": "json" },
+
+ // API version: only 1.0 supported
+ { "name": "v", optional:false, "default": "1.0" }
+ ],
+
+ "services": {
+
+ "webSearch": {
+ "target": "http://ajax.googleapis.com/ajax/services/search/web",
+ "parameters": [
+ { "name": "cx", "type":"string", "optional":true }, // unique id
+ { "name": "cref", "type":"string", "optional":true }, // linked custom search engine
+ { "name": "safe", "type":"string", "optional":true }, // active | moderate | off
+ // lr: see: http://www.google.com/coop/docs/cse/resultsxml.html#languageCollections
+ { "name": "lr", "type":"string", "optional":true } // restrict to lang
+ ]
+ },
+
+ "localSearch": {
+ "target": "http://ajax.googleapis.com/ajax/services/search/local",
+ "parameters": [
+ // comma separated lat,long value to use for center
+ { "name": "sll", "type": "string", "optional": true },
+ { "name": "sspn", "type":"string", "optional": true } // bounding box?
+ ]
+ },
+
+ "videoSearch": {
+ "target": "http://ajax.googleapis.com/ajax/services/search/video",
+ "parameters": [
+ // ordering, set "d" to order by date, "default": by relevance
+ { "name": "scoring", "type": "string", "optional": true }
+ ]
+ },
+
+ "blogSearch": {
+ "target": "http://ajax.googleapis.com/ajax/services/search/blogs",
+ "parameters": [
+ // see videoSearch params
+ { "name": "scoring", "type": "string", "optional": true }
+ ]
+ },
+
+ "newsSearch": {
+ "target": "http://ajax.googleapis.com/ajax/services/search/news",
+ "parameters": [
+ { "name": "scoring", "type": "string", "optional": true },
+ // geo: scope search to location. supply city, state, country, or zipcode
+ // using geo makes "q" param optional
+ { "name": "geo", "type":"string", optional:true }
+ ]
+ },
+
+ "bookSearch": {
+ "target": "http://ajax.googleapis.com/ajax/services/search/books",
+ "parameters": [
+ // set to "1" to only include full books
+ { "name":"as_brr", "optional": true, "type":"number" },
+ // restrict search to user-defined library
+ { "name":"as_list", "optional": true, "type":"string" }
+ ]
+ },
+
+ "imageSearch": {
+ "target": "http://ajax.googleapis.com/ajax/services/search/images",
+ "parameters": [
+ // safe: active | moderate | off
+ { "name": "safe", "type":"string", "optional":true },
+ // limit image size: one of: icon, small|medium|large|xlarge, xxlarge, huge
+ { "name": "imgsz", "type":"string", "optional": true },
+ // limit image color: one of: mono|gray|color
+ { "name": "imgc", "type":"string", "optional": true },
+ // use "face" to limit to mugshots
+ { "name": "imgtype", "type":"string", "optional": true },
+ // limit to file "type": jpg|png|gif|bmp
+ { "name": "as_filetype", "type": "string", "optional": true },
+ // limit results to domain:
+ { "name": "as_sitesearch", "type": "string", "optional": true }
+ ]
+ },
+
+ "getFeed": {
+ "target": "http://ajax.googleapis.com/ajax/services/feed/load",
+ // pass a feed URL in the q parameter
+ "parameters": []
+ },
+
+ "translate" : {
+ "target" : "http://ajax.googleapis.com/ajax/services/language/translate",
+ "parameters": [
+ // A String like "en|es" (for english -> spanish)
+ { "name":"langpair", "type":"string", optional:false }
+ ]
+ }
+
+ }
+}
diff --git a/js/dojo-1.6/dojox/rpc/SMDLibrary/twitter.smd b/js/dojo-1.6/dojox/rpc/SMDLibrary/twitter.smd
new file mode 100644
index 0000000..6c19b3a
--- /dev/null
+++ b/js/dojo-1.6/dojox/rpc/SMDLibrary/twitter.smd
@@ -0,0 +1,35 @@
+{
+
+ "SMDVersion": "2.0",
+ "id": "http://apiwiki.twitter.com/w/page/22554756/Twitter-Search-API-Method:-search",
+ "description": "Twitter Search API",
+
+ "transport": "JSONP",
+ "envelope": "URL",
+ "additionalParameters": true,
+
+ "parameters": [
+ // the most important param, the search query:
+ { "name": "q", optional: false, "default":"" },
+
+
+ // result size: large | small (8 or 4 per page)
+ { "name": "rpp", optional:true, "default": 10 },
+
+ // language selection:
+ { "name": "lang", optional:true, "default": "en" },
+
+ // starting page
+ { "name": "page", optional:true, "default": 0 }
+
+ ],
+
+ "services": {
+
+ "search": {
+ "target": "http://search.twitter.com/search.json",
+ "parameters": [
+ ]
+ }
+ }
+}
diff --git a/js/dojo-1.6/dojox/rpc/SMDLibrary/wikipedia.smd b/js/dojo-1.6/dojox/rpc/SMDLibrary/wikipedia.smd
new file mode 100644
index 0000000..d91b2c3
--- /dev/null
+++ b/js/dojo-1.6/dojox/rpc/SMDLibrary/wikipedia.smd
@@ -0,0 +1,49 @@
+{
+ "SMDVersion": "2.0",
+ "id": "http://en.wikipedia.org/w/api.php",
+ "description": "Wikipedia API",
+
+ transport: "JSONP",
+ envelope: "URL",
+ additionalParameters: true,
+ target: "http://en.wikipedia.org/w/api.php",
+ parameters: [
+ { name: "format", optional: false, "default": "json" }
+ ],
+
+ services: {
+
+ /*
+ * This is a very very basic spec that just gives us a free-form API
+ * endpoint to talk to. See http://en.wikipedia.org/w/api.php for
+ * details on what parameters to supply and what sort of data you
+ * should expect to see. Note that returned JSON is often somewhat
+ * ... interesting ...:
+ *
+ * {
+ * "parse": {
+ * "text": {
+ * "*": "<table ..."
+ * },
+ * "langlinks": [
+ * {
+ * "lang": "simple",
+ * "*": ""
+ * },
+ * // etc.
+ * ]
+ * }
+ * }
+ *
+ * Not sure why we'd ever want an element to be named "*", but that's
+ * how it is. So take care.
+ *
+ */
+ query: {
+ parameters: [
+ { name: "action", type: "string", "default": "parse" }
+ ]
+ }
+
+ }
+}
diff --git a/js/dojo-1.6/dojox/rpc/SMDLibrary/yahoo.smd b/js/dojo-1.6/dojox/rpc/SMDLibrary/yahoo.smd
new file mode 100644
index 0000000..831e0b1
--- /dev/null
+++ b/js/dojo-1.6/dojox/rpc/SMDLibrary/yahoo.smd
@@ -0,0 +1,519 @@
+{
+ "SMDVersion": "2.0",
+ // FIXME: is this the kind of value we're supposed to use here?
+ "id": "http://developer.yahoo.com/search/",
+ "description": "Yahoo's search API",
+
+ transport: "JSONP",
+ envelope: "URL",
+ additionalParameters: true,
+ parameters: [
+ { name: "appid", optional: false, "default": "dojotoolkit" },
+ { name: "output", optional: false, "default": "json" }
+ ],
+
+ // FIXME: Quite a few of these APIs can take multiple entries for the same parameter, to behave
+ // as multi-select options. How should we handle these?
+
+ // ANSWER: JSON Schema defines this aspect of SMD, enumeration of possible values is handled
+ // with an "options" attribute. For example:
+ // { name: "search_in", type: "string", optional: true, "default": "all", options:["all", "question", "best_answer"]}, // can be "all", "question", "best_answer"
+
+ services: {
+ //
+ // ANSWERS
+ //
+ // FIXME: Some of these API endpoints' names only make sense when you know they're in the
+ // Yahoo Answers part of the API; just reading a flat listing of methods in this SMD
+ // likely won't have enough information about what they do. Should we split this up?
+
+ // http://developer.yahoo.com/answers/V1/questionSearch.html
+ questionSearch: {
+ target: "http://answers.yahooapis.com/AnswersService/V1/questionSearch",
+ parameters: [
+ { name: "query", type: "string", optional: false, "default": "" },
+ { name: "search_in", type: "string", optional: true, "default": "all" }, // can be "all", "question", "best_answer"
+ { name: "category_id", type: "integer", optional: true, "default": null }, // one of (category_id, category_name) is required
+ { name: "category_name", type: "string", optional: true, "default": null },
+ { name: "region", type: "string", optional: true, "default": "us" }, // can be "us", "uk", "ca", "au", "in", "es", "br", "ar", "mx", "e1", "it", "de", "fr", "sg"
+ { name: "date_range", type: "string", optional: true, "default": "all" }, // can be "all", "7", "7-30", "30-60", "60-90", "more90"
+ { name: "sort", type: "string", optional: true, "default": "relevance" }, // can be "relevance", "date_desc", "date_asc"
+ { name: "type", type: "string", optional: true, "default": "all" }, // can be "all", "resolved", "open", "undecided"
+ { name: "start", type: "integer", optional: true, "default": 0 },
+ { name: "results", type: "integer", optional: true, "default": 10 } // max 50
+ ]
+ },
+
+ // http://developer.yahoo.com/answers/V1/getByCategory.html
+ getByCategory: {
+ target: "http://answers.yahooapis.com/AnswersService/V1/getByCategory",
+ parameters: [
+ { name: "category_id", type: "integer", optional: true, "default": null }, // one of (category_id, category_name) is required
+ { name: "category_name", type: "string", optional: true, "default": null },
+ { name: "type", type: "string", optional: true, "default": "all" }, // can be "all", "resolved", "open", "undecided"
+ { name: "region", type: "string", optional: true, "default": "us" }, // can be "us", "uk", "ca", "au", "in", "es", "br", "ar", "mx", "e1", "it", "de", "fr", "sg"
+ { name: "sort", type: "string", optional: true, "default": "date_desc" }, // can be "date_desc", "date_asc", "ans_count_desc", "ans_count_asc"
+ { name: "start", type: "integer", optional: true, "default": 0 },
+ { name: "results", type: "integer", optional: true, "default": 10 } // max 50
+ ]
+ },
+
+ // http://developer.yahoo.com/answers/V1/getQuestion.html
+ getQuestion: {
+ target: "http://answers.yahooapis.com/AnswersService/V1/getQuestion",
+ parameters: [
+ { name: "question_id", type: "string", optional: true, "default": null }
+ ]
+ },
+
+ // http://developer.yahoo.com/answers/V1/getByUser.html
+ getByUser: {
+ target: "http://answers.yahooapis.com/AnswersService/V1/getByUser",
+ parameters: [
+ { name: "user_id", type: "string", optional: false, "default": "" },
+ { name: "type", type: "string", optional: true, "default": "all" }, // can be "all", "resolved", "open", "undecided"
+ { name: "filter", type: "string", optional: true, "default": "question" }, // can be "question", "answer", "best_answer"
+ { name: "sort", type: "string", optional: true, "default": "date_desc" }, // can be "date_desc", "date_asc", "ans_count_desc", "ans_count_asc"
+ { name: "start", type: "integer", optional: true, "default": 0 },
+ { name: "results", type: "integer", optional: true, "default": 10 } // max 50
+ ]
+ },
+
+ //
+ // AUDIO SEARCH
+ //
+
+ // http://developer.yahoo.com/search/audio/V1/artistSearch.html
+ artistSearch: {
+ target: "http://search.yahooapis.com/AudioSearchService/V1/artistSearch",
+ parameters: [
+ { name: "artist", type: "string", optional: true, "default": "" }, // one of (artist, artistid) is required
+ { name: "artistid", type: "string", optional: true, "default": "" },
+ { name: "type", type: "string", optional: true, "default": "all" }, // can be "all", "any", "phrase"
+ { name: "results", type: "integer", optional: true, "default": 10 }, // max 50
+ { name: "start", type: "integer", optional: true, "default": 1 }
+ ]
+ },
+
+ // http://developer.yahoo.com/search/audio/V1/albumSearch.html
+ albumSearch: {
+ target: "http://search.yahooapis.com/AudioSearchService/V1/albumSearch",
+ parameters: [
+ { name: "artist", type: "string", optional: true, "default": "" },
+ { name: "artistid", type: "string", optional: true, "default": "" },
+ { name: "album", type: "string", optional: true, "default": "" },
+ { name: "albumid", type: "string", optional: true, "default": "" },
+ { name: "type", type: "string", optional: true, "default": "all" }, // can be "all", "any", "phrase"
+ { name: "results", type: "integer", optional: true, "default": 10 }, // max 50
+ { name: "start", type: "integer", optional: true, "default": 1 }
+ ]
+ },
+
+ // http://developer.yahoo.com/search/audio/V1/songSearch.html
+ songSearch: {
+ // beware, this method has returned many a JSON string containing syntax error(s)
+ target: "http://search.yahooapis.com/AudioSearchService/V1/songSearch",
+ parameters: [
+ { name: "artist", type: "string", optional: true, "default": "" },
+ { name: "artistid", type: "string", optional: true, "default": "" },
+ { name: "album", type: "string", optional: true, "default": "" },
+ { name: "albumid", type: "string", optional: true, "default": "" },
+ { name: "song", type: "string", optional: true, "default": "" },
+ { name: "songid", type: "string", optional: true, "default": "" },
+ { name: "type", type: "string", optional: true, "default": "all" }, // can be "all", "any", "phrase"
+ { name: "results", type: "integer", optional: true, "default": 10 }, // max 50
+ { name: "start", type: "integer", optional: true, "default": 1 }
+ ]
+ },
+
+ // http://developer.yahoo.com/search/audio/V1/songDownloadLocation.html
+ songDownloadLocation: {
+ target: "http://search.yahooapis.com/AudioSearchService/V1/songDownloadLocation",
+ parameters: [
+ { name: "songid", type: "string", optional: false, "default": "" },
+ { name: "results", type: "integer", optional: true, "default": 10 }, // max 50
+ { name: "start", type: "integer", optional: true, "default": 1 },
+ { name: "source", type: "string", optional: true, "default": "" } // can be "audiolunchbox", "artistdirect", "buymusic", "dmusic", "emusic", "epitonic", "garageband", "itunes", "yahoo", "livedownloads", "mp34u", "msn", "musicmatch", "mapster", "passalong", "rhapsody", "soundclick", "theweb"
+ ]
+ },
+
+ //
+ // CONTENT ANALYSIS
+ //
+
+ // http://developer.yahoo.com/search/content/V1/termExtraction.html
+ termExtraction: {
+ // FIXME: the API docs say to submit this as a POST, but we need JSONP for cross-domain, right?
+ // transport: "POST",
+ target: "http://search.yahooapis.com/ContentAnalysisService/V1/termExtraction",
+ parameters: [
+ { name: "context", type: "string", optional: false, "default": "" },
+ { name: "query", type: "string", optional: true, "default": "" }
+ ]
+ },
+
+ //
+ // CONTEXT SEARCH
+ //
+
+ // http://developer.yahoo.com/search/content/V1/contextSearch.html
+ contextSearch: {
+ target: "http://search.yahooapis.com/WebSearchService/V1/contextSearch",
+ parameters: [
+ { name: "query", type: "string", optional: true, "default": "" },
+ { name: "context", type: "string", optional: false, "default": "" },
+ { name: "results", type: "integer", optional: true, "default": 10 }, // max 100
+ { name: "start", type: "integer", optional: true, "default": 1 },
+ { name: "format", type: "string", optional: true, "default": "any" }, // can be "any", "html", "msword", "pdf", "ppt", "rss", "txt", "xls"
+ { name: "adult_ok", type: "boolean", optional: true, "default": null },
+ { name: "similar_ok", type: "boolean", optional: true, "default": null },
+ { name: "language", type: "string", optional: true, "default": null },
+ { name: "country", type: "string", optional: true, "default": null },
+ { name: "site", type: "string", optional: true, "default": null },
+ { name: "license", type: "string", optional: true, "default": "any" } // can be "any", "cc_any", "cc_commercial", "cc_modifiable"
+ ]
+ },
+
+ //
+ // IMAGE SEARCH
+ //
+
+ // http://developer.yahoo.com/search/image/V1/imageSearch.html
+ imageSearch: {
+ target: "http://search.yahooapis.com/ImageSearchService/V1/imageSearch",
+ parameters: [
+ { name: "query", type: "string", optional: false, "default": "" },
+ { name: "type", type: "string", optional: true, "default": "any" }, // can be "all", "any", "phrase"
+ { name: "results", type: "integer", optional: true, "default": 10 }, // max 50
+ { name: "start", type: "integer", optional: true, "default": 1 },
+ { name: "format", type: "string", optional: true, "default": "any" }, // can be "any", "bmp", "gif", "jpeg", "png"
+ { name: "adult_ok", type: "boolean", optional: true, "default": null },
+ { name: "coloration", type: "string", optional: true, "default": "any" }, // can be "any", "color", "bw"
+ { name: "site", type: "string", optional: true, "default": null }
+ ]
+ },
+
+ //
+ // LOCAL SEARCH
+ //
+
+ // http://developer.yahoo.com/search/local/V3/localSearch.html
+ localSearch: {
+ target: "http://local.yahooapis.com/LocalSearchService/V3/localSearch",
+ parameters: [
+ { name: "query", type: "string", optional: true, "default": "" }, // optional, but one of (query, listing_id) is required
+ { name: "listing_id", type: "string", optional: true, "default": "" },
+ { name: "results", type: "integer", optional: true, "default": 10 }, // max 20
+ { name: "start", type: "integer", optional: true, "default": 1 },
+ { name: "sort", type: "string", optional: true, "default": "relevance" }, // can be "relevance", "title", "distance", "rating"
+ { name: "radius", type: "float", optional: true }, // the default varies according to location
+ { name: "street", type: "string", optional: true, "default": null },
+ { name: "city", type: "string", optional: true, "default": null },
+ { name: "state", type: "string", optional: true, "default": null }, // full name or two-letter abbreviation
+ { name: "zip", type: "any", optional: true, "default": null }, // ddddd or ddddd-dddd format
+ { name: "location", type: "string", optional: true, "default": null }, // free text, supersedes the street, city, state, zip fields
+ { name: "latitude", type: "float", optional: true }, // -90 to 90
+ { name: "longitude", type: "float", optional: true }, // -180 to 180
+ { name: "category", type: "integer", optional: true },
+ { name: "omit_category", type: "integer", optional: true },
+ { name: "minimum_rating", type: "integer", optional: true }
+ ]
+ },
+
+ // http://developer.yahoo.com/local/V1/collectionSearch.html
+ collectionSearch: {
+ target: "http://collections.local.yahooapis.com/LocalSearchService/V1/collectionSearch",
+ parameters: [
+ { name: "query", type: "string", optional: true, "default": "" }, // optional, but at least one of (query, username) is required
+ { name: "username", type: "string", optional: true, "default": "" },
+ { name: "city", type: "string", optional: true, "default": null },
+ { name: "results", type: "integer", optional: true, "default": 10 }, // max 50
+ { name: "start", type: "integer", optional: true, "default": 1 }
+ ]
+ },
+
+ // http://developer.yahoo.com/local/V1/getCollection.html
+ getCollection: {
+ target: "http://collections.local.yahooapis.com/LocalSearchService/V1/getCollection",
+ parameters: [
+ { name: "collection_id", type: "integer", optional: false, "default": "" }
+ ]
+ },
+
+ //
+ // MY WEB 2.0
+ //
+
+ // http://developer.yahoo.com/search/myweb/V1/urlSearch.html
+ urlSearch: {
+ target: "http://search.yahooapis.com/MyWebService/V1/urlSearch",
+ parameters: [
+ { name: "tag", type: "string", optional: true, "default": "" },
+ { name: "yahooid", type: "string", optional: true, "default": "" },
+ { name: "sort", type: "string", optional: true, "default": "date" }, // can be "date", "title", "url"
+ { name: "reverse_sort", type: "boolean", optional: true, "default": 0 },
+ { name: "results", type: "integer", optional: true, "default": 10 }, // max 50
+ { name: "start", type: "integer", optional: true, "default": 1 }
+ ]
+ },
+
+ // http://developer.yahoo.com/search/myweb/V1/tagSearch.html
+ tagSearch: {
+ target: "http://search.yahooapis.com/MyWebService/V1/tagSearch",
+ parameters: [
+ { name: "url", type: "string", optional: true, "default": "" },
+ { name: "yahooid", type: "string", optional: true, "default": "" },
+ { name: "sort", type: "string", optional: true, "default": "popularity" }, // can be "popularity", "tag", "date"
+ { name: "reverse_sort", type: "boolean", optional: true, "default": 0 },
+ { name: "results", type: "integer", optional: true, "default": 10 }, // max 50
+ { name: "start", type: "integer", optional: true, "default": 1 }
+ ]
+ },
+
+ // http://developer.yahoo.com/search/myweb/V1/relatedTags.html
+ relatedTags: {
+ target: "http://search.yahooapis.com/MyWebService/V1/relatedTags",
+ parameters: [
+ { name: "tag", type: "string", optional: false, "default": "" },
+ { name: "yahooid", type: "string", optional: true, "default": "" },
+ { name: "sort", type: "string", optional: true, "default": "popularity" }, // can be "popularity", "tag", "date"
+ { name: "reverse_sort", type: "boolean", optional: true, "default": 0 },
+ { name: "results", type: "integer", optional: true, "default": 10 }, // max 50
+ { name: "start", type: "integer", optional: true, "default": 1 }
+ ]
+ },
+
+ //
+ // NEWS SEARCH
+ //
+
+ // http://developer.yahoo.com/search/news/V1/newsSearch.html
+ newsSearch: {
+ target: "http://search.yahooapis.com/NewsSearchService/V1/newsSearch",
+ parameters: [
+ { name: "query", type: "string", optional: false, "default": "" },
+ { name: "type", type: "string", optional: true, "default": "any" }, // can be "all", "any", "phrase"
+ { name: "results", type: "integer", optional: true, "default": 10 }, // max 50
+ { name: "start", type: "integer", optional: true, "default": 1 },
+ { name: "sort", type: "string", optional: true, "default": "rank" }, // can be "rank", "date"
+ { name: "language", type: "string", optional: true, "default": null },
+ { name: "site", type: "string", optional: true, "default": null }
+ ]
+ },
+
+ //
+ // SHOPPING
+ //
+
+ // http://developer.yahoo.com/shopping/V2/catalogListing.html
+ catalogListing: {
+ target: "http://shopping.yahooapis.com/ShoppingService/V2/catalogListing",
+ parameters: [
+ { name: "catalogid", type: "integer", optional: true, "default": null }, // required if idtype,idvalue are not specified
+ { name: "getlisting", type: "boolean", optional: true, "default": 1 },
+ { name: "getreview", type: "boolean", optional: true, "default": 0 },
+ { name: "getspec", type: "boolean", optional: true, "default": 0 },
+ { name: "idtype", type: "string", optional: true, "default": null }, // can be "upc", "brand,model", "brand,partnum"; required if catalogid is not specified
+ { name: "idvalue", type: "string", optional: true, "default": null }, // required if catalogid is not specified
+ { name: "onlynew", type: "boolean", optional: true, "default": 1 },
+ { name: "reviewstart", type: "integer", optional: true, "default": 1 },
+ { name: "reviewsort", type: "string", optional: true, "default": "mostRecommended_descending" }, // can be "mostRecommended_descending", "mostRecommended_ascending", "latest_descending", "latest_ascending", "highestRated_descending", "highestRated_ascending"
+ { name: "zip", type: "string", optional: true, "default": null }
+ ]
+ },
+
+
+ // http://developer.yahoo.com/shopping/V1/merchantSearch.html
+ merchantSearch: {
+ target: "http://api.shopping.yahoo.com/ShoppingService/V1/merchantSearch",
+ parameters: [
+ { name: "merchantid", type: "integer", optional: false, "default": null }
+ ]
+ },
+
+
+ // http://developer.yahoo.com/shopping/V3/productSearch.html
+ productSearch: {
+ target: "http://shopping.yahooapis.com/ShoppingService/V3/productSearch",
+ parameters: [
+ { name: "query", type: "string", optional: true, "default": "" }, // required if category is not specified
+ { name: "category", type: "any", optional: true, "default": "" }, // required if query is not specified
+ { name: "class", type: "string", optional: true, "default": null }, // can be "catalogs", "freeoffers", "paidoffers"; defaults to all three of these
+ { name: "department", type: "integer", optional: true, "default": null },
+ { name: "highestprice", type: "float", optional: true, "default": null },
+ { name: "lowestprice", type: "float", optional: true, "default": null },
+ { name: "merchantId", type: "integer", optional: true, "default": null },
+ { name: "refinement", type: "string", optional: true, "default": null }, // used only if category is specified
+ { name: "results", type: "integer", optional: true, "default": 10 }, // 1-50
+ { name: "show_numratings", type: "boolean", optional: true, "default": 0 },
+ { name: "show_narrowing", type: "boolean", optional: true, "default": 1 },
+ { name: "sort", type: "string", optional: true }, // can be "price_ascending", "price_descending", "userrating_ascending", "userrating_descending"; omitted, the default is to sort by relevance
+ { name: "start", type: "integer", optional: true, "default": 1 } // 1-300
+ ]
+ },
+
+ //
+ // SITE EXPLORER
+ //
+
+ // http://developer.yahoo.com/search/siteexplorer/V1/inlinkData.html
+ inlinkData: {
+ target: "http://search.yahooapis.com/SiteExplorerService/V1/inlinkData",
+ parameters: [
+ { name: "query", type: "string", optional: false, "default": "" },
+ { name: "results", type: "integer", optional: true, "default": 50 }, // max 100
+ { name: "start", type: "integer", optional: true, "default": 1 },
+ { name: "entire_site", type: "boolean", optional: true, "default": null },
+ { name: "omit_inlinks", type: "string", optional: true, "default": "none" } // can be "none", "domain", "subdomain"
+ ]
+ },
+
+ // http://developer.yahoo.com/search/siteexplorer/V1/pageData.html
+ pageData: {
+ target: "http://search.yahooapis.com/SiteExplorerService/V1/pageData",
+ parameters: [
+ { name: "query", type: "string", optional: false, "default": "" },
+ { name: "results", type: "integer", optional: true, "default": 50 }, // max 100
+ { name: "start", type: "integer", optional: true, "default": 1 },
+ { name: "domain_only", type: "boolean", optional: true, "default": null }
+ ]
+ },
+
+ // http://developer.yahoo.com/search/siteexplorer/V1/ping.html
+ ping: {
+ target: "http://search.yahooapis.com/SiteExplorerService/V1/ping",
+ parameters: [
+ { name: "sitemap", type: "string", optional: false, "default": "" }
+ ]
+ },
+
+ // http://developer.yahoo.com/search/siteexplorer/V1/updateNotification.html
+ updateNotification: {
+ target: "http://search.yahooapis.com/SiteExplorerService/V1/updateNotification",
+ parameters: [
+ { name: "url", type: "string", optional: false, "default": "" }
+ ]
+ },
+
+ //
+ // TRAFFIC
+ //
+
+ // http://developer.yahoo.com/traffic/rest/V1/index.html
+ trafficData: {
+ target: "http://local.yahooapis.com/MapsService/V1/trafficData",
+ parameters: [
+ { name: "street", type: "string", optional: true, "default": "" },
+ { name: "city", type: "string", optional: true, "default": "" },
+ { name: "state", type: "string", optional: true, "default": null }, // full name or two-letter abbreviation
+ { name: "zip", type: "any", optional: true, "default": null }, // ddddd or ddddd-dddd format
+ { name: "location", type: "string", optional: true, "default": null }, // free text, supersedes the street, city, state, zip fields
+ { name: "latitude", type: "float", optional: true }, // -90 to 90
+ { name: "longitude", type: "float", optional: true }, // -180 to 180
+ { name: "severity", type: "integer", optional: true, "default": 1 }, // can be 1-5
+ { name: "zoom", type: "integer", optional: true, "default": 6 }, // can be 1-12
+ { name: "radius", type: "float", optional: true }, // in miles, default varies with location; ignored if zoom is specified
+ { name: "include_map", type: "boolean", optional: true, "default": 0 },
+ { name: "image_type", type: "string", optional: true, "default": "png" }, // can be "png" or "gif"
+ { name: "image_height", type: "integer", optional: true, "default": 500 }, // in pixels, can be 10-2000
+ { name: "image_width", type: "integer", optional: true, "default": 620 } // in pixels, can be 10-2000
+ ]
+ },
+
+ //
+ // TRAVEL
+ //
+
+ // http://developer.yahoo.com/travel/tripservice/V1.1/tripSearch.html
+ tripSearch: {
+ target: "http://travel.yahooapis.com/TripService/V1.1/tripSearch",
+ parameters: [
+ { name: "query", type: "string", optional: true, "default": "" },
+ { name: "results", type: "integer", optional: true, "default": 10 }, // max 50
+ { name: "start", type: "integer", optional: true, "default": 1 }
+ ]
+ },
+
+ // http://developer.yahoo.com/travel/tripservice/V1.1/getTrip.html
+ getTrip: {
+ target: "http://travel.yahooapis.com/TripService/V1.1/getTrip",
+ parameters: [
+ { name: "id", type: "integer", optional: false, "default": null }
+ ]
+ },
+
+ //
+ // UTILITY SERVICES
+ //
+
+ // http://developer.yahoo.com/util/timeservice/V1/getTime.html
+ /* RGG: commented out because it refuses to return JSON format even when you tell it
+ to do so (it returns a <script> tag)
+ getTime: {
+ target: "http://developer.yahooapis.com/TimeService/V1/getTime",
+ parameters: [
+ { name: "format", type: "string", optional: true, "default": "unix" } // can be "unix" for unix timestamp, "ms" for milliseconds
+ ]
+ },
+ */
+
+ //
+ // VIDEO SEARCH
+ //
+
+ // http://developer.yahoo.com/search/video/V1/videoSearch.html
+ videoSearch: {
+ target: "http://search.yahooapis.com/VideoSearchService/V1/videoSearch",
+ parameters: [
+ { name: "query", type: "string", optional: false, "default": "" },
+ { name: "type", type: "string", optional: true, "default": "any" }, // can be "all", "any", "phrase"
+ { name: "results", type: "integer", optional: true, "default": 10 }, // max 50
+ { name: "start", type: "integer", optional: true, "default": 1 },
+ { name: "format", type: "string", optional: true, "default": "any" }, // can be "any", "avi", "flash", "mpeg", "msmedia", "quicktime", "realmedia"
+ { name: "adult_ok", type: "boolean", optional: true, "default": null },
+ { name: "site", type: "string", optional: true, "default": null }
+ ]
+ },
+
+ //
+ // WEB SEARCH
+ //
+
+ // http://developer.yahoo.com/search/web/V1/webSearch.html
+ webSearch: {
+ target: "http://search.yahooapis.com/WebSearchService/V1/webSearch",
+ parameters: [
+ { name: "query", type: "string", optional: false, "default": "" }, // must be less than 1kb
+ { name: "region", type: "string", optional: true, "default": "us" },
+ { name: "type", type: "string", optional: true, "default": "any" }, // can be "all", "any", "phrase"
+ { name: "results", type: "integer", optional: true, "default": 10 }, // max 100
+ { name: "start", type: "integer", optional: true, "default": 1 },
+ { name: "format", type: "string", optional: true, "default": "any" }, // can be "any", "html", "msword", "pdf", "ppt", "rss", "txt", "xls"
+ { name: "adult_ok", type: "boolean", optional: true, "default": null },
+ { name: "similar_ok", type: "boolean", optional: true, "default": null },
+ { name: "language", type: "string", optional: true, "default": null },
+ { name: "country", type: "string", optional: true, "default": null },
+ { name: "site", type: "string", optional: true, "default": null },
+ { name: "subscription", type: "string", optional: true, "default": null },
+ { name: "license", type: "string", optional: true, "default": "any" } // can be "any", "cc_any", "cc_commercial", "cc_modifiable"
+ ]
+ },
+
+ // http://developer.yahoo.com/search/web/V1/spellingSuggestion.html
+ spellingSuggestion: {
+ target: "http://search.yahooapis.com/WebSearchService/V1/spellingSuggestion",
+ parameters: [
+ { name: "query", type: "string", optional: false, "default": "" }
+ ]
+ },
+
+ // http://developer.yahoo.com/search/web/V1/relatedSuggestion.html
+ relatedSuggestion: {
+ target: "http://search.yahooapis.com/WebSearchService/V1/relatedSuggestion",
+ parameters: [
+ { name: "query", type: "string", optional: false, "default": "" },
+ { name: "results", type: "integer", optional: true, "default": 10 } // max 50
+ ]
+ }
+ }
+}
diff --git a/js/dojo-1.6/dojox/rpc/Service.js b/js/dojo-1.6/dojox/rpc/Service.js
new file mode 100644
index 0000000..4bbeb9a
--- /dev/null
+++ b/js/dojo-1.6/dojox/rpc/Service.js
@@ -0,0 +1,332 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.rpc.Service"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.rpc.Service"] = true;
+dojo.provide("dojox.rpc.Service");
+dojo.require("dojo.AdapterRegistry");
+
+
+
+dojo.declare("dojox.rpc.Service", null, {
+ constructor: function(smd, options){
+ // summary:
+ // Take a string as a url to retrieve an smd or an object that is an smd or partial smd to use
+ // as a definition for the service
+ //
+ // smd: object
+ // Takes a number of properties as kwArgs for defining the service. It also
+ // accepts a string. When passed a string, it is treated as a url from
+ // which it should synchronously retrieve an smd file. Otherwise it is a kwArgs
+ // object. It accepts serviceUrl, to manually define a url for the rpc service
+ // allowing the rpc system to be used without an smd definition. strictArgChecks
+ // forces the system to verify that the # of arguments provided in a call
+ // matches those defined in the smd. smdString allows a developer to pass
+ // a jsonString directly, which will be converted into an object or alternatively
+ // smdObject is accepts an smdObject directly.
+ //
+ // description:
+ // dojox.rpc.Service must be loaded prior to any plugin services like dojox.rpc.Rest
+ // dojox.rpc.JsonRpc in order for them to register themselves, otherwise you get
+ // a "No match found" error.
+ var url;
+ var self = this;
+ function processSmd(smd){
+ smd._baseUrl = new dojo._Url((dojo.isBrowser ? location.href : dojo.config.baseUrl) ,url || '.') + '';
+ self._smd = smd;
+
+ //generate the methods
+ for(var serviceName in self._smd.services){
+ var pieces = serviceName.split("."); // handle "namespaced" services by breaking apart by .
+ var current = self;
+ for(var i=0; i< pieces.length-1; i++){
+ // create or reuse each object as we go down the chain
+ current = current[pieces[i]] || (current[pieces[i]] = {});
+ }
+ current[pieces[pieces.length-1]]= self._generateService(serviceName, self._smd.services[serviceName]);
+ }
+ }
+ if(smd){
+ //ifthe arg is a string, we assume it is a url to retrieve an smd definition from
+ if( (dojo.isString(smd)) || (smd instanceof dojo._Url)){
+ if(smd instanceof dojo._Url){
+ url = smd + "";
+ }else{
+ url = smd;
+ }
+
+ var text = dojo._getText(url);
+ if(!text){
+ throw new Error("Unable to load SMD from " + smd);
+ }else{
+ processSmd(dojo.fromJson(text));
+ }
+ }else{
+ processSmd(smd);
+ }
+ }
+
+ this._options = (options ? options : {});
+ this._requestId = 0;
+ },
+
+ _generateService: function(serviceName, method){
+ if(this[method]){
+ throw new Error("WARNING: "+ serviceName+ " already exists for service. Unable to generate function");
+ }
+ method.name = serviceName;
+ var func = dojo.hitch(this, "_executeMethod",method);
+ var transport = dojox.rpc.transportRegistry.match(method.transport || this._smd.transport);
+ if(transport.getExecutor){
+ func = transport.getExecutor(func,method,this);
+ }
+ var schema = method.returns || (method._schema = {}); // define the schema
+ var servicePath = '/' + serviceName +'/';
+ // schemas are minimally used to track the id prefixes for the different services
+ schema._service = func;
+ func.servicePath = servicePath;
+ func._schema = schema;
+ func.id = dojox.rpc.Service._nextId++;
+ return func;
+ },
+ _getRequest: function(method,args){
+ var smd = this._smd;
+ var envDef = dojox.rpc.envelopeRegistry.match(method.envelope || smd.envelope || "NONE");
+ var parameters = (method.parameters || []).concat(smd.parameters || []);
+ if(envDef.namedParams){
+ // the serializer is expecting named params
+ if((args.length==1) && dojo.isObject(args[0])){
+ // looks like we have what we want
+ args = args[0];
+ }else{
+ // they provided ordered, must convert
+ var data={};
+ for(var i=0;i<method.parameters.length;i++){
+ if(typeof args[i] != "undefined" || !method.parameters[i].optional){
+ data[method.parameters[i].name]=args[i];
+ }
+ }
+ args = data;
+ }
+ if(method.strictParameters||smd.strictParameters){
+ //remove any properties that were not defined
+ for(i in args){
+ var found=false;
+ for(var j=0; j<parameters.length;j++){
+ if(parameters[i].name==i){ found=true; }
+ }
+ if(!found){
+ delete args[i];
+ }
+ }
+
+ }
+ // setting default values
+ for(i=0; i< parameters.length; i++){
+ var param = parameters[i];
+ if(!param.optional && param.name && !args[param.name]){
+ if(param["default"]){
+ args[param.name] = param["default"];
+ }else if(!(param.name in args)){
+ throw new Error("Required parameter " + param.name + " was omitted");
+ }
+ }
+ }
+ }else if(parameters && parameters[0] && parameters[0].name && (args.length==1) && dojo.isObject(args[0])){
+ // looks like named params, we will convert
+ if(envDef.namedParams === false){
+ // the serializer is expecting ordered params, must be ordered
+ args = dojox.rpc.toOrdered(parameters, args);
+ }else{
+ // named is ok
+ args = args[0];
+ }
+ }
+
+ if(dojo.isObject(this._options)){
+ args = dojo.mixin(args, this._options);
+ }
+
+ var schema = method._schema || method.returns; // serialize with the right schema for the context;
+ var request = envDef.serialize.apply(this, [smd, method, args]);
+ request._envDef = envDef;// save this for executeMethod
+ var contentType = (method.contentType || smd.contentType || request.contentType);
+
+ // this allows to mandate synchronous behavior from elsewhere when necessary, this may need to be changed to be one-shot in FF3 new sync handling model
+ return dojo.mixin(request, {
+ sync: dojox.rpc._sync,
+ contentType: contentType,
+ headers: method.headers || smd.headers || request.headers || {},
+ target: request.target || dojox.rpc.getTarget(smd, method),
+ transport: method.transport || smd.transport || request.transport,
+ envelope: method.envelope || smd.envelope || request.envelope,
+ timeout: method.timeout || smd.timeout,
+ callbackParamName: method.callbackParamName || smd.callbackParamName,
+ rpcObjectParamName: method.rpcObjectParamName || smd.rpcObjectParamName,
+ schema: schema,
+ handleAs: request.handleAs || "auto",
+ preventCache: method.preventCache || smd.preventCache,
+ frameDoc: this._options.frameDoc || undefined
+ });
+ },
+ _executeMethod: function(method){
+ var args = [];
+ var i;
+ for(i=1; i< arguments.length; i++){
+ args.push(arguments[i]);
+ }
+ var request = this._getRequest(method,args);
+ var deferred = dojox.rpc.transportRegistry.match(request.transport).fire(request);
+
+ deferred.addBoth(function(results){
+ return request._envDef.deserialize.call(this,results);
+ });
+ return deferred;
+ }
+});
+
+dojox.rpc.getTarget = function(smd, method){
+ var dest=smd._baseUrl;
+ if(smd.target){
+ dest = new dojo._Url(dest,smd.target) + '';
+ }
+ if(method.target){
+ dest = new dojo._Url(dest,method.target) + '';
+ }
+ return dest;
+};
+
+dojox.rpc.toOrdered=function(parameters, args){
+ if(dojo.isArray(args)){ return args; }
+ var data=[];
+ for(var i=0;i<parameters.length;i++){
+ data.push(args[parameters[i].name]);
+ }
+ return data;
+};
+
+dojox.rpc.transportRegistry = new dojo.AdapterRegistry(true);
+dojox.rpc.envelopeRegistry = new dojo.AdapterRegistry(true);
+//Built In Envelopes
+
+dojox.rpc.envelopeRegistry.register(
+ "URL",
+ function(str){ return str == "URL"; },
+ {
+ serialize:function(smd, method, data ){
+ var d = dojo.objectToQuery(data);
+ return {
+ data: d,
+ transport:"POST"
+ };
+ },
+ deserialize:function(results){
+ return results;
+ },
+ namedParams: true
+ }
+);
+
+dojox.rpc.envelopeRegistry.register(
+ "JSON",
+ function(str){ return str == "JSON"; },
+ {
+ serialize: function(smd, method, data){
+ var d = dojo.toJson(data);
+
+ return {
+ data: d,
+ handleAs: 'json',
+ contentType : 'application/json'
+ };
+ },
+ deserialize: function(results){
+ return results;
+ }
+ }
+);
+dojox.rpc.envelopeRegistry.register(
+ "PATH",
+ function(str){ return str == "PATH"; },
+ {
+ serialize:function(smd, method, data){
+ var i;
+ var target = dojox.rpc.getTarget(smd, method);
+ if(dojo.isArray(data)){
+ for(i = 0; i < data.length;i++){
+ target += '/' + data[i];
+ }
+ }else{
+ for(i in data){
+ target += '/' + i + '/' + data[i];
+ }
+ }
+
+ return {
+ data:'',
+ target: target
+ };
+ },
+ deserialize:function(results){
+ return results;
+ }
+ }
+);
+
+
+
+//post is registered first because it is the default;
+dojox.rpc.transportRegistry.register(
+ "POST",
+ function(str){ return str == "POST"; },
+ {
+ fire:function(r){
+ r.url = r.target;
+ r.postData = r.data;
+ return dojo.rawXhrPost(r);
+ }
+ }
+);
+
+dojox.rpc.transportRegistry.register(
+ "GET",
+ function(str){ return str == "GET"; },
+ {
+ fire: function(r){
+ r.url= r.target + (r.data ? '?' + ((r.rpcObjectParamName) ? r.rpcObjectParamName + '=' : '') + r.data : '');
+ return dojo.xhrGet(r);
+ }
+ }
+);
+
+
+//only works ifyou include dojo.io.script
+dojox.rpc.transportRegistry.register(
+ "JSONP",
+ function(str){ return str == "JSONP"; },
+ {
+ fire: function(r){
+ r.url = r.target + ((r.target.indexOf("?") == -1) ? '?' : '&') + ((r.rpcObjectParamName) ? r.rpcObjectParamName + '=' : '') + r.data;
+ r.callbackParamName = r.callbackParamName || "callback";
+ return dojo.io.script.get(r);
+ }
+ }
+);
+dojox.rpc.Service._nextId = 1;
+
+dojo._contentHandlers.auto = function(xhr){
+ // automatically choose the right handler based on the returned content type
+ var handlers = dojo._contentHandlers;
+ var retContentType = xhr.getResponseHeader("Content-Type");
+ var results = !retContentType ? handlers.text(xhr) :
+ retContentType.match(/\/.*json/) ? handlers.json(xhr) :
+ retContentType.match(/\/javascript/) ? handlers.javascript(xhr) :
+ retContentType.match(/\/xml/) ? handlers.xml(xhr) : handlers.text(xhr);
+ return results;
+};
+
+}
diff --git a/js/dojo-1.6/dojox/rpc/Service.xd.js b/js/dojo-1.6/dojox/rpc/Service.xd.js
new file mode 100644
index 0000000..e82fe6a
--- /dev/null
+++ b/js/dojo-1.6/dojox/rpc/Service.xd.js
@@ -0,0 +1,337 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.rpc.Service"],
+["require", "dojo.AdapterRegistry"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.rpc.Service"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.rpc.Service"] = true;
+dojo.provide("dojox.rpc.Service");
+dojo.require("dojo.AdapterRegistry");
+
+
+
+dojo.declare("dojox.rpc.Service", null, {
+ constructor: function(smd, options){
+ // summary:
+ // Take a string as a url to retrieve an smd or an object that is an smd or partial smd to use
+ // as a definition for the service
+ //
+ // smd: object
+ // Takes a number of properties as kwArgs for defining the service. It also
+ // accepts a string. When passed a string, it is treated as a url from
+ // which it should synchronously retrieve an smd file. Otherwise it is a kwArgs
+ // object. It accepts serviceUrl, to manually define a url for the rpc service
+ // allowing the rpc system to be used without an smd definition. strictArgChecks
+ // forces the system to verify that the # of arguments provided in a call
+ // matches those defined in the smd. smdString allows a developer to pass
+ // a jsonString directly, which will be converted into an object or alternatively
+ // smdObject is accepts an smdObject directly.
+ //
+ // description:
+ // dojox.rpc.Service must be loaded prior to any plugin services like dojox.rpc.Rest
+ // dojox.rpc.JsonRpc in order for them to register themselves, otherwise you get
+ // a "No match found" error.
+ var url;
+ var self = this;
+ function processSmd(smd){
+ smd._baseUrl = new dojo._Url((dojo.isBrowser ? location.href : dojo.config.baseUrl) ,url || '.') + '';
+ self._smd = smd;
+
+ //generate the methods
+ for(var serviceName in self._smd.services){
+ var pieces = serviceName.split("."); // handle "namespaced" services by breaking apart by .
+ var current = self;
+ for(var i=0; i< pieces.length-1; i++){
+ // create or reuse each object as we go down the chain
+ current = current[pieces[i]] || (current[pieces[i]] = {});
+ }
+ current[pieces[pieces.length-1]]= self._generateService(serviceName, self._smd.services[serviceName]);
+ }
+ }
+ if(smd){
+ //ifthe arg is a string, we assume it is a url to retrieve an smd definition from
+ if( (dojo.isString(smd)) || (smd instanceof dojo._Url)){
+ if(smd instanceof dojo._Url){
+ url = smd + "";
+ }else{
+ url = smd;
+ }
+
+ var text = dojo._getText(url);
+ if(!text){
+ throw new Error("Unable to load SMD from " + smd);
+ }else{
+ processSmd(dojo.fromJson(text));
+ }
+ }else{
+ processSmd(smd);
+ }
+ }
+
+ this._options = (options ? options : {});
+ this._requestId = 0;
+ },
+
+ _generateService: function(serviceName, method){
+ if(this[method]){
+ throw new Error("WARNING: "+ serviceName+ " already exists for service. Unable to generate function");
+ }
+ method.name = serviceName;
+ var func = dojo.hitch(this, "_executeMethod",method);
+ var transport = dojox.rpc.transportRegistry.match(method.transport || this._smd.transport);
+ if(transport.getExecutor){
+ func = transport.getExecutor(func,method,this);
+ }
+ var schema = method.returns || (method._schema = {}); // define the schema
+ var servicePath = '/' + serviceName +'/';
+ // schemas are minimally used to track the id prefixes for the different services
+ schema._service = func;
+ func.servicePath = servicePath;
+ func._schema = schema;
+ func.id = dojox.rpc.Service._nextId++;
+ return func;
+ },
+ _getRequest: function(method,args){
+ var smd = this._smd;
+ var envDef = dojox.rpc.envelopeRegistry.match(method.envelope || smd.envelope || "NONE");
+ var parameters = (method.parameters || []).concat(smd.parameters || []);
+ if(envDef.namedParams){
+ // the serializer is expecting named params
+ if((args.length==1) && dojo.isObject(args[0])){
+ // looks like we have what we want
+ args = args[0];
+ }else{
+ // they provided ordered, must convert
+ var data={};
+ for(var i=0;i<method.parameters.length;i++){
+ if(typeof args[i] != "undefined" || !method.parameters[i].optional){
+ data[method.parameters[i].name]=args[i];
+ }
+ }
+ args = data;
+ }
+ if(method.strictParameters||smd.strictParameters){
+ //remove any properties that were not defined
+ for(i in args){
+ var found=false;
+ for(var j=0; j<parameters.length;j++){
+ if(parameters[i].name==i){ found=true; }
+ }
+ if(!found){
+ delete args[i];
+ }
+ }
+
+ }
+ // setting default values
+ for(i=0; i< parameters.length; i++){
+ var param = parameters[i];
+ if(!param.optional && param.name && !args[param.name]){
+ if(param["default"]){
+ args[param.name] = param["default"];
+ }else if(!(param.name in args)){
+ throw new Error("Required parameter " + param.name + " was omitted");
+ }
+ }
+ }
+ }else if(parameters && parameters[0] && parameters[0].name && (args.length==1) && dojo.isObject(args[0])){
+ // looks like named params, we will convert
+ if(envDef.namedParams === false){
+ // the serializer is expecting ordered params, must be ordered
+ args = dojox.rpc.toOrdered(parameters, args);
+ }else{
+ // named is ok
+ args = args[0];
+ }
+ }
+
+ if(dojo.isObject(this._options)){
+ args = dojo.mixin(args, this._options);
+ }
+
+ var schema = method._schema || method.returns; // serialize with the right schema for the context;
+ var request = envDef.serialize.apply(this, [smd, method, args]);
+ request._envDef = envDef;// save this for executeMethod
+ var contentType = (method.contentType || smd.contentType || request.contentType);
+
+ // this allows to mandate synchronous behavior from elsewhere when necessary, this may need to be changed to be one-shot in FF3 new sync handling model
+ return dojo.mixin(request, {
+ sync: dojox.rpc._sync,
+ contentType: contentType,
+ headers: method.headers || smd.headers || request.headers || {},
+ target: request.target || dojox.rpc.getTarget(smd, method),
+ transport: method.transport || smd.transport || request.transport,
+ envelope: method.envelope || smd.envelope || request.envelope,
+ timeout: method.timeout || smd.timeout,
+ callbackParamName: method.callbackParamName || smd.callbackParamName,
+ rpcObjectParamName: method.rpcObjectParamName || smd.rpcObjectParamName,
+ schema: schema,
+ handleAs: request.handleAs || "auto",
+ preventCache: method.preventCache || smd.preventCache,
+ frameDoc: this._options.frameDoc || undefined
+ });
+ },
+ _executeMethod: function(method){
+ var args = [];
+ var i;
+ for(i=1; i< arguments.length; i++){
+ args.push(arguments[i]);
+ }
+ var request = this._getRequest(method,args);
+ var deferred = dojox.rpc.transportRegistry.match(request.transport).fire(request);
+
+ deferred.addBoth(function(results){
+ return request._envDef.deserialize.call(this,results);
+ });
+ return deferred;
+ }
+});
+
+dojox.rpc.getTarget = function(smd, method){
+ var dest=smd._baseUrl;
+ if(smd.target){
+ dest = new dojo._Url(dest,smd.target) + '';
+ }
+ if(method.target){
+ dest = new dojo._Url(dest,method.target) + '';
+ }
+ return dest;
+};
+
+dojox.rpc.toOrdered=function(parameters, args){
+ if(dojo.isArray(args)){ return args; }
+ var data=[];
+ for(var i=0;i<parameters.length;i++){
+ data.push(args[parameters[i].name]);
+ }
+ return data;
+};
+
+dojox.rpc.transportRegistry = new dojo.AdapterRegistry(true);
+dojox.rpc.envelopeRegistry = new dojo.AdapterRegistry(true);
+//Built In Envelopes
+
+dojox.rpc.envelopeRegistry.register(
+ "URL",
+ function(str){ return str == "URL"; },
+ {
+ serialize:function(smd, method, data ){
+ var d = dojo.objectToQuery(data);
+ return {
+ data: d,
+ transport:"POST"
+ };
+ },
+ deserialize:function(results){
+ return results;
+ },
+ namedParams: true
+ }
+);
+
+dojox.rpc.envelopeRegistry.register(
+ "JSON",
+ function(str){ return str == "JSON"; },
+ {
+ serialize: function(smd, method, data){
+ var d = dojo.toJson(data);
+
+ return {
+ data: d,
+ handleAs: 'json',
+ contentType : 'application/json'
+ };
+ },
+ deserialize: function(results){
+ return results;
+ }
+ }
+);
+dojox.rpc.envelopeRegistry.register(
+ "PATH",
+ function(str){ return str == "PATH"; },
+ {
+ serialize:function(smd, method, data){
+ var i;
+ var target = dojox.rpc.getTarget(smd, method);
+ if(dojo.isArray(data)){
+ for(i = 0; i < data.length;i++){
+ target += '/' + data[i];
+ }
+ }else{
+ for(i in data){
+ target += '/' + i + '/' + data[i];
+ }
+ }
+
+ return {
+ data:'',
+ target: target
+ };
+ },
+ deserialize:function(results){
+ return results;
+ }
+ }
+);
+
+
+
+//post is registered first because it is the default;
+dojox.rpc.transportRegistry.register(
+ "POST",
+ function(str){ return str == "POST"; },
+ {
+ fire:function(r){
+ r.url = r.target;
+ r.postData = r.data;
+ return dojo.rawXhrPost(r);
+ }
+ }
+);
+
+dojox.rpc.transportRegistry.register(
+ "GET",
+ function(str){ return str == "GET"; },
+ {
+ fire: function(r){
+ r.url= r.target + (r.data ? '?' + ((r.rpcObjectParamName) ? r.rpcObjectParamName + '=' : '') + r.data : '');
+ return dojo.xhrGet(r);
+ }
+ }
+);
+
+
+//only works ifyou include dojo.io.script
+dojox.rpc.transportRegistry.register(
+ "JSONP",
+ function(str){ return str == "JSONP"; },
+ {
+ fire: function(r){
+ r.url = r.target + ((r.target.indexOf("?") == -1) ? '?' : '&') + ((r.rpcObjectParamName) ? r.rpcObjectParamName + '=' : '') + r.data;
+ r.callbackParamName = r.callbackParamName || "callback";
+ return dojo.io.script.get(r);
+ }
+ }
+);
+dojox.rpc.Service._nextId = 1;
+
+dojo._contentHandlers.auto = function(xhr){
+ // automatically choose the right handler based on the returned content type
+ var handlers = dojo._contentHandlers;
+ var retContentType = xhr.getResponseHeader("Content-Type");
+ var results = !retContentType ? handlers.text(xhr) :
+ retContentType.match(/\/.*json/) ? handlers.json(xhr) :
+ retContentType.match(/\/javascript/) ? handlers.javascript(xhr) :
+ retContentType.match(/\/xml/) ? handlers.xml(xhr) : handlers.text(xhr);
+ return results;
+};
+
+}
+
+}};});