PageRenderTime 43ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 1ms

/src/utils.js

https://bitbucket.org/renren_platform/renren-api-javascript-sdk/
JavaScript | 329 lines | 305 code | 18 blank | 6 comment | 103 complexity | d3502b96dd173624da73ae0f848bfca6 MD5 | raw file
  1. /**
  2. * #@+
  3. *
  4. * @private
  5. */
  6. var overloadSetter = function(fn) {
  7. return function(s, a, b) {
  8. if (a == null)
  9. return s;
  10. if (typeof a != 'string') {
  11. for (var k in a)
  12. fn.call(s, k, a[k]);
  13. } else {
  14. fn.call(s, a, b);
  15. }
  16. return s;
  17. };
  18. },
  19. typeOf = function(item) {
  20. if (item == null)
  21. return 'null';
  22. if (item instanceof String || typeof item == 'string')
  23. return 'string';
  24. if (item instanceof Array)
  25. return 'array';
  26. if (item.nodeName) {
  27. if (item.nodeType == 1)
  28. return 'element';
  29. if (item.nodeType == 3)
  30. return (/\S/).test(item.nodeValue) ? 'textnode' : 'whitespace';
  31. } else if (typeof item.length == 'number') {
  32. if (item.callee)
  33. return 'arguments';
  34. if ('item' in item)
  35. return 'collection';
  36. }
  37. return typeof item;
  38. },
  39. guid = function() {
  40. return (Math.random() * (1 << 30)).toString(36).replace('.', '');
  41. },
  42. extend = overloadSetter(function(key, value) {
  43. this[key] = value;
  44. }),
  45. implement = overloadSetter(function(key, value) {
  46. this.prototype[key] = value;
  47. }),
  48. bind = function(fn, thisobj, args) {
  49. return function() {
  50. if (!args && !arguments.length)
  51. return fn.call(thisobj);
  52. if (args && arguments.length)
  53. return fn.apply(thisobj, args.concat(Array.from(arguments)));
  54. return fn.apply(thisobj, args || arguments);
  55. };
  56. },
  57. cloneOf = function(item) {
  58. switch (typeOf(item)) {
  59. case 'array' :
  60. case 'object' :
  61. return clone(item);
  62. default :
  63. return item;
  64. }
  65. },
  66. clone = function(original) {
  67. if (typeOf(original) == 'array') {
  68. var i = original.length, clone = new Array(i);
  69. while (i--)
  70. clone[i] = cloneOf(original[i]);
  71. return clone;
  72. } else if (typeOf(original) == 'string') {
  73. return new String(original);
  74. }
  75. var clone = {};
  76. for (var key in original)
  77. clone[key] = cloneOf(original[key]);
  78. return clone;
  79. },
  80. forEach = function(object, fn, bind) {
  81. if (typeOf(object) == 'array') {
  82. for (var i = 0, l = object.length; i < l; i++) {
  83. if (i in object)
  84. fn.call(bind, object[i], i, object);
  85. }
  86. } else
  87. for (var key in object) {
  88. if (Object.prototype.hasOwnProperty.call(object, key))
  89. fn.call(bind, object[key], key, object);
  90. }
  91. },
  92. indexOf = function(array, item, from) {
  93. var len = array.length;
  94. for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++) {
  95. if (array[i] === item)
  96. return i;
  97. }
  98. return -1;
  99. },
  100. mergeOne = function(source, key, current) {
  101. switch (typeOf(current)) {
  102. case 'object' :
  103. if (typeOf(source[key]) == 'object')
  104. merge(source[key], current);
  105. else
  106. source[key] = clone(current);
  107. break;
  108. case 'array' :
  109. source[key] = clone(current);
  110. break;
  111. default :
  112. source[key] = current;
  113. }
  114. return source;
  115. },
  116. merge = function(source, k, v) {
  117. if (typeOf(k) == 'string')
  118. return mergeOne(source, k, v);
  119. for (var i = 1, l = arguments.length; i < l; i++) {
  120. var object = arguments[i];
  121. for (var key in object)
  122. mergeOne(source, key, object[key]);
  123. }
  124. return source;
  125. },
  126. combineOne = function(source, key, value) {
  127. var st = typeOf(source[key]);
  128. switch (typeOf(value)) {
  129. case 'object' :
  130. case 'array' :
  131. if (st == 'object')
  132. combine(source[key], value);
  133. else if (st == 'array') {
  134. var array = clone(value);
  135. for (var i = 0, l = array.length; i < l; i++) {
  136. if (indexOf(source[key], array[i]) == -1)
  137. source[key].push(array[i]);
  138. }
  139. } else if (st == 'null')
  140. source[key] = clone(value);
  141. break;
  142. default :
  143. if (st == 'null')
  144. source[key] = value;
  145. }
  146. return source;
  147. },
  148. combine = function(source, k, v) {
  149. if (typeOf(k) == 'string')
  150. return combineOne(source, k, v);
  151. for (var i = 1, l = arguments.length; i < l; i++) {
  152. var object = arguments[i];
  153. for (var key in object)
  154. combineOne(source, key, object[key]);
  155. }
  156. return source;
  157. },
  158. append = function(original) {
  159. for (var i = 1, l = arguments.length; i < l; i++) {
  160. if (typeOf(original) == 'array') {
  161. var atp = typeOf(arguments[i]);
  162. if (atp == 'array' || atp == 'arguments') {
  163. for (var j = 0, lg = arguments[i].length; j < lg; j++)
  164. original.push(arguments[i][j]);
  165. } else if (atp != 'null')
  166. original.push(arguments[i]);
  167. } else {
  168. var extended = arguments[i] || {};
  169. for (var key in extended)
  170. original[key] = extended[key];
  171. }
  172. }
  173. return original;
  174. },
  175. parsePiece = function(key, val, base) {
  176. var sliced = /([^\]]*)\[([^\]]*)\](.*)?/.exec(key);
  177. if (!sliced) {
  178. base[key] = val;
  179. return;
  180. }
  181. var prop = sliced[1], subp = sliced[2], others = sliced[3];
  182. if (!isNaN(subp)) {
  183. var numVal = +subp;
  184. if (subp === numVal.toString(10)) {
  185. subp = numVal;
  186. }
  187. }
  188. base[prop] = base[prop] || (typeof subp == 'number' ? [] : {});
  189. if (others == null)
  190. base[prop][subp] = val;
  191. else
  192. parsePiece('' + subp + others, val, base[prop]);
  193. },
  194. fromQueryString = function(qs) {
  195. var decode = function(s) {
  196. return decodeURIComponent(s.replace(/\+/g, ' '));
  197. }, params = {}, parts = qs.split('&'), pair, val;
  198. for (var i = 0; i < parts.length; i++) {
  199. pair = parts[i].split('=', 2);
  200. if (pair && pair.length == 2) {
  201. val = decode(pair[1]);
  202. if (typeOf(val) == 'string') {
  203. val = val.replace(/^\s+|\s+$/g, '');
  204. // convert numerals to numbers
  205. if (!isNaN(val)) {
  206. numVal = +val;
  207. if (val === numVal.toString(10)) {
  208. val = numVal;
  209. }
  210. }
  211. }
  212. parsePiece(decode(pair[0]), val, params);
  213. }
  214. }
  215. return params;
  216. },
  217. toQueryString = function(object, base) {
  218. var queryString = [];
  219. forEach(object, function(value, key) {
  220. if (base)
  221. key = base + '[' + key + ']';
  222. var result;
  223. switch (typeOf(value)) {
  224. case 'object' :
  225. result = toQueryString(value, key);
  226. break;
  227. case 'array' :
  228. var qs = {};
  229. forEach(value, function(val, i) {
  230. qs[i] = val;
  231. });
  232. result = toQueryString(qs, key);
  233. break;
  234. case 'string' :
  235. case 'number' :
  236. result = encodeURIComponent(key) + '='
  237. + encodeURIComponent(value);
  238. break;
  239. }
  240. if (result && value != null)
  241. queryString.push(result);
  242. });
  243. return queryString.join('&');
  244. },
  245. special = {
  246. '\b' : '\\b',
  247. '\t' : '\\t',
  248. '\n' : '\\n',
  249. '\f' : '\\f',
  250. '\r' : '\\r',
  251. '"' : '\\"',
  252. '\\' : '\\\\'
  253. },
  254. escape = function(chr) {
  255. return special[chr] || '\\u'
  256. + ('0000' + chr.charCodeAt(0).toString(16)).slice(-4);
  257. },
  258. validateJSON = function(string) {
  259. string = string
  260. .replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
  261. .replace(
  262. /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
  263. ']').replace(/(?:^|:|,)(?:\s*\[)+/g, '');
  264. return (/^[\],:{}\s]*$/).test(string);
  265. },
  266. parseJSON = function(string) {
  267. if (!string || typeOf(string) != 'string')
  268. return null;
  269. if (window.JSON && window.JSON.parse)
  270. return window.JSON.parse(string);
  271. if (!validateJSON(string))
  272. throw new Error("Invalid JSON: " + string);
  273. return eval('(' + string + ')');
  274. },
  275. toJSON = window.JSON && window.JSON.stringify ? function(obj) {
  276. return window.JSON.stringify(obj);
  277. } : function(obj) {
  278. if (obj && obj.toJSON)
  279. obj = obj.toJSON();
  280. switch (typeOf(obj)) {
  281. case 'string' :
  282. return '"' + obj.replace(/[\x00-\x1f\\"]/g, escape) + '"';
  283. case 'array' :
  284. var string = [];
  285. forEach(obj, function(value, key) {
  286. var json = toJSON(value);
  287. if (json)
  288. string.push(json);
  289. });
  290. return '[' + string + ']';
  291. case 'object' :
  292. var string = [];
  293. forEach(obj, function(value, key) {
  294. var json = toJSON(value);
  295. if (json)
  296. string.push(toJSON(key) + ':' + json);
  297. });
  298. return '{' + string + '}';
  299. case 'number' :
  300. case 'boolean' :
  301. return '' + obj;
  302. case 'null' :
  303. return 'null';
  304. }
  305. return null;
  306. };
  307. /** #@- */