[483] | 1 | define([ |
---|
| 2 | 'exports', |
---|
| 3 | '../errors/RequestError', |
---|
| 4 | '../errors/CancelError', |
---|
| 5 | '../Deferred', |
---|
| 6 | '../io-query', |
---|
| 7 | '../_base/array', |
---|
| 8 | '../_base/lang', |
---|
| 9 | '../promise/Promise' |
---|
| 10 | ], function(exports, RequestError, CancelError, Deferred, ioQuery, array, lang, Promise){ |
---|
| 11 | exports.deepCopy = function deepCopy(target, source){ |
---|
| 12 | for(var name in source){ |
---|
| 13 | var tval = target[name], |
---|
| 14 | sval = source[name]; |
---|
| 15 | if(tval !== sval){ |
---|
| 16 | if(tval && typeof tval === 'object' && sval && typeof sval === 'object'){ |
---|
| 17 | exports.deepCopy(tval, sval); |
---|
| 18 | }else{ |
---|
| 19 | target[name] = sval; |
---|
| 20 | } |
---|
| 21 | } |
---|
| 22 | } |
---|
| 23 | return target; |
---|
| 24 | }; |
---|
| 25 | |
---|
| 26 | exports.deepCreate = function deepCreate(source, properties){ |
---|
| 27 | properties = properties || {}; |
---|
| 28 | var target = lang.delegate(source), |
---|
| 29 | name, value; |
---|
| 30 | |
---|
| 31 | for(name in source){ |
---|
| 32 | value = source[name]; |
---|
| 33 | |
---|
| 34 | if(value && typeof value === 'object'){ |
---|
| 35 | target[name] = exports.deepCreate(value, properties[name]); |
---|
| 36 | } |
---|
| 37 | } |
---|
| 38 | return exports.deepCopy(target, properties); |
---|
| 39 | }; |
---|
| 40 | |
---|
| 41 | var freeze = Object.freeze || function(obj){ return obj; }; |
---|
| 42 | function okHandler(response){ |
---|
| 43 | return freeze(response); |
---|
| 44 | } |
---|
| 45 | function dataHandler (response) { |
---|
| 46 | return response.data || response.text; |
---|
| 47 | } |
---|
| 48 | |
---|
| 49 | exports.deferred = function deferred(response, cancel, isValid, isReady, handleResponse, last){ |
---|
| 50 | var def = new Deferred(function(reason){ |
---|
| 51 | cancel && cancel(def, response); |
---|
| 52 | |
---|
| 53 | if(!reason || !(reason instanceof RequestError) && !(reason instanceof CancelError)){ |
---|
| 54 | return new CancelError('Request canceled', response); |
---|
| 55 | } |
---|
| 56 | return reason; |
---|
| 57 | }); |
---|
| 58 | |
---|
| 59 | def.response = response; |
---|
| 60 | def.isValid = isValid; |
---|
| 61 | def.isReady = isReady; |
---|
| 62 | def.handleResponse = handleResponse; |
---|
| 63 | |
---|
| 64 | function errHandler(error){ |
---|
| 65 | error.response = response; |
---|
| 66 | throw error; |
---|
| 67 | } |
---|
| 68 | var responsePromise = def.then(okHandler).otherwise(errHandler); |
---|
| 69 | |
---|
| 70 | if(exports.notify){ |
---|
| 71 | responsePromise.then( |
---|
| 72 | lang.hitch(exports.notify, 'emit', 'load'), |
---|
| 73 | lang.hitch(exports.notify, 'emit', 'error') |
---|
| 74 | ); |
---|
| 75 | } |
---|
| 76 | |
---|
| 77 | var dataPromise = responsePromise.then(dataHandler); |
---|
| 78 | |
---|
| 79 | // http://bugs.dojotoolkit.org/ticket/16794 |
---|
| 80 | // The following works around a leak in IE9 through the |
---|
| 81 | // prototype using lang.delegate on dataPromise and |
---|
| 82 | // assigning the result a property with a reference to |
---|
| 83 | // responsePromise. |
---|
| 84 | var promise = new Promise(); |
---|
| 85 | for (var prop in dataPromise) { |
---|
| 86 | if (dataPromise.hasOwnProperty(prop)) { |
---|
| 87 | promise[prop] = dataPromise[prop]; |
---|
| 88 | } |
---|
| 89 | } |
---|
| 90 | promise.response = responsePromise; |
---|
| 91 | freeze(promise); |
---|
| 92 | // End leak fix |
---|
| 93 | |
---|
| 94 | |
---|
| 95 | if(last){ |
---|
| 96 | def.then(function(response){ |
---|
| 97 | last.call(def, response); |
---|
| 98 | }, function(error){ |
---|
| 99 | last.call(def, response, error); |
---|
| 100 | }); |
---|
| 101 | } |
---|
| 102 | |
---|
| 103 | def.promise = promise; |
---|
| 104 | def.then = promise.then; |
---|
| 105 | |
---|
| 106 | return def; |
---|
| 107 | }; |
---|
| 108 | |
---|
| 109 | exports.addCommonMethods = function addCommonMethods(provider, methods){ |
---|
| 110 | array.forEach(methods||['GET', 'POST', 'PUT', 'DELETE'], function(method){ |
---|
| 111 | provider[(method === 'DELETE' ? 'DEL' : method).toLowerCase()] = function(url, options){ |
---|
| 112 | options = lang.delegate(options||{}); |
---|
| 113 | options.method = method; |
---|
| 114 | return provider(url, options); |
---|
| 115 | }; |
---|
| 116 | }); |
---|
| 117 | }; |
---|
| 118 | |
---|
| 119 | exports.parseArgs = function parseArgs(url, options, skipData){ |
---|
| 120 | var data = options.data, |
---|
| 121 | query = options.query; |
---|
| 122 | |
---|
| 123 | if(data && !skipData){ |
---|
| 124 | if(typeof data === 'object'){ |
---|
| 125 | options.data = ioQuery.objectToQuery(data); |
---|
| 126 | } |
---|
| 127 | } |
---|
| 128 | |
---|
| 129 | if(query){ |
---|
| 130 | if(typeof query === 'object'){ |
---|
| 131 | query = ioQuery.objectToQuery(query); |
---|
| 132 | } |
---|
| 133 | if(options.preventCache){ |
---|
| 134 | query += (query ? '&' : '') + 'request.preventCache=' + (+(new Date)); |
---|
| 135 | } |
---|
| 136 | }else if(options.preventCache){ |
---|
| 137 | query = 'request.preventCache=' + (+(new Date)); |
---|
| 138 | } |
---|
| 139 | |
---|
| 140 | if(url && query){ |
---|
| 141 | url += (~url.indexOf('?') ? '&' : '?') + query; |
---|
| 142 | } |
---|
| 143 | |
---|
| 144 | return { |
---|
| 145 | url: url, |
---|
| 146 | options: options, |
---|
| 147 | getHeader: function(headerName){ return null; } |
---|
| 148 | }; |
---|
| 149 | }; |
---|
| 150 | |
---|
| 151 | exports.checkStatus = function(stat){ |
---|
| 152 | stat = stat || 0; |
---|
| 153 | return (stat >= 200 && stat < 300) || // allow any 2XX response code |
---|
| 154 | stat === 304 || // or, get it out of the cache |
---|
| 155 | stat === 1223 || // or, Internet Explorer mangled the status code |
---|
| 156 | !stat; // or, we're Titanium/browser chrome/chrome extension requesting a local file |
---|
| 157 | }; |
---|
| 158 | }); |
---|