Palete/Gtk.js
[app.Builder.js] / JsRender / Roo.js
1 //<Script type="text/javascript">
2
3  
4 Gio = imports.gi.Gio;
5 GLib= imports.gi.GLib;
6 XObject = imports.XObject.XObject;
7
8   
9 //----------------------- our roo verison
10 Base = imports.JsRender.Base.Base;
11 File = imports.File.File;
12
13
14 //----------------------- our roo verison
15
16 var rid = 0;
17
18 Roo = XObject.define(
19     function(cfg) {
20         
21         // id ,
22         //"name":"Edit Module Details",
23         // items : 
24         //"btype":"FORM", // was to be components...
25         //"app":"Builder",
26         //"module":"Pman.Tab.BuilderTop2"
27         //console.dump(cfg);
28         
29         if (!cfg.name || !cfg.fullname ) {
30             cfg.name = cfg.path.split('/').pop().replace(/\.bjs$/, '').replace(/\.js$/, '');
31             //cfg.fullname = (cfg.parent && cfg.parent.length ? (cfg.parent + '.') : '' ) + cfg.name;
32             cfg.fullname = cfg.name;
33         }
34         
35         
36         this.items = false;
37         if (cfg.json) {
38             var jstr =  JSON.parse(cfg.json);
39             this.items = [ jstr ];
40             //console.log(cfg.items.length);
41             delete cfg.json; // not needed!
42         }
43         this.cn = [];
44         
45         Roo.superclass.constructor.call(this, cfg);
46
47         
48         // super?!?!
49         this.id = 'roo-file-' + (rid++);
50         // various loader methods..
51     },
52     Base,
53     {
54         doubleStringProps : [ 
55             'title',
56             'legend',
57             'loadingText',
58             'emptyText',
59             'qtip',
60             'value',
61             'text',
62             'emptyMsg',
63             'displayMsg'
64         ],
65         path : '', // the file path..
66         modOrder : '001', /// sequence id that this uses.
67         region : 'center',
68         parent : '',
69         title : '', // the title on displayed when loading.
70         disable : '', // use a function to that returns false to disable this..
71         permname: '', /// permission name
72         
73         items: false,
74         
75         setNSID : function(id)
76         {
77             
78             this.items[0]['|module'] = id;
79        
80             
81         },
82         
83         
84         getType: function() {
85             return 'Roo';
86         },
87        
88       
89         loadItems : function(cb, sync)
90         {
91             
92             
93             
94             print("load Items!");
95             if (this.items !== false) {
96                 return false;
97             }
98             
99             var _this = this;
100              
101             function loaded(src) {
102                 var cfg = JSON.parse(src);
103                 print("loaded data");
104                 //print(JSON.stringify(cfg, null,4));
105                 _this.modOrder = cfg.modOrder || '001';
106                 _this.name = cfg.name.replace(/\.bjs/, ''); // BC!
107                 _this.parent =  cfg.parent;
108                 _this.permname =  cfg.permname || '';
109                 _this.title =  cfg.title;
110                 _this.items = cfg.items || []; 
111                 
112                 _this.fixItems(_this, false);
113                 
114                 
115                 
116                 cb();
117             }
118             if (sync) {
119                 loaded(File.read(this.path));
120                 return true;
121             }
122             
123             
124             var file = Gio.file_new_for_path(this.path);
125             
126                              
127             file.read_async(0, null, function(source,result) {
128                 var stream = source.read_finish(result)
129                 var dstream = new Gio.DataInputStream.c_new(stream);
130                 
131                 loaded (dstream.read_until(""));
132                 
133                 
134                  
135                 
136             });
137             
138             return true;
139             
140         },
141         /**
142          * old code had broken xtypes and used arrays differently,
143          * this code should try and clean it up..
144          * 
145          * 
146          */
147         fixItems : function(node, fixthis)
148         {
149             if (fixthis) {
150                 // fix xtype.
151                 var fn = this.guessName(node);
152                 //print("guessname got " + fn);
153                 if (fn) {
154                     var bits = fn.split('.');
155                     node.xtype = bits.pop();
156                     node['|xns'] = bits.join('.');
157                     
158                 }
159                 // fix array???
160                  
161                 
162             }
163             if (!node.items || !node.items.length) {
164                 return;
165             }
166             var _this = this;
167             var aitems = [];
168             var nitems = [];
169             node.items.forEach(function(i) {
170                 
171                 
172                 
173                 _this.fixItems(i, true);
174                 if (i.xtype == 'Array') {
175                     aitems.push(i);
176                     return;
177                 }    
178                 nitems.push(i);
179             });
180             node.items = nitems; 
181             
182             if (!aitems.length) {
183                 return;
184             }
185             
186             aitems.forEach(function(i) {
187                 
188                 if (!i.items || !i.items.length) {
189                     return;
190                 }
191                 var prop = i['*prop'] + '[]';
192                 // colModel to cm?
193                 i.items.forEach(function(c) {
194                     c['*prop']  = prop;
195                     node.items.push(c);
196                     
197                 });
198                 
199                 
200             });
201             
202             
203             // array handling.. 
204             
205             
206             
207             
208             
209         },
210         
211         save : function()
212         {
213             
214             print("--- JsRender.Roo.save");
215             Base.prototype.save.call(this);
216             // now write the js file..
217             var js = this.path.replace(/\.bjs$/, '.js');
218             var d = new Date();
219             var js_src = this.toSource();            
220             print("TO SOURCE in " + ((new Date()) - d) + "ms");
221             File.write(js, js_src);
222             // for bootstrap - we can write the HTML to the templates directory..
223             
224             var top = this.guessName(this.items[0]);
225             print ("TOP = " + top)
226              
227             
228             
229             
230             
231             
232         },
233         saveHTML : function(frame) {
234             var top = this.guessName(this.items[0]);
235             print ("TOP = " + top)
236             if (top != 'Roo.bootstrap.Body') {
237                 return;
238             }
239             print("SAVE HTML -- ");
240             print(frame);
241             var _this = this;
242             // wait a second.
243             
244             GLib.timeout_add_seconds(0, 1, function() {
245                 //    print("run refresh?");
246                 var html = _this.traversedom(frame);
247                 //print(html);
248                 
249                 //print(_this.path);
250                 var dir = File.dirname(_this.path) +  File.SEPARATOR + 'templates';
251                 //print(dir);
252                 if (!File.isDirectory(dir)) {
253                     print("Skip no template sub-directory");
254                     return false;
255                 }
256                 var fn = dir + File.SEPARATOR + File.basename(_this.path).replace(/\.bjs$/, '.html');
257                 //print(fn);
258                 File.write(fn, html);
259                 
260                 
261                  return false; // only once..
262                 
263                 
264                 
265             });
266             
267             
268             
269             
270         },
271         
272         
273         traversedom :  function(web_frame) {
274             print("TRAVERSE DOM?");
275             
276             var dom = web_frame.get_dom_document().body;
277             print(dom);
278             var ret = '';
279             //Roo.select('body > div',true).each(function(el) {
280             this.traverseDOMTree(function(s) { ret+=s; }, dom, 1);
281             return ret;
282         },
283         
284         
285         traverseDOMTree : function(cb, currentElement, depth) {
286             if (!currentElement) {
287                 
288                 return;
289             }
290             if (currentElement.class_name.match(/roo-dynamic/)) {
291                 return;
292             }
293             
294             //Roo.log(currentElement);
295             var j;
296             var nodeName = currentElement.node_name;
297             var tagName = currentElement.tag_name;
298             
299             if  (nodeName == '#text') {
300                 cb(currentElement.node_value);
301                 return;
302             
303             }
304              
305             
306             
307             if(nodeName == 'BR'){
308                 cb("<BR/>");
309                 return;
310             }
311             if (nodeName != 'BODY') {
312                 
313             
314             
315                 var i = 0;
316               // Prints the node tagName, such as <A>, <IMG>, etc
317                 if (tagName) {
318                     var attr = [];
319                     for(i = 0; i < currentElement.attributes.length;i++) {
320                         var aname = currentElement.attributes.item(i).name;
321                         if (aname=='id') {
322                             aname= 'xbuilderid';
323                         }
324                         // skip
325                         if (currentElement.attributes.item(i).value == 'builderel') {
326                             return;
327                         }
328                         attr.push(aname + '="' + currentElement.attributes.item(i).value + '"' );
329                     }
330                     
331                     
332                     cb("<"+currentElement.tag_name+ ( attr.length ? (' ' + attr.join(' ') ) : '') + ">");
333                 } 
334                 else {
335                   cb("[unknown tag]");
336                 }
337             } else {
338                 tagName = false;
339             }
340             // Traverse the tree
341             i = 0;
342             var currentElementChild = currentElement.child_nodes.item(i);
343             var allText = true;
344             while (currentElementChild) {
345                 // Formatting code (indent the tree so it looks nice on the screen)
346                 
347                 if  (currentElementChild.node_name == '#text') {
348                     cb(currentElementChild.node_value);
349                     i++;
350                     currentElementChild=currentElement.child_nodes.item(i);
351                     continue;
352                 }   
353                 allText = false;
354                 cb("\n");
355                 for (j = 0; j < depth; j++) {
356                   // &#166 is just a vertical line
357                   cb("  ");
358                 }               
359                 
360                     
361                 // Recursively traverse the tree structure of the child node
362                 this.traverseDOMTree(cb, currentElementChild, depth+1);
363                 i++;
364                 currentElementChild=currentElement.child_nodes.item(i);
365             }
366             if (!allText) {
367                     // The remaining code is mostly for formatting the tree
368                 cb("\n");
369                 for (j = 0; j < depth - 1; j++) {
370                   cb("  ");
371                 }     
372             }
373             if (tagName) {
374                 cb("</"+tagName+">");
375             }
376             
377         },
378         
379         
380         
381          /**
382          * convert xtype for munged output..
383          * 
384          */
385         mungeXtype : function(xtype, els)
386         {
387             var bits = xtype.split('.');
388             // assume it has lenght!
389             
390             els.push("xtype: '"+ bits.pop()+"'");
391             els.push('xns: '+ bits.join('.'));
392             if (xtype.match(/bootstrap/)) {
393                 els.push("'xtype-bootstrap' : '"+ xtype +"'");
394             }
395                 //code
396             
397             
398             
399         },
400         
401         
402         toSourcePreview: function()
403         {
404             
405             var top = this.guessName(this.items[0]);
406             print(JSON.stringify(this.items, null,4));
407                        
408             if (!top) {
409                 return false;
410             }
411             
412             
413             if (top.match(/Dialog/)) {
414                 return this.toSourceDialog(true);
415             }
416             
417             if (top.match(/Modal/)) {
418                 return this.toSourceModal(true);
419             }
420             
421             return this.toSourceLayout(true);
422             
423             
424             
425         },
426         
427         /**
428          * This needs to use some options on the project
429          * to determine how the file is output..
430          * 
431          * At present we are hard coding it..
432          * 
433          * 
434          */
435         toSource: function()
436         {
437             // dump the file tree back out to a string.
438             
439             // we have 2 types = dialogs and components
440             // 
441             var top = this.guessName(this.items[0]);
442             if (!top) {
443                 return false;
444             }
445             if (top.match(/Dialog/)) {
446                 return this.toSourceDialog();
447             }
448             
449             if (top.match(/Modal/)) {
450                 return this.toSourceModal(true);
451             }
452             return this.toSourceLayout();
453             
454             /*
455             eventually support 'classes??'
456              return this.toSourceStdClass();
457             */
458               
459         },
460        
461         outputHeader : function()
462         {
463             return [
464                 "//<script type=\"text/javascript\">",
465                 "",
466                 "// Auto generated file - created by app.Builder.js- do not edit directly (at present!)",
467                 ""
468             ].join("\n");
469             
470        
471         },
472         // a standard dialog module.
473         // fixme - this could be alot neater..
474         toSourceDialog : function(isPreview) 
475         {
476             
477             isPreview = isPreview || false;
478             var items = JSON.parse(JSON.stringify(this.items[0]));
479             var o = this.mungeToString(items, false, '            ');   
480             return [
481                 this.outputHeader(),
482                 this.name + " = {",
483                 "",
484                 "    dialog : false,",
485                 "    callback:  false,",
486                 "",   
487                 "    show : function(data, cb)",
488                 "    {",
489                 "        if (!this.dialog) {",
490                 "            this.create();",
491                 "        }",
492                 "",
493                 "        this.callback = cb;",
494                 "        this.data = data;",
495                 "        this.dialog.show(this.data._el);",
496                 "        if (this.form) {",
497                 "           this.form.reset();",
498                 "           this.form.setValues(data);",
499                 "           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });",
500                 "        }",
501                 "",   
502                 "    },",
503                 "",
504                 "    create : function()",
505                 "    {",
506                 "        var _this = this;",
507                 "        this.dialog = Roo.factory(" + o +  ");",
508                 "    }",
509                 "};",
510                 ""
511                 
512              ].join("\n");
513              
514              
515              
516         },
517         
518         toSourceModal : function(isPreview) 
519         {
520             
521             isPreview = isPreview || false;
522             var items = JSON.parse(JSON.stringify(this.items[0]));
523             var o = this.mungeToString(items, false, '            ');   
524             return [
525                 this.outputHeader(),
526                 this.name + " = {",
527                 "",
528                 "    dialog : false,",
529                 "    callback:  false,",
530                 "",   
531                 "    show : function(data, cb)",
532                 "    {",
533                 "        if (!this.dialog) {",
534                 "            this.create();",
535                 "        }",
536                 "",
537                 "        this.callback = cb;",
538                 "        this.data = data;",
539                 "        this.dialog.show(this.data._el);",
540                 "        if (this.form) {",
541                 "           this.form.reset();",
542                 "           this.form.setValues(data);",
543                 "           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });",
544                 "        }",
545                 "",   
546                 "    },",
547                 "",
548                 "    create : function()",
549                 "    {",
550                 "        var _this = this;",
551                 "        this.dialog = Roo.factory(" + o +  ");",
552                 "    }",
553                 "};",
554                 ""
555                 
556              ].join("\n");
557              
558              
559              
560         },
561         
562         
563         pathToPart : function()
564         {
565             var dir = File.basename(File.dirname(this.path));
566             var modname = dir.split('.').pop();
567             
568             // now we have the 'module name'..
569             var fbits = File.basename(this.path).split('.');
570             fbits.pop(); // remove extension..
571             var npart = fbits.pop(); // this should be 'AdminProjectManager' for example...
572             if (npart.substring(0, modname.length) == modname) {
573                 npart = npart.substring(modname.length);
574             }
575             return [ modname , npart];
576             
577             
578             
579             
580         },
581         
582         // a layout compoent 
583         toSourceLayout : function(isPreview) 
584         {
585             isPreview = isPreview || false;
586             var topItem = JSON.parse(JSON.stringify(this.items[0]));
587             if (isPreview) {
588                 topItem.region = 'center';
589                 topItem.background = false;
590             }
591             
592             var o = this.mungeToString(topItem, false, '            ');   
593              
594             var modkey = this.modOrder + '-' + this.name.replace(/[^A-Z.]+/ig, '-');
595             
596             var parent =   (this.parent ?  "'" + this.parent + "'" :  'false');
597             if (isPreview) {
598                 parent = 'false'
599             }
600             
601           
602             return [
603                 this.outputHeader(),
604                 
605                 this.name  +  " = new Roo.XComponent({",
606                 "    part     :  "+ JSON.stringify(this.pathToPart()) + ",",
607                         /// critical used by builder to associate modules/parts/persm
608                 "    order    : '" +modkey+"',",
609                 "    region   : '" + this.region   +"',",
610                 "    parent   : "+ parent + ",",
611                 "    name     : " + JSON.stringify(this.title  || "unnamed module") + ",",
612                 "    disabled : " + (this.disabled || 'false') +", ",
613                 "    permname : '" + (this.permname|| '') +"', ",
614                     
615                // "    tree : function() { return this._tree(); },",   //BC
616                 "    _tree : function()",
617                 "    {",
618                 "        var _this = this;", // bc
619                 "        var MODULE = this;", /// this looks like a better name.
620                 "        return " + o + ';',
621                 "    }",
622                 "});",
623                 ""
624                  
625              ].join("\n");
626             
627         },
628             
629         guessName : function(ar) // turns the object into full name.
630         {
631              // eg. xns: Roo, xtype: XXX -> Roo.xxx
632             if (!ar) {
633                 return false;
634             }
635             var ret = [];
636             ret.push(typeof( ar['|xns'] ) == 'undefined' ? 'Roo' : ar['|xns'] );
637             
638             
639             
640             if (typeof( ar['xtype'] ) == 'undefined' || !ar['xtype'].length) {
641                 return false;
642             }
643             var xtype = ar['xtype'] + '';
644             if (xtype[0] == '*') { // prefixes????
645                 xtype  = xtype.substring(1);
646             }
647             if (xtype.match(/^Roo/)) {
648                 // already starts with roo...
649                 ret = [];
650             }
651             ret.push(xtype);
652             var str =  ret.join('.');
653             
654             
655             
656             var pm = imports.ProjectManager.ProjectManager;
657             return pm.getPalete('Roo').guessName(ret.join('.'));
658             
659                             
660                                  
661         },
662         /*
663         getTree : function( o ) {
664             
665             
666             
667         }
668         */
669         getHelpUrl : function(cls)
670         {
671             return 'http://www.akbkhome.com/roojs1/docs/symbols/' + cls + '.html';
672         }
673         
674 });