2 * This is baed on the code in the app builder..
8 render = new Pman.Builder.JsRender(
9 Pman.Builder.Tree.toJS()
12 var source = render.toSource();
15 * @cfg {Array} items - the array of items..
16 * @cfg {String} name - eg. Pman.Tab.XXXXyyyyy
18 * @cfg {String} path - needs the full path << we only have the class name..
19 * @cfg {String} region - ?? needed anymore?
20 * @cfg {String} parent
22 * @cfg {String} disable? function call to disable it?
23 * @cfg {String} permname
24 * @cfg {Number} modOrder
27 Pman.Builder.JsRender = function(cfg) {
31 Pman.Builder.JsRender.prototype = {
35 path : '', // the file path..
36 modOrder : '001', /// sequence id that this uses.
39 title : '', // the title on displayed when loading.
40 disable : '', // use a function to that returns false to disable this..
41 permname: '', /// permission name
46 * @type {Object} the properties that have to be double quoted to enable translation
63 * munge JSON tree into Javascript code.
65 * FIXME: + or / prefixes to properties hide it from renderer.
66 * FIXME: '*props' - not supported by this.. ?? - upto rendering code..
67 * FIXME: needs to understand what properties might be translatable (eg. double quotes)
69 * @arg {object} obj the object or array to munge..
70 * @arg {boolean} isListener - is the array being sent a listener..
71 * @arg {string} pad - the padding to indent with.
75 mungeToString: function(obj, isListener, pad)
82 isListener = isListener || false;
84 // am I munging a object or array...
85 if (obj.constructor.toString() === Array.toString()) {
86 for (var i= 0; i < obj.length; i++) {
100 typeof(obj['|xns']) != 'undefined' &&
101 typeof(obj['xtype']) != 'undefined'
103 this.mungeXtype(obj['|xns'] + '.' + obj['xtype'], els);
104 //els.push('xtype: '+ obj['|xns'] + '.' + obj['xtype']);
105 skip.push('|xns','xtype');
109 if (!isArray && obj.items && obj.items.length) {
112 obj.items.forEach(function(pl) {
113 if (typeof(pl['*prop']) == 'undefined') {
118 //print(JSON.stringify(pl,null,4));
120 var prop = pl['*prop'] + '';
122 if (!prop.match(/\[\]$/)) {
123 // it's a standard prop..
125 // munge property..??
132 prop = prop.substring(0, prop.length -2); //strip []
133 // it's an array type..
134 obj[prop] = obj[prop] || [];
136 // print("ADDNG PROP:" + prop + ' ' + keys.indexOf(prop) );
137 if (keys.indexOf(prop) < 0) {
144 obj.items = newitems;
145 if (!obj.items.length) {
153 //if (isArray) { print(JSON.stringify(keys, null,4)); }
154 // keys is just the real keys of the object.
159 keys.forEach(function(i) {
161 if (typeof(obj[i]) == 'undefined') { // empty or removed.
165 if (!isArray && skip.indexOf(i) > -1) { // things we do not write..
169 // set the key to be quoted with singel quotes..
170 var leftv = i[0] == '|' ? i.substring(1) : i;
171 if (Lang.isKeyword(leftv) || Lang.isBuiltin(leftv)) {
172 left = "'" + leftv + "'";
173 } else if (leftv.match(/[^A-Z_]+/i)) { // not plain a-z... - quoted.
174 var val = JSON.stringify(leftv);
175 left = "'" + val.substring(1, val.length-1).replace(/'/g, "\\'") + "'";
185 // change the lines...
186 var str= ('' + obj[i]).replace(/^\s+|\s+$/g,""); // remove bar.
187 var lines = str.split("\n");
188 if (lines.length > 1) {
189 str = lines.join("\n" + pad);
192 els.push(left + str);
198 //var left = isArray ? '' : (JSON.stringify(i) + " : " )
201 // does not hapepnd with arrays..
202 if (typeof(el) == 'string' && !obj[i].length) { //skip empty.
205 // this needs to go...
206 //if (typeof(el) == 'string' && obj[i].match(new RegExp("Gtk.main" + "_quit"))) { // we can not handle this very well..
210 var str= ('' + obj[i]).replace(/^\s+|\s+$/g,"");;
211 var lines = str.split("\n");
212 if (lines.length > 1) {
213 str = lines.join("\n" + pad);
216 els.push(left + str);
223 if (typeof(el) == 'object') {
225 // we can skip empty items lists and empty listeners..
226 //if (!isArray && i == 'items' && !el.length) {
230 var right = _this.mungeToString(el, i == 'listeners', pad + ' ');
232 //if (!left.length && isArray) print(right);
234 if ((typeof(right) != 'undefined') && right.length){
235 els.push(left + right);
241 if (typeof(obj[i]) != 'string') {
242 els.push(left + JSON.stringify(obj[i]));
246 if (!_this.doubleStringProps) {
247 els.push(left + JSON.stringify(obj[i]));
250 if (_this.doubleStringProps.indexOf(i) > -1) {
251 els.push(left + JSON.stringify(obj[i]));
255 els.push(left + "'" + obj[i].replace(/'/g, "\\'") + "'");
260 if (!isArray && !els.length) {
264 var spad = pad.substring(0, pad.length-4);
265 return (isArray ? '[' : '{') + "\n" +
266 pad + els.join(",\n" + pad ) +
267 "\n" + spad + (isArray ? ']' : '}');
274 setNSID : function(id)
277 this.items[0]['|module'] = id;
283 getType: function() {
289 * old code had broken xtypes and used arrays differently,
290 * this code should try and clean it up..
294 fixItems : function(node, fixthis)
298 var fn = this.guessName(node);
299 //print("guessname got " + fn);
301 var bits = fn.split('.');
302 node.xtype = bits.pop();
303 node['|xns'] = bits.join('.');
310 if (!node.items || !node.items.length) {
316 node.items.forEach(function(i) {
320 _this.fixItems(i, true);
321 if (i.xtype == 'Array') {
329 if (!aitems.length) {
333 aitems.forEach(function(i) {
335 if (!i.items || !i.items.length) {
338 var prop = i['*prop'] + '[]';
340 i.items.forEach(function(c) {
359 * convert xtype for munged output..
362 mungeXtype : function(xtype, els)
364 var bits = xtype.split('.');
365 // assume it has lenght!
367 els.push("xtype: '"+ bits.pop()+"'");
368 els.push('xns: '+ bits.join('.'));
372 * This needs to use some options on the project
373 * to determine how the file is output..
375 * At present we are hard coding it..
381 // dump the file tree back out to a string.
383 // we have 2 types = dialogs and components
385 var top = this.guessName(this.items[0]);
389 if (top.match(/Dialog/)) {
390 return this.toSourceDialog();
392 return this.toSourceLayout();
395 eventually support 'classes??'
396 return this.toSourceStdClass();
401 outputHeader : function()
404 "//<script type=\"text/javascript\">",
406 "// Auto generated file - created by app.Builder.js- do not edit directly (at present!)",
412 // a standard dialog module.
413 // fixme - this could be alot neater..
414 toSourceDialog : function()
416 var items = JSON.parse(JSON.stringify(this.items[0]));
417 var o = this.mungeToString(items, false, ' ');
425 " show : function(data, cb)",
427 " if (!this.dialog) {",
431 " this.callback = cb;",
432 " this.data = data;",
433 " this.dialog.show(this.data._el);",
435 " this.form.reset();",
436 " this.form.setValues(data);",
437 " this.form.fireEvent('actioncomplete', this.form, { type: 'setdata', data: data });",
442 " create : function()",
444 " var _this = this;",
445 " this.dialog = Roo.factory(" + o + ");",
457 * try to remove Pman.Tab.XXXXXYYYY
458 * where XXXX= the project name..
461 pathToPart : function()
465 var modname = this.name.split('.').pop();
467 var ret = modname.match(/([A-Z][a-z]+)/g);
468 var mm = ret.shift();
469 return [ mm, ret.join('')];
471 //return [ modname , npart];
479 toSourceLayout : function()
481 var items = JSON.parse(JSON.stringify(this.items[0]));
482 var o = this.mungeToString(items, false, ' ');
484 var modkey = this.modOrder + '-' + this.name.replace(/[^A-Z.]+/ig, '-');
487 if (this.name.match(/^Pman/)) {
490 // old BC way we did things..
495 "// register the module first",
496 "Pman.on('beforeload', function()",
499 " part : "+ JSON.stringify(this.pathToPart()) + ",", /// critical used by builder to associate modules/parts/persm
500 " modKey : '" +modkey+"',",
501 " module : " + this.name + ",",
502 " region : '" + this.region +"',",
503 " parent : " + (this.parent || 'false') + ",",
504 " name : " + JSON.stringify(this.title || "unnamed module") + ",",
505 " disabled : " + (this.disabled || 'false') +", ",
506 " permname: '" + (this.permname|| '') +"' ",
511 this.name + " = new Roo.util.Observable({",
514 " disabled : false,",
515 " parentLayout: false,",
517 " add : function(parentLayout, region)",
520 " var _this = this;", // standard avaialbe..
521 " this.parentLayout = parentLayout;",
523 " this.panel = parentLayout.addxtype(" + o + ");",
524 " this.layout = this.panel.layout;",
538 this.name + " = new Roo.XComponent({",
539 " order : '" +modkey+"',",
540 " region : '" + this.region +"',",
541 " parent : "+ (this.parent ? "'" + this.parent + "'" : 'false') + ",",
542 " name : " + JSON.stringify(this.title || "unnamed module") + ",",
543 " disabled : " + (this.disabled || 'false') +", ",
544 " tree : function()",
546 " var _this = this;", // bc
547 " var MODULE = this;", /// this looks like a better name.
548 " return " + o + ';',
557 guessName : function(ar) // turns the object into full name.
559 // eg. xns: Roo, xtype: XXX -> Roo.xxx
564 ret.push(typeof( ar['|xns'] ) == 'undefined' ? 'Roo' : ar['|xns'] );
568 if (typeof( ar['xtype'] ) == 'undefined' || !ar['xtype'].length) {
571 var xtype = ar['xtype'] + '';
572 if (xtype[0] == '*') { // prefixes????
573 xtype = xtype.substring(1);
575 if (xtype.match(/^Roo/)) {
576 // already starts with roo...
580 return ret.join('.');