Fixed timed event check
[ajatus.git] / js / ajatus.utils.js
blobe6fd9809a708f0db2e4216153cad9ff133159017
1 /*
2  * This file is part of
3  *
4  * Ajatus - Distributed CRM
5  * @requires jQuery v1.2.1
6  * 
7  * Copyright (c) 2007 Jerry Jalava <jerry.jalava@gmail.com>
8  * Copyright (c) 2007 Nemein Oy <http://nemein.com>
9  * Website: http://ajatus.info
10  * Licensed under the GPL license
11  * http://www.gnu.org/licenses/gpl.html
12  * 
13  */
15 (function($){
16     $.ajatus = $.ajatus || {};
17     
18     $.ajatus.utils = {        
19     };
20     
21     $.ajatus.utils.to_boolean = function(value) {
22         if (typeof value == 'boolean') {
23             return value;
24         }
25         
26         if (typeof value == 'string') {
27             if (value === 'true') {
28                 return true;
29             } else if (value === '1') {
30                 return true;
31             }
32             return false;
33         }
35         if (typeof value == 'number') {
36             if (value === 1) {
37                 return true;
38             }
39             return false;
40         }
41         
42         return false;
43     };
45     /**
46      * Renders pretty printed version from given value
47      * Original pretty_print function by Damien Katz <damien_katz@yahoo.com>
48      * Modified to work with Ajatus by Jerry Jalava <jerry.jalava@gmail.com>
49      * @param {Mixed} val Value to render
50      * @param {Number} indent Current indent level (Default: 4)
51      * @param {String} linesep Line break to be used (Default: "\n")
52      * @param {Number} depth Current line depth (Default: 1)
53      * @returns Pretty printed value
54      * @type String
55      */
56     $.ajatus.utils.pretty_print = function(val, indent, linesep, depth) {
57         var indent = typeof indent != 'undefined' ? indent : 4;
58         var linesep = typeof linesep != 'undefined' ? linesep : "\n";
59         var depth = typeof depth != 'undefined' ? depth : 1;
60         
61         var propsep = linesep.length ? "," + linesep : ", ";
63         var tab = [];
65         for (var i = 0; i < indent * depth; i++) {
66             tab.push("")
67         };
68         tab = tab.join(" ");
70         switch (typeof val) {
71             case "boolean":
72             case "number":
73             case "string":
74                 return $.ajatus.converter.toJSON(val);
75             case "object":
76                 if (val === null) {
77                     return "null";
78                 }
79                 if (val.constructor == Date) {
80                     return $.ajatus.converter.toJSON(val);
81                 }
83                 var buf = [];
84                 if (val.constructor == Array) {
85                     buf.push("[");
86                     for (var index = 0; index < val.length; index++) {
87                         buf.push(index > 0 ? propsep : linesep);
88                         buf.push(
89                             tab, $.ajatus.utils.pretty_print(val[index], indent, linesep, depth + 1)
90                         );
91                     }
92                     
93                     if (index >= 0) {
94                         buf.push(linesep, tab.substr(indent))
95                     };
96                     
97                     buf.push("]");
98                 } else {
99                     buf.push("{");
100                     var index = 0;
101                     for (var key in val) {                        
102                         if (! val.hasOwnProperty(key)) {
103                             continue;
104                         };
105                         
106                         buf.push(index > 0 ? propsep : linesep);
107                         buf.push(
108                             tab, $.ajatus.converter.toJSON(key), ": ",
109                             $.ajatus.utils.pretty_print(val[key], indent, linesep, depth + 1)
110                         );
111                         index++;
112                     }
113                     
114                     if (index >= 0) {
115                         buf.push(linesep, tab.substr(indent));
116                     };
117                     
118                     buf.push("}");
119                 }
120                 
121                 return buf.join("");
122             break;
123         }
124     };
125     
126     $.ajatus.utils.base64 = {
127         END_OF_INPUT: -1,
128         base64Chars: [
129             'A','B','C','D','E','F','G','H',
130             'I','J','K','L','M','N','O','P',
131             'Q','R','S','T','U','V','W','X',
132             'Y','Z','a','b','c','d','e','f',
133             'g','h','i','j','k','l','m','n',
134             'o','p','q','r','s','t','u','v',
135             'w','x','y','z','0','1','2','3',
136             '4','5','6','7','8','9','+','/'
137         ],
138         
139         reverseBase64Chars: null,
141         encode: function(value) {
142             var base64Str;
143             var base64Count;
144             
145             function setBase64Str(str) {
146                 base64Str = str;
147                 base64Count = 0;
148             }
150             setBase64Str(value);
151             var result = '';
152             var inBuffer = new Array(3);
153             var lineCount = 0;
154             var done = false;
155             while (!done && (inBuffer[0] = readBase64()) != END_OF_INPUT) {
156                 inBuffer[1] = readBase64();
157                 inBuffer[2] = readBase64();
158                 result += ($.ajatus.utils.base64.base64Chars[ inBuffer[0] >> 2 ]);
159                 if (inBuffer[1] != END_OF_INPUT) {
160                     result += ($.ajatus.utils.base64.base64Chars[((inBuffer[0] << 4) & 0x30) | (inBuffer[1] >> 4)]);
161                     if (inBuffer[2] != END_OF_INPUT) {
162                         result += ($.ajatus.utils.base64.base64Chars[((inBuffer[1] << 2) & 0x3c) | (inBuffer[2] >> 6) ]);
163                         result += ($.ajatus.utils.base64.base64Chars[inBuffer[2] & 0x3F]);
164                     } else {
165                         result += ($.ajatus.utils.base64.base64Chars[((inBuffer[1] << 2) & 0x3c)]);
166                         result += ('=');
167                         done = true;
168                     }
169                 } else {
170                     result += ($.ajatus.utils.base64.base64Chars[((inBuffer[0] << 4) & 0x30)]);
171                     result += ('=');
172                     result += ('=');
173                     done = true;
174                 }
175                 lineCount += 4;
176                 if (lineCount >= 76) {
177                     result += ('\n');
178                     lineCount = 0;
179                 }
180             }
181             
182             return result;
183         },
184         decode: function(value) {
185             var base64Str;
186             var base64Count;
187             
188             if ($.ajatus.utils.base64.reverseBase64Chars == null) {
189                 for (var i=0; i < $.ajatus.utils.base64.base64Chars.length; i++) {
190                     $.ajatus.utils.base64.reverseBase64Chars[$.ajatus.utils.base64.base64Chars[i]] = i;
191                 }                
192             }
193             
194             function setBase64Str(str) {
195                 base64Str = str;
196                 base64Count = 0;
197             }
199             function readReverseBase64() {   
200                 if (! base64Str) {
201                     return END_OF_INPUT;
202                 }
203                 
204                 while (true) {
205                     if (base64Count >= base64Str.length) {
206                         return END_OF_INPUT;
207                     }
208                     var nextCharacter = base64Str.charAt(base64Count);
209                     base64Count++;
210                     if ($.ajatus.utils.base64.reverseBase64Chars[nextCharacter]){
211                         return $.ajatus.utils.base64.reverseBase64Chars[nextCharacter];
212                     }
213                     if (nextCharacter == 'A') {
214                         return 0;
215                     }
216                 }
217                 return END_OF_INPUT;
218             }
220             function ntos(n){
221                 n=n.toString(16);
222                 if (n.length == 1) n="0"+n;
223                 n="%"+n;
224                 return unescape(n);
225             }
226             
227             setBase64Str(value);
228             var result = "";
229             var inBuffer = new Array(4);
230             var done = false;
231             while (!done && (inBuffer[0] = readReverseBase64()) != END_OF_INPUT
232                 && (inBuffer[1] = readReverseBase64()) != END_OF_INPUT)
233             {
234                 inBuffer[2] = readReverseBase64();
235                 inBuffer[3] = readReverseBase64();
236                 result += ntos((((inBuffer[0] << 2) & 0xff)| inBuffer[1] >> 4));
237                 if (inBuffer[2] != END_OF_INPUT){
238                     result +=  ntos((((inBuffer[1] << 4) & 0xff)| inBuffer[2] >> 2));
239                     if (inBuffer[3] != END_OF_INPUT){
240                         result +=  ntos((((inBuffer[2] << 6)  & 0xff) | inBuffer[3]));
241                     } else {
242                         done = true;
243                     }
244                 } else {
245                     done = true;
246                 }
247             }
248             
249             return result;            
250         }
251     };
252     
253     /**
254      *
255      * UTF-8 data encode / decode
256      * http://www.webtoolkit.info/
257      *
258      * @returns Encoded/Decoded string
259      * @type String
260      */
261     $.ajatus.utils.utf8 = {
262         encode: function(string) {
263             string = string.replace(/\r\n/g,"\n");
264             var utftext = "";
266             for (var n = 0; n < string.length; n++) {
267                 var c = string.charCodeAt(n);
269                 if (c < 128) {
270                     utftext += String.fromCharCode(c);
271                 } else if (   (c > 127)
272                            && (c < 2048))
273                 {
274                     utftext += String.fromCharCode((c >> 6) | 192);
275                     utftext += String.fromCharCode((c & 63) | 128);
276                 } else {
277                     utftext += String.fromCharCode((c >> 12) | 224);
278                     utftext += String.fromCharCode(((c >> 6) & 63) | 128);
279                     utftext += String.fromCharCode((c & 63) | 128);
280                 }
281             }
283             return utftext;
284         },
285         decode: function(utftext) {
286             var string = "";
287             var i = 0;
288             var c = c1 = c2 = 0;
290             while ( i < utftext.length ) {
291                 c = utftext.charCodeAt(i);
293                 if (c < 128) {
294                     string += String.fromCharCode(c);
295                     i++;
296                 } else if (   (c > 191)
297                            && (c < 224))
298                 {
299                     c2 = utftext.charCodeAt(i+1);
300                     string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
301                     i += 2;
302                 } else {
303                     c2 = utftext.charCodeAt(i+1);
304                     c3 = utftext.charCodeAt(i+2);
305                     string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
306                     i += 3;
307                 }
308             }
310             return string;
311         }
312     };
313     
314     $.ajatus.utils.array = {
315         has_match: function(needles, haystack) {
316             if (   typeof haystack != 'object'
317                 || haystack.length <= 0)
318             {
319                 return false;
320             }
322             if (typeof needles == 'object') {
323                 var matched = false;
324                 $.each(needles, function(i,needle){
325                     if ($.inArray(needle, haystack) != -1) {
326                         matched = true;
327                     }
328                     // if (typeof(haystack[needle]) != 'undefined') {
329                     //                         matched = true;
330                     //                     }
331                 });
332                 return matched;
333             } else if (typeof needles == 'string') {
334                 var matched = false;
335                 if ($.inArray(needles, haystack) != -1) {
336                     matched = true;
337                 }
338                 return matched;
339             }
340             
341             return false;
342         }
343     };
344     
345     $.ajatus.utils.object = {
346         clone: function(obj) {
347             if(obj == null || typeof(obj) != 'object') {
348                 return obj;                
349             }
350             var temp = {};
351             for(var key in obj) {
352                 temp[key] = $.ajatus.utils.object.clone(obj[key]);                
353             }
355             return temp;
356         }
357     };
358     
359     // Put focus on given form element (0 == first) (skips hidden fields)
360     $.fn.set_focus_on = function(eid) {
361         var elem = $('input:visible:not(:hidden)', this).get(eid);
362         var select = $('select:visible', this).get(eid);
364         if (select && elem) {
365             if (select.offsetTop < elem.offsetTop) {
366                 elem = select;
367             }
368         }
370         var textarea = $('textarea:visible', this).get(eid);
371         if (textarea && elem) {
372             if (textarea.offsetTop < elem.offsetTop) {
373                 elem = textarea;
374             }
375         }
377         if (elem) {
378             elem.focus();
379         }
381         return this;
382     }
383     
384     $.ajatus.utils.pause = function(ms) {
385         var date = new Date();
386         var currDate = null;
388         do { currDate = new Date(); }
389         while(currDate - date < ms);
390     }
391     
392     $.ajatus.utils.generate_id = function() {
393         var random_key = Math.floor(Math.random()*4013);
394         return (10016486 + (random_key * 22423));
395     }
396     
397     $.ajatus.utils.get_url_arg = function(name) {
398         var value = null;
399         
400         name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
401         var exp = "[\\?&]"+name+"=([^&#]*)";
402         var regex = new RegExp( exp );
403         var results = regex.exec(window.location.href);
404         if (results != null) {
405             value = results[1];
406         }
407         
408         return value;
409     }
410     
411     $.ajatus.utils.load_script = function(url, callback, cb_args) {
412         $('head').append('<script type="text/javascript" charset="utf-8" src="'+url+'"></script>');
413         if (typeof callback == 'string') {
414             if (   typeof cb_args == 'undefined'
415                 || typeof cb_args != 'object')
416             {
417                 var cb_args = [];
418             }
419             
420             setTimeout('eval("var fn = eval('+callback+'); fn.apply(fn, [\''+cb_args.join("','")+'\']);")', 300);
421         }
422     }
423     
424     $.ajatus.utils.doc_generator = function(prefix, count, type, data, value_tpl) {
425         var doc = {
426             _id: '',
427             value: {
428             }
429         };
430         if (typeof value_tpl != 'undefined') {
431             doc.value = value_tpl;
432         }
433         if (typeof type == 'undefined') {
434             var type = $.ajatus.preferences.client.content_types['note'];
435         }
436         if (typeof data == 'undefined') {
437             var data = {
438             }
439         }
440                 
441         $.each(type.original_schema, function(i,n){
442             doc.value[i] = {
443                 val: n.def_val,
444                 widget: n.widget
445             };
446         });
447         
448         var docs = [];
449         
450         if (typeof prefix == 'undefined') {
451             var prefix = 'ajatus';
452         }
453         if (typeof count == 'undefined') {
454             count = 100;
455         }
456         
457         function prepare_title(title, id) {
458             var full_title = title + " ";
459             full_title += (id).toString();
460             return full_title;
461         }
462         
463         for (var i=0; i<count; i++) {
464             var new_doc = new $.ajatus.document(doc);
465             
466             if (   typeof data.title == 'undefined'
467                 && typeof new_doc.value['title'] != 'undefined')
468             {
469                 new_doc.value['title'].val = $.ajatus.i10n.get("Generated doc title (%s)", [prefix]) + " " + i;
470             }
471             
472             $.each(data, function(x,n){
473                 if (typeof new_doc.value[x] != 'undefined') {
474                     new_doc.value[x].val = n;
475                 }
476             });
478             var now = $.ajatus.formatter.date.js_to_iso8601(new Date());
480             var new_metadata = {
481                 created: now,
482                 creator: $.ajatus.preferences.local.user.email,
483                 revised: now,
484                 revisor: $.ajatus.preferences.local.user.email
485             };
487             new_doc = $.ajatus.document.modify_metadata(new_doc, new_metadata);
488             
489             new_doc._id = prefix + "_gen_doc_" + (i).toString();
490             docs.push($.ajatus.utils.object.clone(new_doc));
491         }
492         
493         return docs;
494     }
495     
496     /**
497      * Following functions are taken from the jquery form plugin.
498      * Plugin can be found from http://www.malsup.com/jquery/form/
499      */
500     $.fieldValue = function(el, successful) {
501         var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
502         if (typeof successful == 'undefined') successful = true;
504         if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
505             (t == 'checkbox' || t == 'radio') && !el.checked ||
506             (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
507             tag == 'select' && el.selectedIndex == -1))
508                 return null;
510         if (tag == 'select') {
511             var index = el.selectedIndex;
512             if (index < 0) return null;
513             var a = [], ops = el.options;
514             var one = (t == 'select-one');
515             var max = (one ? index+1 : ops.length);
516             for(var i=(one ? index : 0); i < max; i++) {
517                 var op = ops[i];
518                 if (op.selected) {
519                     // extra pain for IE...
520                     var v = $.browser.msie && !(op.attributes['value'].specified) ? op.text : op.value;
521                     if (one) return v;
522                     a.push(v);
523                 }
524             }
525             return a;
526         }
527         return el.value;
528     };
529         $.fn.formToArray = function(semantic) {
530         var a = [];
531         if (this.length == 0) return a;
533         var form = this[0];
534         var els = semantic ? form.getElementsByTagName('*') : form.elements;
535         if (!els) return a;
536         for(var i=0, max=els.length; i < max; i++) {
537             var el = els[i];
538             var n = el.name;
539             if (!n) continue;
541             if (semantic && form.clk && el.type == "image") {
542                 // handle image inputs on the fly when semantic == true
543                 if(!el.disabled && form.clk == el)
544                     a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
545                 continue;
546             }
548             var v = $.fieldValue(el, true);
549             if (v && v.constructor == Array) {
550                 for(var j=0, jmax=v.length; j < jmax; j++)
551                     a.push({name: n, value: v[j]});
552             }
553             else if (v !== null && typeof v != 'undefined')
554                 a.push({name: n, value: v});
555         }
557         if (!semantic && form.clk) {
558             // input type=='image' are not found in elements array! handle them here
559             var inputs = form.getElementsByTagName("input");
560             for(var i=0, max=inputs.length; i < max; i++) {
561                 var input = inputs[i];
562                 var n = input.name;
563                 if(n && !input.disabled && input.type == "image" && form.clk == input)
564                     a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
565             }
566         }
567         return a;
568     };
569     /**
570      * Form plugin functions end
571      */
572     
573 })(jQuery);