Palete/Gtk.js
[app.Builder.js] / JsRender / Node.vala
1
2 // test..
3 // valac gitlive/app.Builder.js/JsRender/Lang.vala gitlive/app.Builder.js/JsRender/Node.vala --pkg gee-1.0 --pkg=json-glib-1.0 -o /tmp/Lang ;/tmp/Lang
4
5 public class JsRender.Node  {
6     
7     public GLib.List<Node> items; // child items..
8     
9     public Gee.HashMap<string,string> props; // the properties..
10     public Gee.HashMap<string,string> listeners; // the listeners..
11     public string  xvala_cls;
12         public string xvala_xcls; // 'Xcls_' + id;
13     public string xvala_id; // item id or ""
14             
15     public bool is_array;
16     
17     public Node()
18     {
19         this.items = new GLib.List<Node>();
20         this.props = new Gee.HashMap<string,string>();
21                 this.listeners = new Gee.HashMap<string,string>();
22         this.is_array = false;
23         this.xvala_xcls = "";
24     }
25     
26     
27     
28     
29     public bool isArray()
30     {
31         return this.is_array;
32     }
33     public bool hasChildren()
34     {
35         return this.items.length() > 0;
36     }
37     public bool hasXnsType()
38     {
39         if (this.props.get("|xns") != null && this.props.get("xtype") != null) {
40             return true;
41             
42         }
43         return false;
44     }
45         public string fqn()
46         {
47                 if (!this.hasXnsType ()) {
48                         return "";
49                 }
50                 return this.props.get("|xns") + "." + this.props.get("xtype"); 
51
52         }
53         
54     // wrapper around get props that returns empty string if not found.
55     public string get(string key)
56     {
57         var k = this.props.get(key);
58         if (k != null) {
59                         return k;
60                 }
61                 
62                 k = this.props.get("|" + key);
63                 if (k != null) {
64                         
65                 return k;
66                 }
67         
68         return "";
69         
70     }
71      
72     /* creates javascript based on the rules */
73     public Node? findProp(string n) {
74                 for(var i=0;i< this.items.length();i++) {
75                         var p = this.items.nth_data(i).get("*prop");
76                         if (this.items.nth_data(i).get("*prop").length < 1) {
77                                 continue;
78                         }
79                         if (p == n) {
80                                 return this.items.nth_data(i);
81                         }
82                 }
83                 return null;
84
85         }
86
87         string gLibStringListJoin( string sep, GLib.List<string> ar) 
88         {
89                 var ret = "";
90                 for (var i = 0; i < ar.length(); i++) {
91                         ret += i>0 ? sep : "";
92                         ret += ar.nth_data(i);
93                 }
94                 return ret;
95
96         }
97     
98     public string mungeToString (bool isListener, string pad,  GLib.List<string> doubleStringProps)
99     {
100         
101          
102         pad = pad.length < 1 ? "    " : pad;
103         
104         
105          
106         
107         //isListener = isListener || false;
108
109        //var keys = this.keys();
110         var isArray = this.isArray();
111         
112         
113         var els = new GLib.List<string>(); 
114         var skip = new Gee.ArrayList<string>();
115         if (!isArray && this.hasXnsType() ) {
116                 // this.mungeXtype(obj['|xns'] + '.' + obj['xtype'], els); ??????
117                 
118                 
119                skip.add("|xns");
120                skip.add("xtype");
121                
122         }
123         //var newitems = new Gee.ArrayList<JsRender.Node>();
124         var oprops = new Gee.HashMap<string,Node>();
125         
126         if (!isArray && this.hasChildren()) {
127             // look for '*props'
128            
129             for (var ii =0; ii< this.items.length(); ii++) {
130                 var pl = this.items.nth_data(ii);
131                 if (!pl.props.has_key("*prop")) {
132                     //newitems.add(pl);
133                     continue;
134                 }
135                 
136                 //print(JSON.stringify(pl,null,4));
137                 // we have a prop...
138                 //var prop = pl['*prop'] + '';
139                 //delete pl['*prop'];
140                 var prop = pl.get("*prop");
141                 // name ends in [];
142                 if (! Regex.match_simple("\\[\\]$", prop)) {
143                     // it's a standard prop..
144                     
145                     // munge property..??
146                     oprops.set(prop, pl);
147                     
148                     
149                     //keys.push(prop);
150                     continue;
151                 }
152                 
153                 prop  = prop.substring(0,  -2); //strip []
154                 // it's an array type..
155                 if (!oprops.has_key(prop)) {
156                     var cn = new Node();
157                     oprops.set(prop, cn);
158                     
159                 }
160                 // ignores the fact it might be duplciated...
161                 oprops.get(prop).is_array = true;
162                 oprops.get(prop).items.append(pl);
163               
164                 
165                 
166                 
167             }
168             
169             //obj.items = newitems;
170             //if (!obj.items.length) {
171             //    delete obj.items;
172             //}
173             
174         }
175         if (this.isArray()) {
176             
177             
178             for (var i=0;i< this.items.length();i++) {
179                 var el = this.items.nth_data(i);
180                 
181                 els.append("%d".printf(i) + " : " + el.mungeToString(false, pad,doubleStringProps));
182                 
183             }
184             var spad = pad.substring(0, pad.length-4);
185             return   "{\n" +
186                 pad  + this.gLibStringListJoin(",\n" + pad , els) + 
187                 "\n" + spad +  "}";
188                
189             
190             
191             
192           
193         } 
194         string left;
195         Regex func_regex ;
196         try {
197             func_regex = new Regex("^\\s+|\\s+$");
198         } catch (Error e) {
199             print("failed to build regex");
200             return "";
201         }
202         var piter = this.props.map_iterator();
203         while (piter.next() ) {
204             var k = piter.get_key();
205             var v = piter.get_value();
206             
207             if (skip.contains(k) ) {
208                 continue;
209             }
210             
211             
212             string leftv = k[0] == '|' ? k.substring(1) : k;
213             // skip builder stuff. prefixed with  '.' .. just like unix fs..
214             if (leftv[0] == '.') { // |. or . -- do not output..
215                 continue;
216             }
217              if (k[0] == '*') {
218                 // ignore '*prop';
219                 continue;
220              }
221                 
222             
223             if (Lang.isKeyword(leftv) || Lang.isBuiltin(leftv)) {
224                 left = "'" + leftv + "'";
225             } else if (Regex.match_simple("[^A-Za-z_]+",leftv)) { // not plain a-z... - quoted.
226                 var val = this.quoteString(leftv);
227                 
228                 left = "'" + val.substring(1, val.length-1).replace("'", "\\'") + "'";
229             } else {
230                 left = leftv;
231             }
232             left += " : ";
233             
234             if (isListener) {
235             // change the lines...
236                 /*           
237                 string str = "";
238                 try {
239                     str = func_regex.replace(v,v.length, 0, "");
240                 } catch(Error e) {
241                     print("regex failed");
242                     return "";
243                 }
244                 */
245                                 var str = v.strip();
246                 var lines = str.split("\n");
247                 if (lines.length > 0) {
248                     str = string.joinv("\n" + pad, lines);
249                 }
250                 
251                 els.append(left  + str);
252                 continue;
253             }
254              
255             // next.. is it a function..
256             if (k[0] == '|') {
257                 // does not hapepnd with arrays.. 
258                 if (v.length < 1) {  //if (typeof(el) == 'string' && !obj[i].length) { //skip empty.
259                     continue;
260                 }
261                                 /*
262                         print(v);
263                 string str = "";
264                 try {
265                     str = func_regex.replace(v,v.length, 0, "");
266                 } catch(Error e) {
267                     print("regex failed");
268                     return "";
269                 }
270                 */
271                 var str = v.strip();
272                                   
273                 var lines = str.split("\n");
274                                   
275                 if (lines.length > 0) {
276                     str =  string.joinv("\n" + pad, lines);
277                 }
278                 //print("==> " +  str + "\n");
279                 els.append(left + str);
280                 continue;
281             }
282             // standard..
283             
284             
285             if (Lang.isNumber(v) || Lang.isBoolean(v)) { // boolean or number...?
286                 els.append(left + v );
287                 continue;
288             }
289             
290             // strings..
291             if (doubleStringProps.length() < 1) {
292                 els.append(left + this.quoteString(v));
293                 continue;
294             }
295            
296             if (doubleStringProps.index(k) > -1) {
297                 els.append(left + this.quoteString(v));
298                 continue;
299             }
300              
301             // single quote.. v.substring(1, v.length-1).replace("'", "\\'") + "'";
302             els.append(left + "'" + v.substring(1, v.length-1).replace("'", "\\'") + "'");
303             
304
305            
306            
307            
308         }
309         var iter = oprops.map_iterator();
310         while (iter.next()) {
311             var k = iter.get_key();
312             var vo = iter.get_value();
313             string leftv = k[0] == '|' ? k.substring(1) : k;
314             if (Lang.isKeyword(leftv) || Lang.isBuiltin(leftv)) {
315                 left = "'" + leftv + "'";
316             } else if (Regex.match_simple("[^A-Za-z_]+",leftv)) { // not plain a-z... - quoted.
317                 var val = this.quoteString(leftv);
318                 
319                 left = "'" + val.substring(1, val.length-1).replace("'", "\\'") + "'";
320             } else {
321                 left = leftv;
322             }
323             left += " : ";
324             
325             var right = vo.mungeToString(k == "listeners", pad + "    ",doubleStringProps);
326             
327             //if (!left.length && isArray) print(right);
328             
329             if (right.length > 0){
330                 els.append(left + right);
331             }
332         
333             
334         }
335
336
337                 if (this.listeners.size > 0) {
338                         // munge the listeners.
339                         //print("ADDING listeners?");
340                         
341                         var liter = this.listeners.map_iterator();
342                 
343                     var itms = "listeners : {\n";
344                         var i =0;
345                     while (liter.next()) {
346                                 
347                                 itms += i >0 ? ",\n" : "";    
348                                 // 
349                                 var str = liter.get_value().strip();
350                 var lines = str.split("\n");
351                 if (lines.length > 0) {
352                     str = string.joinv("\n" + pad + "       ", lines);
353                 }
354                 
355
356                                 
357                                 itms +=  pad + "    "  + liter.get_key()  + " : " + str;
358
359                                 i++;
360                         
361                                 
362                         }
363                         itms += "\n" + pad + "}";
364                         //print ( "ADD " + itms); 
365                         els.append(itms);
366
367                 }
368
369
370                 
371                 // finally munge the children...
372                 if (this.items.length()> 0) {
373                         var itms = "items : [\n";
374                         for(var i = 0; i < this.items.length();i++) {
375                                 // 
376                                 itms +=    pad + "    "  +
377                                         this.items.nth_data(i).mungeToString(false, pad + "        ",  doubleStringProps) + "\n";
378
379
380                         }
381                         
382                         els.append(itms);
383                 }
384
385                 // finally output listeners...
386                 
387
388                 
389
390
391
392                         
393         if (els.length() < 1) {
394             return "";
395         }
396         // oprops...    
397             
398         var spad = pad.substring(0, pad.length-4);
399         return   "{\n" +
400             pad  + gLibStringListJoin(",\n" + pad , els) + 
401             "\n" + spad +  "}";
402            
403            
404                
405         
406         
407     }
408     static Json.Generator gen = null;
409     
410     public string quoteString(string str)
411     {
412         if (Node.gen == null) {
413             Node.gen = new Json.Generator();
414         }
415        var n = new Json.Node(Json.NodeType.VALUE);
416                 n.set_string(str);
417  
418         Node.gen.set_root (n);
419         return  Node.gen.to_data (null);   
420     }
421
422     public void loadFromJson(Json.Object obj) {
423         obj.foreach_member((o , key, value) => {
424                         //print(key+"\n");
425             if (key == "items") {
426                 var ar = value.get_array();
427                 ar.foreach_element( (are, ix, el) => {
428                     var node = new Node();
429                     node.loadFromJson(el.get_object());
430                     this.items.append(node);
431                 });
432                 return;
433             }
434             if (key == "listeners") {
435                 var li = value.get_object();
436                 li.foreach_member((lio , li_key, li_value) => {
437                     this.listeners.set(li_key, li_value.get_string());
438
439                 });
440                 return;
441             }
442                         var v = value.get_value();
443                         var sv =  Value (typeof (string));
444                         v.transform(ref sv);
445                          
446             this.props.set(key,  (string)sv);
447         });
448         
449
450
451
452     }
453     public Json.Object toJsonObject()
454         {
455                 var ret = new Json.Object();
456
457                 // listeners...
458                 var li = new Json.Object();
459                 ret.set_object_member("listeners", li);
460                 var liter = this.listeners.map_iterator();
461         while (liter.next()) {
462                         li.set_string_member(liter.get_key(), liter.get_value());
463                 }
464
465                 //props
466             var iter = this.props.map_iterator();
467         while (iter.next()) {
468                         this.jsonObjectsetMember(ret, iter.get_key(), iter.get_value());
469                 }
470                 
471                 var ar = new Json.Array();
472                 ret.set_array_member("items", ar);
473                 
474                 // children..
475                 for(var i =0;i < this.items.length();i++) {
476                         ar.add_object_element(this.items.nth_data(i).toJsonObject());
477         }
478                 return ret;
479                 
480  
481         }
482          
483         public void jsonObjectsetMember(Json.Object o, string key, string val) {
484                 if (Lang.isBoolean(val)) {
485                         o.set_boolean_member(key, val == "false" ? false : true);
486                         return;
487                 }
488                 
489                 
490                 if (Lang.isNumber(val)) {
491                         if (val.contains(".")) {
492                                 //print( "ADD " + key + "=" + val + " as a double?\n");
493                                 o.set_double_member(key, double.parse (val));
494                                 return;
495
496                         }
497                         //print( "ADD " + key + "=" + val + " as a int?\n")  ;
498                         o.set_int_member(key,long.parse(val));
499                         return;
500                 }
501                 ///print( "ADD " + key + "=" + val + " as a string?\n");
502                 o.set_string_member(key,val);
503                 
504         }
505     
506 }