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