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
5 public class JsRender.Node {
7 public GLib.List<Node> items; // child items..
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 ""
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;
33 public bool hasChildren()
35 return this.items.length() > 0;
37 public bool hasXnsType()
39 if (this.props.get("|xns") != null && this.props.get("xtype") != null) {
47 if (!this.hasXnsType ()) {
50 return this.props.get("|xns") + "." + this.props.get("xtype");
54 // wrapper around get props that returns empty string if not found.
55 public string get(string key)
57 var k = this.props.get(key);
62 k = this.props.get("|" + key);
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) {
80 return this.items.nth_data(i);
87 string gLibStringListJoin( string sep, GLib.List<string> ar)
90 for (var i = 0; i < ar.length(); i++) {
91 ret += i>0 ? sep : "";
92 ret += ar.nth_data(i);
98 public string mungeToString (bool isListener, string pad, GLib.List<string> doubleStringProps)
102 pad = pad.length < 1 ? " " : pad;
107 //isListener = isListener || false;
109 //var keys = this.keys();
110 var isArray = this.isArray();
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); ??????
123 //var newitems = new Gee.ArrayList<JsRender.Node>();
124 var oprops = new Gee.HashMap<string,Node>();
126 if (!isArray && this.hasChildren()) {
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")) {
136 //print(JSON.stringify(pl,null,4));
138 //var prop = pl['*prop'] + '';
139 //delete pl['*prop'];
140 var prop = pl.get("*prop");
142 if (! Regex.match_simple("\\[\\]$", prop)) {
143 // it's a standard prop..
145 // munge property..??
146 oprops.set(prop, pl);
153 prop = prop.substring(0, -2); //strip []
154 // it's an array type..
155 if (!oprops.has_key(prop)) {
157 oprops.set(prop, cn);
160 // ignores the fact it might be duplciated...
161 oprops.get(prop).is_array = true;
162 oprops.get(prop).items.append(pl);
169 //obj.items = newitems;
170 //if (!obj.items.length) {
175 if (this.isArray()) {
178 for (var i=0;i< this.items.length();i++) {
179 var el = this.items.nth_data(i);
181 els.append("%d".printf(i) + " : " + el.mungeToString(false, pad,doubleStringProps));
184 var spad = pad.substring(0, pad.length-4);
186 pad + this.gLibStringListJoin(",\n" + pad , els) +
197 func_regex = new Regex("^\\s+|\\s+$");
199 print("failed to build regex");
202 var piter = this.props.map_iterator();
203 while (piter.next() ) {
204 var k = piter.get_key();
205 var v = piter.get_value();
207 if (skip.contains(k) ) {
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..
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);
228 left = "'" + val.substring(1, val.length-1).replace("'", "\\'") + "'";
235 // change the lines...
239 str = func_regex.replace(v,v.length, 0, "");
241 print("regex failed");
246 var lines = str.split("\n");
247 if (lines.length > 0) {
248 str = string.joinv("\n" + pad, lines);
251 els.append(left + str);
255 // next.. is it a function..
257 // does not hapepnd with arrays..
258 if (v.length < 1) { //if (typeof(el) == 'string' && !obj[i].length) { //skip empty.
265 str = func_regex.replace(v,v.length, 0, "");
267 print("regex failed");
273 var lines = str.split("\n");
275 if (lines.length > 0) {
276 str = string.joinv("\n" + pad, lines);
278 //print("==> " + str + "\n");
279 els.append(left + str);
285 if (Lang.isNumber(v) || Lang.isBoolean(v)) { // boolean or number...?
286 els.append(left + v );
291 if (doubleStringProps.length() < 1) {
292 els.append(left + this.quoteString(v));
296 if (doubleStringProps.index(k) > -1) {
297 els.append(left + this.quoteString(v));
301 // single quote.. v.substring(1, v.length-1).replace("'", "\\'") + "'";
302 els.append(left + "'" + v.substring(1, v.length-1).replace("'", "\\'") + "'");
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);
319 left = "'" + val.substring(1, val.length-1).replace("'", "\\'") + "'";
325 var right = vo.mungeToString(k == "listeners", pad + " ",doubleStringProps);
327 //if (!left.length && isArray) print(right);
329 if (right.length > 0){
330 els.append(left + right);
337 if (this.listeners.size > 0) {
338 // munge the listeners.
339 //print("ADDING listeners?");
341 var liter = this.listeners.map_iterator();
343 var itms = "listeners : {\n";
345 while (liter.next()) {
347 itms += i >0 ? ",\n" : "";
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);
357 itms += pad + " " + liter.get_key() + " : " + str;
363 itms += "\n" + pad + "}";
364 //print ( "ADD " + itms);
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++) {
377 this.items.nth_data(i).mungeToString(false, pad + " ", doubleStringProps) + "\n";
385 // finally output listeners...
393 if (els.length() < 1) {
398 var spad = pad.substring(0, pad.length-4);
400 pad + gLibStringListJoin(",\n" + pad , els) +
408 static Json.Generator gen = null;
410 public string quoteString(string str)
412 if (Node.gen == null) {
413 Node.gen = new Json.Generator();
415 var n = new Json.Node(Json.NodeType.VALUE);
418 Node.gen.set_root (n);
419 return Node.gen.to_data (null);
422 public void loadFromJson(Json.Object obj) {
423 obj.foreach_member((o , key, value) => {
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);
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());
442 var v = value.get_value();
443 var sv = Value (typeof (string));
446 this.props.set(key, (string)sv);
453 public Json.Object toJsonObject()
455 var ret = new Json.Object();
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());
466 var iter = this.props.map_iterator();
467 while (iter.next()) {
468 this.jsonObjectsetMember(ret, iter.get_key(), iter.get_value());
471 var ar = new Json.Array();
472 ret.set_array_member("items", ar);
475 for(var i =0;i < this.items.length();i++) {
476 ar.add_object_element(this.items.nth_data(i).toJsonObject());
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);
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));
497 //print( "ADD " + key + "=" + val + " as a int?\n") ;
498 o.set_int_member(key,long.parse(val));
501 ///print( "ADD " + key + "=" + val + " as a string?\n");
502 o.set_string_member(key,val);