Merge branch 'master' of http://git.roojs.com:8081/web.mtrack
[web.mtrack] / MTrackWeb / templates / images / js / mtrack2.js
1 //<Script type="text/javascript">
2
3 /**
4  * Roo conversion....
5  * 
6  * currenlty mostly a clone of the JQuery version..
7  *
8  * uses a simple  registry - all code get's added to it, 
9  * then whenever html is loaded via AJAX, we can run run through the handlers and add them.
10  * 
11  */
12
13
14  
15 MTrack = {
16     
17     registry : [],
18     /**
19      * usage:
20      * MTrack.register('a.changeset-link', 'each', function() ....)
21      * MTrack.register('a.changeset-link', 'on', 'click', function() ....)
22      * 
23      */
24     register : function( selector, method, arg1, arg2) 
25     {
26         MTrack.registry.push( {
27             selector : selector,
28             method : method,
29             event : method == 'on' ? arg1 : false,
30             args : method == 'on' ? arg2 : arg1 
31         });
32     },
33     
34     addHandlers : function (toWhat) 
35     {
36         // forEach? - no IE support?
37         toWhat = toWhat || document.body; // 
38         // run the main registry
39         MTrack.registry.forEach(function(cfg) {
40             var el = Roo.get(toWhat).select(cfg.selector,true)
41             el[cfg.method].apply(el, cfg.event ? [ event, args ] : [ args ] );  
42         });
43         // any other weird crap goes here.
44         
45         if (Roo.isGecko) {
46             Roo.select(toWhat,true).select("form").set( { "autocomplete" : "off" });
47         }
48         // time ago 
49         //jQuery.timeago.settings.allowFuture = true;
50         //$(toWhat).find('abbr.timeinterval').timeago();
51         
52         // multipe select addon
53         //$(toWhat).find("select[multiple]").asmSelect({
54         //    addItemTarget: 'bottom',
55         //    animate: false,
56         //    highlight: false,
57         //    removeLabel: '[x]',
58         //    sortable: false
59         //});
60       
61     },
62     
63     currentURL : false,
64     missingHashRequest : false,
65     
66     
67     // This is the main body load tool...
68     // it still needs to handle anchors...
69     
70     
71     ajaxLoad : function(url,slideleft)
72     { 
73         this.currentURL = url;
74         var target = Roo.get("ajaxbody");
75         var content = Roo.get("content");
76         target.setStyle('position', 'relative');
77         
78         Roo.select('.mask').show(); // must show first?
79         Roo.select('.mask-loading').show();
80         // content has a border...
81         var t = content.getBox().top - Roo.get(document).getScroll().top - 13;
82         var l = content.getBox().left - Roo.get(document).getScroll().top - 13;
83         var w = content.getBox().width+ 26;
84         var h = content.getBox().height + 26;
85      
86         Roo.select('.mask').first().setLocation(l,t);
87         Roo.select('.mask').first().setSize( w , h, false  );
88         
89         Roo.select('.mask-loading').first().setLocation(
90                 l + ( w / 2) - 16, t +   16 
91         );
92         
93         if (MTrack.missingHashRequest) {
94             MTrack.missingHashRequest.abort();
95             MTrack.missingHashRequest = false;
96         }
97         Roo.get('loader').hide();
98         Roo.Ajax.request({
99             url : baseURL + url,
100             params : { ajax_body : 1 },
101             success : function(data) {
102                 
103                 Roo.select('.mask').hide();
104                 Roo.get('loader').update(data);
105                 Roo.get('loader').show();
106                 Roo.get('loader').setWidth( w );
107                 Roo.get('loader').setPosition( slideleft?  l+w : l-w , t  );
108                 
109                 target.animate(
110                     {
111                         left: slideleft ? -1 * w  : w
112                     },
113                     .5,
114                     function() {
115                         target.setPosition(  0, 0 ); // reset it at end of animation - as it ends up with the new content.
116                     }
117                 );
118                 
119                 Roo.get('loader').animate(
120                     {
121                             left: l+13
122                     },
123                     .5,
124                     function () {
125                         target.update( Roo.get('loader').dom.innerHTML);
126                         Roo.get('loader').hide();
127                         Roo.get('loader').update("");
128                         target.show();// make sure!!
129                     
130                         MTrack.missingHashes(target,  url);
131                         MTrack.addHandlers(target);
132                     }
133                 );
134             }
135             //console.log('loaded dif');
136             
137                
138         });
139       
140         return false;  
141     },
142     
143     
144     missingHashRequest : false,
145     missingHashes: function(el,url) {
146         //console.log('finding missing hashes?');
147         var hashes = [];
148         el.select('.browse-missing-hash').each(function() {
149             hashes.push(this.dom.id);
150         });
151         if (!hashes.length) {
152             return;
153         }
154         if (MTrack.missingHashRequest) {
155             MTrack.missingHashRequest.abort();
156         }
157         MTrack.missingHashRequest = Roo.Ajax.request({
158             method : 'POST',
159             url : baseURL + url,
160             params : { hashes : hashes.join(',') },
161             success : function(data) {
162                 //console.log(data.data);
163                 if (data.data) {
164                     for(var hash in data.data) {
165                         var o = data.data[hash];
166                         Roo.select('#'+ hash).first().dom.innerHTML =  o.changeby + ' : ' + o.changelog;
167                         Roo.select('#age-'+ hash).first().dom.innerHTML = o.age ; // do magic replacement!!!
168                         Roo.select('#rev-'+ hash).first().dom.innerHTML = o.rev ; // do magic replacement!!!
169                         MTrack.addHandlers(Roo.select('#age-'+ hash).first());
170                         MTrack.missingHashRequest  = false;
171                     }
172                     
173                 }
174                // console.log(data)
175             }
176         });
177         
178     }
179         
180         
181 }
182
183 Roo.onReady(function() {
184     MTrack.addHandlers(); // adds to main body..
185     // change project.
186     
187     Roo.select('#banner select').on('change', function(e) {
188         // ajax change project, and refresh body..
189         Roo.Ajax.request({
190             url : baseURL + '/Project.html',
191             params : { active_project_id : this.value },
192             success : function() {
193                 // what if it's false..currentURL = false;
194                 MTrack.ajaxLoad(MTrack.currentURL, true);
195                 
196             }
197             
198         })
199          
200     });
201         
202         
203 });
204
205
206 try { 
207     window.onpopstate = function(ev) {
208          
209         if (!ev.state || typeof(ev.state.url) == 'undefined') {
210             return;
211         }
212         MTrack.ajaxLoad(ev.state.url, false);
213 };
214 } catch (e) {}
215     
216      
217      
218
219
220
221
222 // any date picers.. - on milestones?
223 MTrack.register('.dateinput', 'each', function(e) {
224     var ee = new Roo.form.DateField({
225         dateFormat: 'Y-m-d' // nice and compatible..
226     });
227     ee.applyTo(e);
228     // minDate: 0,
229     
230 } );
231
232
233
234 MTrack.register('a.browse-link', 'on', 'click', function(event) 
235 {
236     event.preventDefault();
237   
238     var href= this.getAttribute('href').substring(baseURL.length);
239     try { 
240         window.history.pushState( { url: href }, "Browse : " + href , this.href );
241     } catch (e) {}
242     var slideleft = $(this).is('.browse-link-up')  ? 0 : 1;    
243     MTrack.ajaxLoad(href,slideleft); 
244 });
245
246
247
248 //// ------------------- OLD STUFF NEEDS TIDY UP ----------------------
249
250 /*
251
252
253 $(document).ready(function() {
254     
255      
256     
257   
258   $("textarea.wiki").markItUp({
259     nameSpace:          "wiki",
260     previewParserPath:  baseURL + "/Preview",
261     root: rootURL + "/js",
262     onShiftEnter:       {keepDefault:false, replaceWith:'\\n\\n'},
263     markupSet:  [
264       {
265         name:'Heading 1', key:'1',
266         openWith:'== ', closeWith:' ==', placeHolder:'Your title here...'
267       },
268       {
269         name:'Heading 2', key:'2',
270         openWith:'=== ', closeWith:' ===', placeHolder:'Your title here...'
271       },
272       {
273         name:'Heading 3', key:'3',
274         openWith:'==== ', closeWith:' ====', placeHolder:'Your title here...'
275       },
276       {
277         name:'Heading 4', key:'4',
278         openWith:'===== ', closeWith:' =====', placeHolder:'Your title here...'
279       },
280       {
281         name:'Heading 5', key:'5',
282         openWith:'====== ', closeWith:' ======',
283         placeHolder:'Your title here...'
284       },
285       {separator:'---------------' },
286       {name:'Bold', key:'B', openWith:"'''", closeWith:"'''"},
287       {name:'Italic', key:'I', openWith:"''", closeWith:"''"},
288       {name:'Stroke through', key:'S', openWith:'~~', closeWith:'~~'},
289       {separator:'---------------' },
290       {name:'Bulleted list', openWith:' * '},
291       {name:'Numeric list', openWith:' 1. '},
292       {separator:'---------------' },
293       {name:'Quotes', openWith:'(!(> |!|>)!)'},
294       {name:'Code', openWith:'{{{\\n', closeWith:'\\n}}}'},
295       {separator:'---------------' },
296       {name:'Preview', call:'preview', className:'preview'}
297     ]
298   });
299
300   $.tablesorter.addParser({
301     id: 'ticket',
302     is: function(s) {
303       return /^#\d+/.test(s);
304     },
305     format: function(s) {
306       return $.tablesorter.formatFloat(s.replace(new RegExp(/#/g), ''));
307     },
308     type: 'numeric'
309   });
310  
311   $.tablesorter.addParser({
312     id: 'mtrackdate',
313     is: function(s) {
314       // don't auto-detect
315       return false;
316     },
317     format: function(s) {
318       // relies on the textExtraction routine below to pull a
319       // date/time string out of the title portion of the abbr tag
320       return $.tablesorter.formatFloat(new Date(s).getTime());
321     },
322     type: 'numeric'
323   });
324   
325   
326   
327   $("table.report, table.wiki").tablesorter({
328     textExtraction: function(node) {
329       var kid = node.childNodes[0];
330       if (kid && kid.tagName == 'ABBR') {
331         // assuming that this abbr is of class='timeinterval'
332         return kid.title;
333       }
334       // default 'simple' behavior
335       if (kid && kid.hasChildNodes()) {
336         return kid.innerHTML;
337       }
338       return node.innerHTML;
339     }
340   });
341   
342   
343   $('input.search[type=text]').each(function () {
344     if ($.browser.webkit) {
345       this.type = 'search';
346       ///$(this).attr('autosave', ABSWEB+'/');
347       $(this).attr('results', 5);
348     } else {
349       $(this).addClass('roundsearch');
350     }
351   });
352   // Convert links that are styled after buttons into actual buttons
353   $('a.button[href]').each(function () {
354     var href = $(this).attr('href');
355     var but = $('<button type="button"/>');
356     but.text($(this).text());
357     $(this).replaceWith(but);
358     but.click(function () {
359       document.location.href = href;
360       return false;
361     });
362   });
363
364   $.fn.mtrackWatermark = function () {
365     this.each(function () {
366       var ph = $(this).attr('title');
367       if ($.browser.webkit) {
368         // Use native safari placeholder for watermark
369         $(this).attr('placeholder', ph);
370       } else {
371         // http://plugins.jquery.com/files/jquery.tinywatermark-2.0.0.js.txt
372         var w;
373         var me = $(this);
374         me.focus(function () {
375           if (w) {
376             w = 0;
377             me.removeClass('watermark').data('w', 0).val('');
378           }
379         })
380         .blur(function () {
381           if (!me.val()) {
382             w = 1;
383             me.addClass('watermark').data('w', 1).val(ph);
384           }
385         })
386         .closest('form').submit(function () {
387           if (w) {
388             me.val('');
389           }
390         });
391         me.blur();
392       }
393     });
394   };
395   // Watermarking -??? what??
396   $('input[title!=""]').mtrackWatermark();
397  
398
399   // Arrange for the footer to sink to the bottom of the window, if the window
400   // contents are not very tall
401   var last_dh = 0;
402   var last_wh = 0;
403   function mtrack_footer_position(force) {
404     var ele = $('#footer');
405     if (!force &&
406         (last_dh != $(document).height() || last_wh != $(window).height)) {
407       force = true;
408     }
409     if (force) {
410       // Force a from-scratch layout assessment; put the footer back in
411       // it's natural location in the doc
412       ele.css({
413         position: "relative",
414         "margin-top": "3em",
415         top: 0
416       });
417     }
418     if ($(document).height() <= $(window).height()) {
419       ele.css({
420         position: "absolute",
421         "margin-top": "0",
422         top: (
423             $(window).scrollTop() +
424             $(window).height() -
425             ele.height() - 1
426           )+"px"
427       });
428     } else {
429       ele.css({
430         position: "relative",
431         "margin-top": "3em"
432       });
433     }
434     last_dh = $(document).height();
435     last_wh = $(window).height();
436   }
437   window.mtrack_footer_position = mtrack_footer_position;
438   $(window)
439     .scroll(mtrack_footer_position)
440     .resize(mtrack_footer_position);
441   function mtrack_footer_set_and_wait() {
442     mtrack_footer_position();
443     setTimeout(function () {
444       mtrack_footer_set_and_wait();
445     }, 1500);
446   }
447   mtrack_footer_set_and_wait();
448 });
449  
450
451 // from file.php
452
453
454 // from head -- probably for reports only..
455
456  
457 $(document).ready(function() {
458          
459       $.tablesorter.addParser({
460         id: 'priority',
461         is: function(s) {
462           // don't auto-detect
463           return false;
464         },
465         format: function(s) {
466             if (typeof(priorities[s]) != 'undefined') {
467                 return priorities[s];
468             }
469             return s;
470         },
471         type: 'numeric'
472       });
473       
474       $.tablesorter.addParser({
475         id: 'severity',
476         is: function(s) {
477           // don't auto-detect
478           return false;
479         },
480         format: function(s) {
481             if (typeof(severities[s]) != 'undefined') {
482                 return severities[s];
483             }
484             return s;
485         },
486         type: 'numeric'
487     });
488 });
489
490 // from wiki..
491
492 $(document).ready(function(){
493   $('ul.wikitree').treeview({
494     collapsed: true,
495     persist: "location"
496   });
497 });
498
499  */