JsRender/Node.vala
[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     GLib.List<Node> items; // child items..
8     
9     Gee.HashMap<string,string> props; // the properties..
10     
11   
12     
13     public bool is_array;
14     
15     Node()
16     {
17         this.items = new GLib.List<Node>();
18         this.props = new Gee.HashMap<string,string>();
19         this.is_array = false;
20         
21     }
22     
23     
24     
25     
26     public bool isArray()
27     {
28         return this.is_array;
29     }
30     public bool hasChildren()
31     {
32         return this.items.length() > 0;
33     }
34     public bool hasXnsType()
35     {
36         if (this.props.get("|xns") != null && this.props.get("xtype") != null) {
37             return true;
38             
39         }
40         return false;
41     }
42     // wrapper around get props that returns empty string if not found.
43     public string get(string key)
44     {
45         var k = this.props.get(key);
46         if (k == null) {
47             return "";
48         }
49         return k;
50         
51     }
52      
53     /* creates javascript based on the rules */
54     
55   
56     
57     public string mungeToString (bool isListener, string pad,  GLib.List<string> doubleStringProps)
58     {
59         
60          
61         pad = pad.length < 1 ? "    " : pad;
62         
63         
64          
65         
66         //isListener = isListener || false;
67
68        //var keys = this.keys();
69         var isArray = this.isArray();
70         
71         
72         var els = new GLib.List<string>(); 
73         var skip = new Gee.ArrayList<string>();
74         if (!isArray && this.hasXnsType() ) {
75                 // this.mungeXtype(obj['|xns'] + '.' + obj['xtype'], els); ??????
76                 
77                 
78                skip.add("|xns");
79                skip.add("xtype");
80                
81         }
82         //var newitems = new Gee.ArrayList<JsRender.Node>();
83         var oprops = new Gee.HashMap<string,Node>();
84         
85         if (!isArray && this.hasChildren()) {
86             // look for '*props'
87            
88             for (var ii =0; ii< this.items.length(); ii++) {
89                 var pl = this.items.nth_data(ii);
90                 if (!pl.props.has_key("*prop")) {
91                     //newitems.add(pl);
92                     continue;
93                 }
94                 
95                 //print(JSON.stringify(pl,null,4));
96                 // we have a prop...
97                 //var prop = pl['*prop'] + '';
98                 //delete pl['*prop'];
99                 var prop = pl.get("*prop");
100                 // name ends in [];
101                 if (! Regex.match_simple("\\[\\]$", prop)) {
102                     // it's a standard prop..
103                     
104                     // munge property..??
105                     oprops.set(prop, pl);
106                     
107                     
108                     //keys.push(prop);
109                     continue;
110                 }
111                 
112                 prop  = prop.substring(0,  -2); //strip []
113                 // it's an array type..
114                 if (!oprops.has_key(prop)) {
115                     var cn = new Node();
116                     oprops.set(prop, cn);
117                     
118                 }
119                 // ignores the fact it might be duplciated...
120                 oprops.get(prop).is_array = true;
121                 oprops.get(prop).items.append(pl);
122               
123                 
124                 
125                 
126             }
127             
128             //obj.items = newitems;
129             //if (!obj.items.length) {
130             //    delete obj.items;
131             //}
132             
133         }
134         if (this.isArray()) {
135             
136             
137             for (var i=0;i< this.items.length();i++) {
138                 var el = this.items.nth_data(i);
139                 
140                 els.append("%d".printf(i) + " : " + el.mungeToString(false, pad,doubleStringProps));
141                 
142             }
143             var spad = pad.substring(0, pad.length-4);
144             return   "{\n" +
145                 pad  + string.join(",\n" + pad , els) + 
146                 "\n" + spad +  "}";
147                
148             
149             
150             
151           
152         } 
153         string left;
154         Regex func_regex ;
155         try {
156             func_regex = new Regex("^\\s+|\\s+$");
157         } catch (Error e) {
158             print("failed to build regex");
159             return "";
160         }
161         var piter = this.props.map_iterator();
162         while (piter.next() ) {
163             var k = piter.get_key();
164             var v = piter.get_value();
165             
166             if (skip.contains(k) ) {
167                 continue;
168             }
169             
170             
171             string leftv = k[0] == '|' ? k.substring(1) : k;
172             // skip builder stuff. prefixed with  '.' .. just like unix fs..
173             if (leftv[0] == '.') { // |. or . -- do not output..
174                 continue;
175             }
176              if (k[0] == '*') {
177                 // ignore '*prop';
178                 continue;
179              }
180                 
181             
182             if (Lang.isKeyword(leftv) || Lang.isBuiltin(leftv)) {
183                 left = "'" + leftv + "'";
184             } else if (Regex.match_simple("[^A-Za-z_]+",leftv)) { // not plain a-z... - quoted.
185                 var val = this.quoteString(leftv);
186                 
187                 left = "'" + val.substring(1, val.length-1).replace("'", "\\'") + "'";
188             } else {
189                 left = leftv;
190             }
191             left += " : ";
192             
193             if (isListener) {
194             // change the lines...
195                             
196                 string str;
197                 try {
198                     str = func_regex.replace(v,v.length, 0, "");
199                 } catch(Error e) {
200                     print("regex failed");
201                     return "";
202                 }
203                 
204                 var lines = str.split("\n");
205                 if (lines.length > 1) {
206                     str = string.join("\n" + pad, lines);
207                 }
208                 
209                 els.append(left  + str);
210                 continue;
211             }
212              
213             // next.. is it a function..
214             if (k[0] == '|') {
215                 // does not hapepnd with arrays.. 
216                 if (v.length < 1) {  //if (typeof(el) == 'string' && !obj[i].length) { //skip empty.
217                     continue;
218                 }
219                 
220                 string str;
221                 try {
222                     str = func_regex.replace(v,v.length, 0, "");
223                 } catch(Error e) {
224                     print("regex failed");
225                     return "";
226                 }
227                 
228                 var lines = str.split("\n");
229                 if (lines.length > 1) {
230                     str =  string.join("\n" + pad, lines);
231                 }
232                 
233                 els.append(left + str);
234                 continue;
235             }
236             // standard..
237             
238             
239             if (Lang.isNumber(v) || Lang.isBoolean(v)) { // boolean or number...?
240                 els.append(left + v );
241                 continue;
242             }
243             
244             // strings..
245             if (doubleStringProps.length() < 1) {
246                 els.append(left + this.quoteString(v));
247                 continue;
248             }
249            
250             if (doubleStringProps.index(k) > -1) {
251                 els.append(left + this.quoteString(v));
252                 continue;
253             }
254              
255             // single quote.. v.substring(1, v.length-1).replace("'", "\\'") + "'";
256             els.append(left + "'" + v.substring(1, v.length-1).replace("'", "\\'") + "'");
257             
258
259            
260            
261            
262         }
263         var iter = oprops.map_iterator();
264         while (iter.next()) {
265             var k = iter.get_key();
266             var vo = iter.get_value();
267             string leftv = k[0] == '|' ? k.substring(1) : k;
268             if (Lang.isKeyword(leftv) || Lang.isBuiltin(leftv)) {
269                 left = "'" + leftv + "'";
270             } else if (Regex.match_simple("[^A-Za-z_]+",leftv)) { // not plain a-z... - quoted.
271                 var val = this.quoteString(leftv);
272                 
273                 left = "'" + val.substring(1, val.length-1).replace("'", "\\'") + "'";
274             } else {
275                 left = leftv;
276             }
277             left += " : ";
278             
279             var right = vo.mungeToString(k == "listeners", pad + "    ",doubleStringProps);
280             
281             //if (!left.length && isArray) print(right);
282             
283             if (right.length > 0){
284                 els.append(left + right);
285             }
286         
287             
288         }
289         if (els.length() < 1) {
290             return "";
291         }
292         // oprops...    
293             
294         var spad = pad.substring(0, pad.length-4);
295         return   "{\n" +
296             pad  + string.join(",\n" + pad , els) + 
297             "\n" + spad +  "}";
298            
299            
300                
301         
302         
303     }
304     static Json.Generator gen = null;
305     
306     public string quoteString(string str)
307     {
308         if (Node.gen == null) {
309             Node.gen = new Json.Generator();
310         }
311         var builder = new Json.Builder();
312         builder.add_string_value(str);
313         Node.gen.set_root (builder.get_root ());
314         return  Node.gen.to_data (null);   
315     }
316
317     void loadFromJson(Json.Object obj) {
318         obj.foreach_member(o , key, value) {
319             if (key == "items") {
320                 var ar = value.get_array();
321                 ar.foreach_element( (are, ix, el) {
322
323                 });
324
325                 return;
326             }
327             if (key == "listeners") {
328
329                 return;
330             }
331             this.props.set(key, value.get_string());
332         }
333         
334
335
336
337     }
338     
339     
340 }