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 GLib.List<Node> items; // child items..
9 Gee.HashMap<string,string> props; // the properties..
10 Gee.HashMap<string,string> listeners; // the listeners..
18 this.items = new GLib.List<Node>();
19 this.props = new Gee.HashMap<string,string>();
20 this.is_array = false;
31 public bool hasChildren()
33 return this.items.length() > 0;
35 public bool hasXnsType()
37 if (this.props.get("|xns") != null && this.props.get("xtype") != null) {
43 // wrapper around get props that returns empty string if not found.
44 public string get(string key)
46 var k = this.props.get(key);
54 /* creates javascript based on the rules */
58 public string mungeToString (bool isListener, string pad, GLib.List<string> doubleStringProps)
62 pad = pad.length < 1 ? " " : pad;
67 //isListener = isListener || false;
69 //var keys = this.keys();
70 var isArray = this.isArray();
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); ??????
83 //var newitems = new Gee.ArrayList<JsRender.Node>();
84 var oprops = new Gee.HashMap<string,Node>();
86 if (!isArray && this.hasChildren()) {
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")) {
96 //print(JSON.stringify(pl,null,4));
98 //var prop = pl['*prop'] + '';
100 var prop = pl.get("*prop");
102 if (! Regex.match_simple("\\[\\]$", prop)) {
103 // it's a standard prop..
105 // munge property..??
106 oprops.set(prop, pl);
113 prop = prop.substring(0, -2); //strip []
114 // it's an array type..
115 if (!oprops.has_key(prop)) {
117 oprops.set(prop, cn);
120 // ignores the fact it might be duplciated...
121 oprops.get(prop).is_array = true;
122 oprops.get(prop).items.append(pl);
129 //obj.items = newitems;
130 //if (!obj.items.length) {
135 if (this.isArray()) {
138 for (var i=0;i< this.items.length();i++) {
139 var el = this.items.nth_data(i);
141 els.append("%d".printf(i) + " : " + el.mungeToString(false, pad,doubleStringProps));
144 var spad = pad.substring(0, pad.length-4);
146 pad + string.join(",\n" + pad , els) +
157 func_regex = new Regex("^\\s+|\\s+$");
159 print("failed to build regex");
162 var piter = this.props.map_iterator();
163 while (piter.next() ) {
164 var k = piter.get_key();
165 var v = piter.get_value();
167 if (skip.contains(k) ) {
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..
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);
188 left = "'" + val.substring(1, val.length-1).replace("'", "\\'") + "'";
195 // change the lines...
199 str = func_regex.replace(v,v.length, 0, "");
201 print("regex failed");
205 var lines = str.split("\n");
206 if (lines.length > 1) {
207 str = string.join("\n" + pad, lines);
210 els.append(left + str);
214 // next.. is it a function..
216 // does not hapepnd with arrays..
217 if (v.length < 1) { //if (typeof(el) == 'string' && !obj[i].length) { //skip empty.
223 str = func_regex.replace(v,v.length, 0, "");
225 print("regex failed");
229 var lines = str.split("\n");
230 if (lines.length > 1) {
231 str = string.join("\n" + pad, lines);
234 els.append(left + str);
240 if (Lang.isNumber(v) || Lang.isBoolean(v)) { // boolean or number...?
241 els.append(left + v );
246 if (doubleStringProps.length() < 1) {
247 els.append(left + this.quoteString(v));
251 if (doubleStringProps.index(k) > -1) {
252 els.append(left + this.quoteString(v));
256 // single quote.. v.substring(1, v.length-1).replace("'", "\\'") + "'";
257 els.append(left + "'" + v.substring(1, v.length-1).replace("'", "\\'") + "'");
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);
274 left = "'" + val.substring(1, val.length-1).replace("'", "\\'") + "'";
280 var right = vo.mungeToString(k == "listeners", pad + " ",doubleStringProps);
282 //if (!left.length && isArray) print(right);
284 if (right.length > 0){
285 els.append(left + right);
290 if (els.length() < 1) {
295 var spad = pad.substring(0, pad.length-4);
297 pad + string.join(",\n" + pad , els) +
305 static Json.Generator gen = null;
307 public string quoteString(string str)
309 if (Node.gen == null) {
310 Node.gen = new Json.Generator();
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);
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);
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());
337 this.props.set(key, value.get_string());