source: [view]
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;