resources/RooUsage.txt
[app.Builder.js] / old-javascript / JsRender / Roo.vala
1  
2 namespace JsRender {
3
4     static int rid = 0; 
5  
6     class Roo : JsRender 
7     {
8        string region;
9         bool disabled;
10         
11         public Roo(Project.Project project, string path) {
12             base( project, path);
13             this.xtype = "Roo";
14              this.language = "js";
15             
16             
17             //this.items = false;
18             //if (cfg.json) {
19             //    var jstr =  JSON.parse(cfg.json);
20             //    this.items = [ jstr ];
21             //    //console.log(cfg.items.length);
22             //    delete cfg.json; // not needed!
23             // }
24             this.modOrder = "001"; /// sequence id that this uses.
25             this.region = "center";
26             this.disabled = false;
27             
28             // super?!?!
29             this.id = "file-roo-%d".printf(rid++);
30             //console.dump(this);
31             // various loader methods..
32
33             string[]  dsp = { "title",
34                 "legend",
35                 "loadingText",
36                 "emptyText",
37                 "qtip",
38                 "value",
39                 "text",
40                 "emptyMsg",
41                 "displayMsg" };
42             for (var i=0;i<dsp.length;i++) {
43                 this.doubleStringProps.add(dsp[i]);
44             }
45
46             
47         }
48     
49     /*    
50         setNSID : function(id)
51         {
52             
53             this.items[0]['|module'] = id;
54        
55             
56         },
57         
58         
59         getType: function() {
60             return 'Roo';
61         },
62
63     */
64                 
65         public   override void   removeFiles() {
66                 var html = GLib.Path.get_dirname(this.path) +"/templates/" + name + ".html";
67                 if (FileUtils.test(html, FileTest.EXISTS)) {
68                         GLib.FileUtils.remove(html);
69                 }
70                 var js = GLib.Path.get_dirname(this.path) +"/" + name + ".html";
71                 if (FileUtils.test(js, FileTest.EXISTS)) {
72                         GLib.FileUtils.remove(js);
73                 }
74         }
75                 
76         public  override void  loadItems() throws GLib.Error // : function(cb, sync) == original was async.
77         {
78             
79              
80                 print("load Items!");
81                 if (this.tree != null) {
82                         return;
83                 }
84                 print("load " + this.path);
85
86                 var pa = new Json.Parser();
87                 pa.load_from_file(this.path);
88                 var node = pa.get_root();
89
90                 if (node.get_node_type () != Json.NodeType.OBJECT) {
91                         throw new Error.INVALID_FORMAT ("Unexpected element type %s", node.type_name ());
92                 }
93                 var obj = node.get_object ();
94         
95         
96                 this.modOrder = this.jsonHasOrEmpty(obj, "modOrder");
97                 this.name = this.jsonHasOrEmpty(obj, "name");
98                 this.parent = this.jsonHasOrEmpty(obj, "parent");
99                 this.permname = this.jsonHasOrEmpty(obj, "permname");
100                 this.title = this.jsonHasOrEmpty(obj, "title");
101                 this.modOrder = this.jsonHasOrEmpty(obj, "modOrder");
102
103                 var bjs_version_str = this.jsonHasOrEmpty(obj, "bjs-version");
104                 bjs_version_str = bjs_version_str == "" ? "1" : bjs_version_str;
105
106                 
107                 // load items[0] ??? into tree...
108                 if (obj.has_member("items") 
109                         && 
110                         obj.get_member("items").get_node_type() == Json.NodeType.ARRAY
111                         &&
112                         obj.get_array_member("items").get_length() > 0
113                 ) {
114                         this.tree = new Node(); 
115                         var ar = obj.get_array_member("items");
116                         var tree_base = ar.get_object_element(0);
117                         this.tree.loadFromJson(tree_base, int.parse(bjs_version_str));
118                 }
119
120
121             
122         }
123         /**
124          * old code had broken xtypes and used arrays differently,
125          * this code should try and clean it up..
126          * 
127          * 
128          * /
129         fixItems : function(node, fixthis)
130         {
131             if (fixthis) {
132                 // fix xtype.
133                 var fn = this.guessName(node);
134                 //print("guessname got " + fn);
135                 if (fn) {
136                     var bits = fn.split('.');
137                     node.xtype = bits.pop();
138                     node['|xns'] = bits.join('.');
139                     
140                 }
141                 // fix array???
142                  
143                 
144             }
145             if (!node.items || !node.items.length) {
146                 return;
147             }
148             var _this = this;
149             var aitems = [];
150             var nitems = [];
151             node.items.forEach(function(i) {
152                 
153                 
154                 
155                 _this.fixItems(i, true);
156                 if (i.xtype == 'Array') {
157                     aitems.push(i);
158                     return;
159                 }    
160                 nitems.push(i);
161             });
162             node.items = nitems; 
163             
164             if (!aitems.length) {
165                 return;
166             }
167             
168             aitems.forEach(function(i) {
169                 
170                 if (!i.items || !i.items.length) {
171                     return;
172                 }
173                 var prop = i['*prop'] + '[]';
174                 // colModel to cm?
175                 i.items.forEach(function(c) {
176                     c['*prop']  = prop;
177                     node.items.push(c);
178                     
179                 });
180                 
181                 
182             });
183             
184             
185             // array handling.. 
186             
187             
188             
189             
190             
191         },
192     */
193         
194         public  override  void save()
195         {
196             
197                 print("--- JsRender.Roo.save");
198                 this.saveBJS();
199
200                 // no tree..
201                 if (this.tree == null) {
202                         return;
203                 }
204                 // now write the js file..
205                 string js;
206                 try {
207                         Regex regex = new Regex("\\.(bjs|js)$");
208
209                         js = regex.replace(this.path,this.path.length , 0 , ".js");
210                 } catch (RegexError e) {
211                         this.name = "???";
212                         print("count not make filename from path");
213                         return;
214                 }
215
216
217                 //var d = new Date();
218                 var js_src = this.toSource();            
219                 //print("TO SOURCE in " + ((new Date()) - d) + "ms");
220                 try {
221                         this.writeFile(js, js_src);            
222                 } catch (FileError e ) {
223                         print("Save failed\n");
224                 }
225                 // for bootstrap - we can write the HTML to the templates directory..
226                  
227             //var top = this.guessName(this.items[0]);
228             //print ("TOP = " + top)
229              
230             
231             
232             
233         }
234
235          
236
237          
238         public override void saveHTML ( string html )
239         {
240                  
241                 var top = this.tree.fqn();
242                 print ("TOP = " + top + "\n" );
243                 if (top.index_of("Roo.bootstrap.") < 0 &&
244                     top.index_of("Roo.mailer.") < 0
245                         ) {
246                         return;
247                 }
248                 
249                 
250 // now write the js file..
251                 string fn;
252                 try {
253                         Regex regex = new Regex("\\.(bjs|js)$");
254
255                         fn = regex.replace(this.path,this.path.length , 0 , ".html");
256                 } catch (RegexError e) {
257                         this.name = "???";
258                         print("count not make filename from path");
259                         return;
260                 }
261                 var bn = GLib.Path.get_basename(fn);
262                 var dn = GLib.Path.get_dirname(fn);
263
264                 var targetdir = dn + (
265                         top.index_of("Roo.mailer.") < 0 ? "/templates" : "" );
266                               
267                 
268                 if (!FileUtils.test(targetdir, FileTest.IS_DIR)) {
269                         print("Skip save - templates folder does not exist : %s\n", targetdir);
270                         return;
271                 }
272                 print("SAVE HTML -- %s\n%s\n",targetdir + "/" +  bn, html);
273                 try {
274                         this.writeFile(targetdir + "/" +  bn , html);            
275                 } catch (FileError e ) {
276                         print("SaveHtml failed\n");
277                 }
278             
279             
280             
281         }
282
283         public Gee.ArrayList<string> findxincludes(Node node,   Gee.ArrayList<string> ret)
284         {
285                 
286                 if (node.props.has_key("* xinclude")) {
287                         ret.add(node.props.get("* xinclude"));
288                 }
289                 for (var i =0; i < node.items.size; i++) {
290                         this.findxincludes(node.items.get(i), ret);
291                 }
292                 return ret;
293                         
294         }
295             
296         /**
297          * javascript used in Webkit preview 
298          */
299         
300         public override string  toSourcePreview()
301         {
302                 print("to source preview\n");
303                 if (this.tree == null) {
304                         return "";
305                 }
306                 var top = this.tree.fqn();
307                 var xinc = new Gee.ArrayList<string>(); 
308
309                 this.findxincludes(this.tree, xinc);
310                 print("got %d xincludes\n", xinc.size);
311                 var prefix_data = "";
312                 if (xinc.size > 0 ) {
313                         for(var i = 0; i < xinc.size; i++) {
314                                 print("check xinclude:  %s\n", xinc.get(i));
315                                 var sf = this.project.getByName(xinc.get(i));
316                                 if (sf == null) {
317                                         print("Failed to find file by name?\n");
318                                         continue;
319                                 }
320
321                                 sf.loadItems();
322                                 var xinc_str = sf.toSource();
323                                 
324                                 //string xinc_str;
325                                 //FileUtils.get_contents(js, out xinc_str);
326                                 prefix_data += "\n" + xinc_str + "\n";
327                                 
328                         }
329
330                 }
331
332                 
333                 
334                 //print(JSON.stringify(this.items, null,4));
335                        
336                 if (top == null) {
337                         print ("guessname returned false");
338                         return "";
339                 }
340
341
342                 if (top.contains("Dialog")) {
343                         return prefix_data + this.toSourceDialog(true);
344                 }
345
346                 if (top.contains("Modal")) {
347                         return prefix_data + this.toSourceModal(true);
348                 }
349
350                 return prefix_data + this.toSourceLayout(true);
351             
352             
353             
354         }
355         
356         /**
357          * This needs to use some options on the project
358          * to determine how the file is output..
359          * 
360          * At present we are hard coding it..
361          * 
362          * 
363          */
364         public override string toSource()
365         {
366             // dump the file tree back out to a string.
367             
368             // we have 2 types = dialogs and components
369             // 
370             if (this.tree == null) {
371                     return "";
372             }
373             var top = this.tree.fqn();
374             if (top == null) {
375                 return "";
376             }
377             if (top.contains("Dialog")) {
378                 return this.toSourceDialog(false);
379             }
380             
381             if (top.contains("Modal")) {
382                 return this.toSourceModal(false);
383             }
384             return this.toSourceLayout(false);
385             
386             /*
387             eventually support 'classes??'
388              return this.toSourceStdClass();
389             */
390               
391         }
392        
393         public string outputHeader()
394         {
395                 string[] s = {
396                         "//<script type=\"text/javascript\">",
397                         "",
398                         "// Auto generated file - created by app.Builder.js- do not edit directly (at present!)",
399                         ""
400                    
401                 };  
402                 var ret=  string.joinv("\n",s);
403                 var bits = this.name.split(".");
404                 if (bits.length > 1) {
405                         ret += "\nRoo.namespace(\'" + 
406                                 this.name.substring(0, this.name.length - (bits[bits.length-1].length + 1)) +
407                                 "');\n";
408                                 
409                 }
410                 /// genericlly used..
411                   
412                 return ret;
413             
414        
415         }
416         // a standard dialog module.
417         // fixme - this could be alot neater..
418         public string toSourceDialog(bool isPreview) 
419         {
420             
421             //var items = JSON.parse(JSON.stringify(this.items[0]));
422             
423             
424             var o = this.mungeToString("            ");   
425
426  
427             string[] adda = { " = {",
428                 "",
429                 "    dialog : false,",
430                 "    callback:  false,",
431                 "",   
432                 "    show : function(data, cb)",
433                 "    {",
434                 "        if (!this.dialog) {",
435                 "            this.create();",
436                 "        }",
437                 "",
438                 "        this.callback = cb;",
439                 "        this.data = data;",
440                 "        this.dialog.show(this.data._el);",
441                 "        if (this.form) {",
442                 "           this.form.reset();",
443                 "           this.form.setValues(data);",
444                 "           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });",
445                 "        }",
446                 "",   
447                 "    },",
448                 "",
449                 "    create : function()",
450                 "    {",
451                 "        var _this = this;",
452                 "        this.dialog = Roo.factory(" 
453             };
454             string[] addb = {  
455                         ");",
456                 "    }",
457                 "};",
458                 ""
459             };
460             return  this.outputHeader() + "\n" +
461                 this.name + string.joinv("\n", adda) + o + string.joinv("\n", addb);
462             
463              
464              
465              
466         }
467         
468         public string toSourceModal(bool isPreview) 
469         {
470             
471             
472             //var items = JSON.parse(JSON.stringify(this.items[0]));
473             var o = this.mungeToString("            ");   
474             
475             string[] adda = { " = {",
476                 "",
477                 "    dialog : false,",
478                 "    callback:  false,",
479                 "",   
480                 "    show : function(data, cb)",
481                 "    {",
482                 "        if (!this.dialog) {",
483                 "            this.create();",
484                 "        }",
485                 "",
486                 "        this.callback = cb;",
487                 "        this.data = data;",
488                 "        this.dialog.show(this.data._el);",
489                 "        if (this.form) {",
490                 "           this.form.reset();",
491                 "           this.form.setValues(data);",
492                 "           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });",
493                 "        }",
494                 "",   
495                 "    },",
496                 "",
497                 "    create : function()",
498                 "    {",
499                 "        var _this = this;",
500                 "        this.dialog = Roo.factory("
501             };
502             string[] addb =  {
503                 ");",
504                 "    }",
505                 "};",
506                 ""
507             };
508             return this.outputHeader() + "\n" + 
509                 this.name + string.joinv("\n", adda) + o + string.joinv("\n", addb);
510              
511              
512              
513         }
514         
515         
516         public string   pathToPart()
517         {
518             var dir = Path.get_basename(Path.get_dirname(this.path));
519             var ar = dir.split(".");
520             var modname = ar[ar.length-1];
521             
522             // now we have the 'module name'..
523             var fbits = Path.get_basename(this.path).split(".");
524             
525              
526             var npart = fbits[fbits.length - 2]; // this should be 'AdminProjectManager' for example...
527             if (modname.length < npart.length && npart.substring(0, modname.length) == modname) {
528                 npart = npart.substring(modname.length);
529             }
530             return "[" + this.tree.quoteString(modname) + ", " + this.tree.quoteString(npart) + " ]";
531             //return ret;
532             
533             
534             
535             
536         }
537         
538         // a layout compoent 
539         public string toSourceLayout(bool isPreview) 
540         {
541           
542             
543                 if (isPreview) {
544                         //       topItem.region = 'center';
545                         //    topItem.background = false;
546                 }
547             
548                 var o = this.mungeToString("            ");   
549                 var reg = new Regex("[^A-Za-z.]+");
550             
551                 string modkey = this.modOrder + "-" + reg.replace(this.name, this.name.length, 0 , "-");
552             
553                 string  parent =   (this.parent.length > 0 ?  "'" + this.parent + "'" :  "false");
554
555                 
556                 
557                 if (isPreview) {
558                         // set to false to ensure this is the top level..
559                         parent = "false";
560                         var topnode = this.tree.fqn();
561                         print("topnode = %s\n", topnode);
562                         if (GLib.Regex.match_simple("^Roo\\.bootstrap\\.",topnode) &&
563                             topnode != "Roo.bootstrap.Body"
564                         ) {
565                                 parent = "\"#bootstrap-body\"";
566                         }
567                           
568                 }
569             
570           
571                 return 
572                         this.outputHeader() + "\n" +
573                         
574                         this.name  +  " = new Roo.XComponent({\n" +
575                         "    part     :  "+ this.pathToPart() + ",\n" +
576                                 /// critical used by builder to associate modules/parts/persm
577                         "    order    : '" +modkey+"',\n" +
578                         "    region   : '" + this.region   +"',\n" +
579                         "    parent   : "+ parent + ",\n" +
580                         "    name     : " + this.tree.quoteString(this.title.length > 0 ? this.title : "unnamed module") + ",\n" +
581                         "    disabled : " + (this.disabled ? "true" : "false") +", \n" +
582                         "    permname : '" + (this.permname.length > 0 ? this.permname : "") +"', \n" +
583                             
584                        // "    tree : function() { return this._tree(); },\n" +   //BC
585                         "    _tree : function()\n" +
586                         "    {\n" +
587                         "        var _this = this;\n" + // bc
588                         "        var MODULE = this;\n" + /// this looks like a better name.
589                         "        return " + o + ";" +
590                         "    }\n" +
591                         "});\n";
592                          
593              
594             
595         }
596             
597         public new string? guessName (Node? ar) // turns the object into full name.
598         {
599              // eg. xns: Roo, xtype: XXX -> Roo.xxx
600             if (ar == null) {
601                 return null;
602             }
603             
604             string[] ret = {} ;
605             ret += (ar.get("|xns").length < 1 ? "Roo": ar.get("|xns"));
606              
607             
608             if ( ar.get("xtype").length < 1) {
609                 return null;
610             }
611                     
612             var xtype = ar.get("xtype");
613
614             if (xtype[0] == '*') { // prefixes????
615                 xtype  = xtype.substring(1);
616             }
617             if (! Regex.match_simple("^Roo", xtype)) {
618                 
619                 // already starts with roo...
620                 ret = {};
621             }
622             ret += xtype;
623             var str =  string.joinv(".", ret);
624             
625             return str;
626            // 
627             //Palete.Palete.factory("Roo").guessName(str);
628             
629                             
630                                  
631         }
632         
633         string getHelpUrl(string cls)
634         {
635             return "http://www.roojs.com/roojs1/docs/symbols/" + cls + ".html";
636         }
637                  
638      
639     }
640 }