utils.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /**
  2. * Utilities
  3. */
  4. createClass = function (/* [baseclass, [mixin, ...]], definition */) {
  5. var Class, args;
  6. Class = function () {
  7. this.init.apply(this, arguments);
  8. };
  9. if (arguments.length > 1) {
  10. if (arguments[0]) {
  11. Class.prototype = $.extend(new arguments[0](), arguments[arguments.length - 1]);
  12. Class._super = arguments[0].prototype;
  13. } else {
  14. Class.prototype = arguments[arguments.length - 1];
  15. }
  16. if (arguments.length > 2) {
  17. args = Array.prototype.slice.call(arguments, 1, -1);
  18. args.unshift(Class.prototype);
  19. $.extend.apply($, args);
  20. }
  21. } else {
  22. Class.prototype = arguments[0];
  23. }
  24. Class.prototype.cls = Class;
  25. return Class;
  26. };
  27. /**
  28. * Wraps a format string for tooltips
  29. * {{x}}
  30. * {{x.2}
  31. * {{x:months}}
  32. */
  33. $.SPFormatClass = SPFormat = createClass({
  34. fre: /\{\{([\w.]+?)(:(.+?))?\}\}/g,
  35. precre: /(\w+)\.(\d+)/,
  36. init: function (format, fclass) {
  37. this.format = format;
  38. this.fclass = fclass;
  39. },
  40. render: function (fieldset, lookups, options) {
  41. var self = this,
  42. fields = fieldset,
  43. match, token, lookupkey, fieldvalue, prec;
  44. return this.format.replace(this.fre, function () {
  45. var lookup;
  46. token = arguments[1];
  47. lookupkey = arguments[3];
  48. match = self.precre.exec(token);
  49. if (match) {
  50. prec = match[2];
  51. token = match[1];
  52. } else {
  53. prec = false;
  54. }
  55. fieldvalue = fields[token];
  56. if (fieldvalue === undefined) {
  57. return '';
  58. }
  59. if (lookupkey && lookups && lookups[lookupkey]) {
  60. lookup = lookups[lookupkey];
  61. if (lookup.get) { // RangeMap
  62. return lookups[lookupkey].get(fieldvalue) || fieldvalue;
  63. } else {
  64. return lookups[lookupkey][fieldvalue] || fieldvalue;
  65. }
  66. }
  67. if (isNumber(fieldvalue)) {
  68. if (options.get('numberFormatter')) {
  69. fieldvalue = options.get('numberFormatter')(fieldvalue);
  70. } else {
  71. fieldvalue = formatNumber(fieldvalue, prec,
  72. options.get('numberDigitGroupCount'),
  73. options.get('numberDigitGroupSep'),
  74. options.get('numberDecimalMark'));
  75. }
  76. }
  77. return fieldvalue;
  78. });
  79. }
  80. });
  81. // convience method to avoid needing the new operator
  82. $.spformat = function(format, fclass) {
  83. return new SPFormat(format, fclass);
  84. };
  85. clipval = function (val, min, max) {
  86. if (val < min) {
  87. return min;
  88. }
  89. if (val > max) {
  90. return max;
  91. }
  92. return val;
  93. };
  94. quartile = function (values, q) {
  95. var vl;
  96. if (q === 2) {
  97. vl = Math.floor(values.length / 2);
  98. return values.length % 2 ? values[vl] : (values[vl-1] + values[vl]) / 2;
  99. } else {
  100. if (values.length % 2 ) { // odd
  101. vl = (values.length * q + q) / 4;
  102. return vl % 1 ? (values[Math.floor(vl)] + values[Math.floor(vl) - 1]) / 2 : values[vl-1];
  103. } else { //even
  104. vl = (values.length * q + 2) / 4;
  105. return vl % 1 ? (values[Math.floor(vl)] + values[Math.floor(vl) - 1]) / 2 : values[vl-1];
  106. }
  107. }
  108. };
  109. normalizeValue = function (val) {
  110. var nf;
  111. switch (val) {
  112. case 'undefined':
  113. val = undefined;
  114. break;
  115. case 'null':
  116. val = null;
  117. break;
  118. case 'true':
  119. val = true;
  120. break;
  121. case 'false':
  122. val = false;
  123. break;
  124. default:
  125. nf = parseFloat(val);
  126. if (val == nf) {
  127. val = nf;
  128. }
  129. }
  130. return val;
  131. };
  132. normalizeValues = function (vals) {
  133. var i, result = [];
  134. for (i = vals.length; i--;) {
  135. result[i] = normalizeValue(vals[i]);
  136. }
  137. return result;
  138. };
  139. remove = function (vals, filter) {
  140. var i, vl, result = [];
  141. for (i = 0, vl = vals.length; i < vl; i++) {
  142. if (vals[i] !== filter) {
  143. result.push(vals[i]);
  144. }
  145. }
  146. return result;
  147. };
  148. isNumber = function (num) {
  149. return !isNaN(parseFloat(num)) && isFinite(num);
  150. };
  151. formatNumber = function (num, prec, groupsize, groupsep, decsep) {
  152. var p, i;
  153. num = (prec === false ? parseFloat(num).toString() : num.toFixed(prec)).split('');
  154. p = (p = $.inArray('.', num)) < 0 ? num.length : p;
  155. if (p < num.length) {
  156. num[p] = decsep;
  157. }
  158. for (i = p - groupsize; i > 0; i -= groupsize) {
  159. num.splice(i, 0, groupsep);
  160. }
  161. return num.join('');
  162. };
  163. // determine if all values of an array match a value
  164. // returns true if the array is empty
  165. all = function (val, arr, ignoreNull) {
  166. var i;
  167. for (i = arr.length; i--; ) {
  168. if (ignoreNull && arr[i] === null) continue;
  169. if (arr[i] !== val) {
  170. return false;
  171. }
  172. }
  173. return true;
  174. };
  175. // sums the numeric values in an array, ignoring other values
  176. sum = function (vals) {
  177. var total = 0, i;
  178. for (i = vals.length; i--;) {
  179. total += typeof vals[i] === 'number' ? vals[i] : 0;
  180. }
  181. return total;
  182. };
  183. ensureArray = function (val) {
  184. return $.isArray(val) ? val : [val];
  185. };
  186. // http://paulirish.com/2008/bookmarklet-inject-new-css-rules/
  187. addCSS = function(css) {
  188. var tag, iefail;
  189. if (document.createStyleSheet) {
  190. try {
  191. document.createStyleSheet().cssText = css;
  192. return;
  193. } catch (e) {
  194. // IE <= 9 maxes out at 31 stylesheets; inject into page instead.
  195. iefail = true;
  196. }
  197. }
  198. tag = document.createElement('style');
  199. tag.type = 'text/css';
  200. document.getElementsByTagName('head')[0].appendChild(tag);
  201. if (iefail) {
  202. document.styleSheets[document.styleSheets.length - 1].cssText = css;
  203. } else {
  204. tag[(typeof document.body.style.WebkitAppearance == 'string') /* webkit only */ ? 'innerText' : 'innerHTML'] = css;
  205. }
  206. };