tools/build_gtk_tree.js
[app.Builder.js] / JsRender / Base.js
1 //<Script type="text/javascript">
2
3
4 var XObject     = imports.XObject.XObject;
5
6
7 var Lang        = imports.JsRender.Lang.Lang;
8
9
10 var JsParser    = imports.JsParser.JsParser;
11 var TokenReader = imports.JSDOC.TokenReader.TokenReader;
12 var TextStream  = imports.JSDOC.TextStream.TextStream;
13
14 var File = imports.File.File;
15 // File Provider..
16
17 Base = XObject.define(
18     
19     function(cfg) {
20         
21         XObject.extend(this, cfg);
22         
23     },
24     Object,
25     {
26         /**
27          * @cfg {Array} doubleStringProps list of properties that can be double quoted.
28          */
29         doubleStringProps : false,
30         
31         id : false,
32         name : false,   // is the JS name of the file.
33         path : '',      // is the full path to the file.
34         parent : false, // JS parent.
35         
36         title : false,  // a title.. ?? nickname.. ??? - 
37         project: false, // name...
38         //Project : false, // link to container project!
39         
40         items : false, // the tree of nodes.
41         
42         cn : false, // array used by project tree.
43         
44         
45         save : function()
46         {
47             var write = { }; 
48             var _this = this;
49             var write = this.toJsonArray()
50             print("WRITE: " + this.path);// + "\n" + JSON.stringify(write));
51             File.write(this.path, JSON.stringify(write, null, 4));
52         },
53         /**
54          *
55          * load from a javascript file.. rather than bjs..
56          * 
57          *
58          */
59          
60         _loadItems : function(cb)
61         {
62             // already loaded..
63             if (this.items !== false) {
64                 return false;
65             }
66               
67             
68             
69             var tr = new  TokenReader(  { 
70                 keepDocs :true, 
71                 keepWhite : true,  
72                 keepComments : true, 
73                 sepIdents : false,
74                 collapseWhite : false,
75                 filename : args[0],
76                 ignoreBadGrammer: true
77             });
78             
79             var str = File.read(this.path);
80             var toks = tr.tokenize(new TextStream(str));  
81             var rf = new JsParser(toks);
82             rf.parse();
83             var cfg = rf.cfg;
84             
85             this.modOrder = cfg.modOrder || '001';
86             this.name = cfg.name.replace(/\.bjs/, ''); // BC!
87             this.parent =  cfg.parent;
88             this.permname =  cfg.permname || '';
89             this.title =  cfg.title || cfg.name;;
90             this.items = cfg.items || []; 
91             //???
92             //this.fixItems(_this, false);
93             cb();
94             return true;    
95                 
96         },
97         
98         /**
99          * accepts:
100          * { success : , failure : , scope : }
101          * 
102          * 
103          * 
104          */
105          
106         getTree : function( o ) {
107             print("File.getTree tree called on base object?!?!");
108         },
109         toJsonArray : function()
110         {
111             var ret = { }; 
112             var _this = this;
113             ['id', 'name', 'parent', 'title', 'path', 'items' , 'permname', 'modOrder' ].forEach( function(k) {
114                 ret[k] = typeof(_this[k]) == 'undefined' ? '' : _this[k];
115             });
116             return ret;
117         },
118         getTitle : function()
119         {
120             if (this.title) {
121                 return this.title;
122             }
123             return this.path.split('/').pop();
124             
125         },
126         getTitleTip: function()
127         {
128             if (this.title) {
129                 return '<b>' + this.title + '</b> ' + this.path;
130             }
131             return this.path;
132         },
133         sortCn: function()
134         {
135             this.cn.sort(function(a,b) {
136                 return a.path > b.path;// ? 1 : -1;
137             });
138         },
139         // should be in palete provider really..
140         
141         guessName : function(ar) // turns the object into full name.
142         {
143              // eg. xns: Roo, xtype: XXX -> Roo.xxx
144             if (typeof( ar['|xns'] ) == 'undefined' || typeof( ar['xtype'] ) == 'undefined') {
145                 return '';
146                }
147              
148             return ar['|xns'] +'.' + ar['xtype'];
149                             
150                                  
151         },
152         
153         
154         
155         copyTo: function(path, cb)
156         {
157             var _this = this;
158             this.loadItems(function() {
159                 
160                 _this.path = path;
161                 cb();
162             });
163             
164         },
165         
166         /**
167          * 
168          * munge JSON tree into Javascript code.
169          * 
170          * FIXME: + or / prefixes to properties hide it from renderer.
171          * FIXME: '*props' - not supported by this.. ?? - upto rendering code..
172          * FIXME: needs to understand what properties might be translatable (eg. double quotes)
173          * 
174          * @arg {object} obj the object or array to munge..
175          * @arg {boolean} isListener - is the array being sent a listener..
176          * @arg {string} pad - the padding to indent with. 
177          */
178         
179         
180         mungeToString:  function(obj, isListener, pad)
181         {
182             
183              
184             pad = pad || '    ';
185             var keys = [];
186             var isArray = false;
187             isListener = isListener || false;
188              
189             // am I munging a object or array...
190             if (obj.constructor.toString() === Array.toString()) {
191                 for (var i= 0; i < obj.length; i++) {
192                     keys.push(i);
193                 }
194                 isArray = true;
195             } else {
196                 for (var i in obj) {
197                     keys.push(i);
198                 }
199             }
200             
201             
202             var els = []; 
203             var skip = [];
204             if (!isArray && 
205                     typeof(obj['|xns']) != 'undefined' &&
206                     typeof(obj['xtype']) != 'undefined'
207                 ) {
208                     this.mungeXtype(obj['|xns'] + '.' + obj['xtype'], els);
209                     //els.push('xtype: '+ obj['|xns'] + '.' + obj['xtype']);
210                     skip.push('|xns','xtype');
211                 }
212             
213             
214             if (!isArray && obj.items && obj.items.length) {
215                 // look for props..
216                 var newitems = [];
217                 for (var ii =0; ii< obj.items.length; ii++) {
218                     var pl = obj.items[ii];
219                     
220  
221                     if (typeof(pl['*prop']) == 'undefined') {
222                         newitems.push(pl);
223                         continue;
224                     }
225                     
226                     //print(JSON.stringify(pl,null,4));
227                     // we have a prop...
228                     var prop = pl['*prop'] + '';
229                     delete pl['*prop'];
230                     if (!prop.match(/\[\]$/)) {
231                         // it's a standard prop..
232                         
233                         // munge property..??
234                         
235                         obj[prop] = pl;
236                         
237                         keys.push(prop);
238                         continue;
239                     }
240                     prop  = prop.substring(0, prop.length -2); //strip []
241                     // it's an array type..
242                     obj[prop] = obj[prop]  || [];
243                     obj[prop].push(pl);
244                   //  print("ADDNG PROP:" + prop + ' ' + keys.indexOf(prop) );
245                     if (keys.indexOf(prop) < 0) {
246                         keys.push(prop);
247                     }
248                     
249                     
250                     
251                 }
252                 
253                 obj.items = newitems;
254                 if (!obj.items.length) {
255                     delete obj.items;
256                 }
257                 
258             }
259             
260              
261             
262             //if (isArray) { print(JSON.stringify(keys, null,4)); }
263             // keys is just the real keys of the object.
264             var _this = this;
265             
266             var left =  '';
267             
268             for (var ii =0; ii< keys.length; ii++) {
269             
270                 var i = keys[ii];
271               
272                 if (typeof(obj[i]) == 'undefined') { // empty or removed.
273                     continue;
274                 }
275                 var el = obj[i];
276                 if (!isArray && skip.indexOf(i) > -1) { // things we do not write..
277                     continue;
278                 }
279                 if (!isArray) {
280                     // set the key to be quoted with singel quotes..
281                     var leftv = i[0] == '|' ? i.substring(1) : i;
282                     // skip builder stuff. prefixed with  '.' .. just like unix fs..
283                     if (leftv[0] == '.') {
284                         continue;
285                     }
286                     if (Lang.isKeyword(leftv) || Lang.isBuiltin(leftv)) {
287                         left = "'" + leftv + "'";
288                     } else if (leftv.match(/[^A-Z_]+/i)) { // not plain a-z... - quoted.
289                         var val = JSON.stringify(leftv);
290                         left = "'" + val.substring(1, val.length-1).replace(/'/g, "\\'") + "'";
291                     } else {
292                         left = '' + leftv;
293                     }
294                     left += ' : ';
295                     
296                 }
297                 
298                 
299                 if (isListener) {
300                     // change the lines...
301                     var str= ('' + obj[i]).replace(/^\s+|\s+$/g,""); // remove bar.
302                     var lines = str.split("\n");
303                     if (lines.length > 1) {
304                         str = lines.join("\n" + pad);
305                     }
306                     
307                     els.push(left  + str);
308                     continue;
309                 }
310                  
311                 
312                 
313                 //var left = isArray ? '' : (JSON.stringify(i) + " : " )
314                 
315                 if (i[0] == '|') {
316                     // does not hapepnd with arrays..
317                     if (typeof(el) == 'string' && !obj[i].length) { //skip empty.
318                         continue;
319                     }
320                     // this needs to go...
321                     //if (typeof(el) == 'string'  && obj[i].match(new RegExp("Gtk.main" + "_quit"))) { // we can not handle this very well..
322                     //    continue;;
323                     //}
324                     
325                     var str= ('' + obj[i]).replace(/^\s+|\s+$/g,"");;
326                     var lines = str.split("\n");
327                     if (lines.length > 1) {
328                         str = lines.join("\n" + pad);
329                     }
330                     
331                     els.push(left + str);
332                     continue;
333                 }
334                 
335                 
336                 
337                 
338                 if (typeof(el) == 'object') {
339                     
340                     // we can skip empty items lists and empty listeners..
341                     //if (!isArray && i == 'items' && !el.length) {
342                     //    return; 
343                     //}
344                    // 
345                     var right = _this.mungeToString(el, i == 'listeners', pad + '    ');
346                     
347                     //if (!left.length && isArray) print(right);
348                     
349                     if ((typeof(right) != 'undefined') && right.length){
350                         els.push(left + right);
351                     }
352                 
353                     continue;
354                 }
355                 // standard. .
356                 if (typeof(obj[i]) != 'string') {
357                     els.push(left + JSON.stringify(obj[i]));
358                     continue;
359                 }
360                 // strings..
361                 if (!_this.doubleStringProps) {
362                     els.push(left + JSON.stringify(obj[i]));
363                     continue;
364                 }
365                 if (_this.doubleStringProps.indexOf(i) > -1) {
366                     els.push(left + JSON.stringify(obj[i]));
367                     continue;
368                 }
369                 // single quote..
370                 els.push(left + "'" + obj[i].replace(/'/g, "\\'") + "'");
371                 
372
373             }
374             
375             if (!isArray && !els.length) {
376                 return '';
377             }
378             //output the thing.
379             var spad = pad.substring(0, pad.length-4);
380             return (isArray ? '[' : '{') + "\n" +
381                 pad  + els.join(",\n" + pad ) + 
382                 "\n" + spad + (isArray ? ']' : '}');
383                
384             
385             
386         } 
387         
388          
389         
390     }
391     
392      
393     
394 );
395
396
397
398
399
400