helper.js 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. /* exported getParameterByName, updateQueryString, throttle, debounce, getHashParams, setStatus, addAtPosition, getValue, getValueJSON, setValueJSON, bindString, ellipsize, sizeOfObject, base64Encode */
  2. //the following is absolutely necessary for IE compatibility, because IE <= 9 have no console object
  3. window.console = window.console || (function()
  4. {
  5. var c = {}; c.log = c.warn = c.debug = c.info = c.error = c.time = c.dir = c.profile = c.clear = c.exception = c.trace = c.assert = function(){};
  6. return c;
  7. })();
  8. function getParameterByName(name)
  9. {
  10. name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
  11. var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
  12. results = regex.exec(window['location']['search']);
  13. return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
  14. }
  15. function updateQueryString(key, value, url)
  16. {
  17. if (!url) url = window.location.href;
  18. var re = new RegExp("([?&])" + key + "=.*?(&|#|$)(.*)", "gi"),
  19. hash;
  20. if (re.test(url)) {
  21. if (typeof value !== 'undefined' && value !== null)
  22. return url.replace(re, '$1' + key + "=" + value + '$2$3');
  23. else {
  24. hash = url.split('#');
  25. url = hash[0].replace(re, '$1$3').replace(/(&|\?)$/, '');
  26. if (typeof hash[1] !== 'undefined' && hash[1] !== null)
  27. url += '#' + hash[1];
  28. return url;
  29. }
  30. }
  31. else {
  32. if (typeof value !== 'undefined' && value !== null) {
  33. var separator = url.indexOf('?') !== -1 ? '&' : '?';
  34. hash = url.split('#');
  35. url = hash[0] + separator + key + '=' + value;
  36. if (typeof hash[1] !== 'undefined' && hash[1] !== null)
  37. url += '#' + hash[1];
  38. return url;
  39. }
  40. else
  41. return url;
  42. }
  43. }
  44. function throttle(func, wait, options)
  45. {
  46. var context, args, result;
  47. var timeout = null;
  48. var previous = 0;
  49. if(!options)
  50. options = {};
  51. var later = function()
  52. {
  53. previous = options['leading'] === false ? 0 : (new Date().getTime());
  54. timeout = null;
  55. result = func.apply(context, args);
  56. context = args = null;
  57. };
  58. return function()
  59. {
  60. var now = new Date().getTime();
  61. if (!previous && options['leading'] === false) previous = now;
  62. var remaining = wait - (now - previous);
  63. context = this;
  64. args = arguments;
  65. if (remaining <= 0)
  66. {
  67. clearTimeout(timeout);
  68. timeout = null;
  69. previous = now;
  70. result = func.apply(context, args);
  71. context = args = null;
  72. }
  73. else if (!timeout && options['trailing'] !== false)
  74. {
  75. timeout = setTimeout(later, remaining);
  76. }
  77. return result;
  78. };
  79. }
  80. /**
  81. * Returns a function, that, as long as it continues to be invoked, will not
  82. * be triggered. The function will be called after it stops being called for
  83. * N milliseconds. If `immediate` is passed, trigger the function on the
  84. * leading edge, instead of the trailing.
  85. *
  86. * @param {function} func
  87. * @param {number} wait
  88. * @param {boolean} immediate
  89. */
  90. function debounce(func, wait, immediate)
  91. {
  92. var timeout;
  93. return function() {
  94. var context = this, args = arguments;
  95. clearTimeout(timeout);
  96. timeout = setTimeout(function() {
  97. timeout = null;
  98. if (!immediate) func.apply(context, args);
  99. }, wait);
  100. if (immediate && !timeout) func.apply(context, args);
  101. };
  102. }
  103. /**
  104. * Parses the hash parameters to this page and returns them as an object.
  105. * @function
  106. */
  107. function getHashParams()
  108. {
  109. var params = {};
  110. var hashFragment = window.location.hash;
  111. if(hashFragment)
  112. {
  113. // split up the query string and store in an object
  114. var paramStrs = hashFragment.slice(1).split('&');
  115. for (var i = 0; i < paramStrs.length; i++)
  116. {
  117. var paramStr = paramStrs[i].split('=');
  118. params[paramStr[0]] = unescape(paramStr[1]);
  119. }
  120. }
  121. // Opening from Drive will encode the state in a query search parameter
  122. var searchFragment = window.location.search;
  123. if (searchFragment)
  124. {
  125. // split up the query string and store in an object
  126. var paramStrs2 = searchFragment.slice(1).split('&');
  127. for(var j = 0; j < paramStrs2.length; j++)
  128. {
  129. var paramStr2 = paramStrs2[j].split('=');
  130. params[paramStr2[0]] = unescape(paramStr2[1]);
  131. }
  132. }
  133. return params;
  134. }
  135. function addAtPosition($item, $list, index)
  136. {
  137. //append to end
  138. if(index === null
  139. || typeof(index) == 'undefined'
  140. || index > $('li', $list).length)
  141. {
  142. $item.appendTo($list);
  143. }
  144. else if(index === 0)
  145. {
  146. $item.prependTo($list);
  147. }
  148. else
  149. {
  150. $item.insertAfter($list.children().eq(index-1));
  151. }
  152. }
  153. function ellipsize(text, maxLength)
  154. {
  155. var ret = text;
  156. if(ret.length > maxLength)
  157. ret = ret.substr(0, maxLength - 1) + "&hellip;";
  158. return ret;
  159. }
  160. function sizeOfObject(object)
  161. {
  162. var objectList = [];
  163. var stack = [ object ];
  164. var bytes = 0;
  165. while ( stack.length ) {
  166. var value = stack.pop();
  167. if ( typeof value === 'boolean' ) {
  168. bytes += 4;
  169. }
  170. else if ( typeof value === 'string' ) {
  171. bytes += value.length * 2;
  172. }
  173. else if ( typeof value === 'number' ) {
  174. bytes += 8;
  175. }
  176. else if
  177. (
  178. typeof value === 'object'
  179. && objectList.indexOf( value ) === -1
  180. )
  181. {
  182. objectList.push( value );
  183. for( var i in value ) {
  184. stack.push( value[ i ] );
  185. }
  186. }
  187. }
  188. return bytes;
  189. }
  190. function setStatus(status)
  191. {
  192. window['status'] = status;
  193. console.log(window['status'] = status);
  194. }
  195. function base64Encode(str)
  196. {
  197. var CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  198. var out = "", i = 0, len = str.length, c1, c2, c3;
  199. while (i < len)
  200. {
  201. c1 = str.charCodeAt(i++) & 0xff;
  202. if (i == len)
  203. {
  204. out += CHARS.charAt(c1 >> 2);
  205. out += CHARS.charAt((c1 & 0x3) << 4);
  206. out += "==";
  207. break;
  208. }
  209. c2 = str.charCodeAt(i++);
  210. if (i == len)
  211. {
  212. out += CHARS.charAt(c1 >> 2);
  213. out += CHARS.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
  214. out += CHARS.charAt((c2 & 0xF) << 2);
  215. out += "=";
  216. break;
  217. }
  218. c3 = str.charCodeAt(i++);
  219. out += CHARS.charAt(c1 >> 2);
  220. out += CHARS.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
  221. out += CHARS.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
  222. out += CHARS.charAt(c3 & 0x3F);
  223. }
  224. return out;
  225. }
  226. function formatMoney(c)
  227. {
  228. if(!c) return '';
  229. return Number(c).toLocaleString('en-us', { style: 'currency', currency: 'USD' }).split('.')[0];
  230. }
  231. function formatDate(dt)
  232. {
  233. if(!dt)
  234. return '';
  235. var date = new Date(dt);
  236. var year = date.getFullYear();
  237. var month = (1 + date.getMonth()).toString();
  238. month = month.length > 1 ? month : '0' + month;
  239. var day = date.getDate().toString();
  240. day = day.length > 1 ? day : '0' + day;
  241. return year + '-' + month + '-' + day;
  242. }
  243. function array_intersection(old, nu, property, inclusion)
  244. {
  245. //items to add starts empty
  246. var added = [];
  247. //start with all the old items, which we'll remove as we find them in the new list
  248. var removed = old.slice(0);
  249. var unchanged = [];
  250. //go through all new items
  251. for(var i = 0; i < nu.length; i++)
  252. {
  253. if(!nu[i]) continue;
  254. var found = false;
  255. //go through all old items
  256. for(var j = 0; j < removed.length; j++)
  257. {
  258. if(!removed[j]) continue;
  259. //if the new item is found in the old list
  260. //also check if the item is to be included no matter what
  261. if(removed[j][property] == nu[i][property]
  262. || (inclusion && removed[j][property] == inclusion[property]))
  263. {
  264. //this new item is in the old list, so remove it from the old list
  265. found = true;
  266. //remove this item from the remove list
  267. var unchanged_item = removed.splice(j, 1)[0];
  268. //add it to the unchanged list
  269. unchanged.push(unchanged_item);
  270. break;
  271. }
  272. }
  273. if(!found)
  274. added.push(nu[i]);
  275. }
  276. var obj =
  277. {
  278. 'added': added,
  279. 'removed': removed,
  280. 'unchanged': unchanged
  281. };
  282. return obj;
  283. }
  284. var second = 1e3,
  285. minute = 6e4,
  286. hour = 36e5,
  287. day = 864e5,
  288. week = 6048e5;
  289. function timeFromNow(tm)
  290. {
  291. var system_date = new Date(Date.parse(tm));
  292. var user_date = new Date();
  293. var diff = Math.floor((user_date - system_date) / 1000);
  294. if (diff <= 1) {return "just now";}
  295. if (diff < 20) {return diff + " seconds ago";}
  296. if (diff < 40) {return "half a minute ago";}
  297. if (diff < 60) {return "less than a minute ago";}
  298. if (diff <= 90) {return "one minute ago";}
  299. if (diff <= 3540) {return Math.round(diff / 60) + " minutes ago";}
  300. if (diff <= 5400) {return "1 hour ago";}
  301. if (diff <= 86400) {return Math.round(diff / 3600) + " hours ago";}
  302. if (diff <= 129600) {return "1 day ago";}
  303. if (diff < 604800) {return Math.round(diff / 86400) + " days ago";}
  304. if (diff <= 777600) {return "1 week ago";}
  305. /*
  306. if (diff < 1209600) {return Math.round(diff / 1209600) + " weeks ago";}
  307. if (diff <= 4838400) {return "1 month ago";}
  308. */
  309. var dateString =
  310. system_date.getFullYear() +"/"+
  311. ("0" + (system_date.getMonth()+1)).slice(-2) +"/"+
  312. ("0" + system_date.getDate()).slice(-2) + " " +
  313. ("0" + system_date.getHours()).slice(-2) + ":" +
  314. ("0" + system_date.getMinutes()).slice(-2) + ":" +
  315. ("0" + system_date.getSeconds()).slice(-2);
  316. return "on " + dateString;
  317. }
  318. function timeDifference(a, b)
  319. {
  320. var date_a = new Date(a);
  321. var date_b = new Date(b);
  322. var sec = parseInt((date_b - date_a) / 1000);
  323. var ret = '';
  324. if(sec > 60)
  325. {
  326. ret += parseInt(sec / 60) + ' min ';
  327. sec = sec % 60;
  328. }
  329. ret += sec + ' sec';
  330. return ret;
  331. }