Builder/Provider/File/Base.js
[app.Builder.js] / Builder / Provider / File / Base.js
index 33b70e1..c37d992 100644 (file)
@@ -5,17 +5,22 @@ XObject = imports.XObject.XObject;
 
 Lang = imports.Builder.Provider.File.Lang.Lang;
 
-
+File = imports.File.File;
 // File Provider..
 
 Base = XObject.define(
     
     function(cfg) {
-    
+        
         XObject.extend(this, cfg);
+        
     },
     Object,
     {
+        /**
+         * @cfg {Array} doubleStringProps list of properties that can be double quoted.
+         */
+        doubleStringProps : false,
         
         id : false,
         name : false,   // is the JS name of the file.
@@ -24,7 +29,7 @@ Base = XObject.define(
         
         title : false,  // a title.. ?? nickname.. ??? - 
         project: false, // name...
-        Project : false, // link to container project!
+        //Project : false, // link to container project!
         
         items : false, // the tree of nodes.
         
@@ -34,12 +39,11 @@ Base = XObject.define(
         save : function()
         {
             var write = { }; 
-            var data = ['name', 'parent', 'title', 'items'].forEach( function(k) {
-                write[k] = _this[k];
-            });
-            print("WRITE: " + this.path + "\n" + JSON.stringify(write));
-            //File.write(this.path, JSON.stringify(write));
-        }
+            var _this = this;
+            var write = this.toJsonArray()
+            print("WRITE: " + this.path);// + "\n" + JSON.stringify(write));
+            File.write(this.path, JSON.stringify(write, null, 4));
+        },
         
         /**
          * accepts:
@@ -56,8 +60,8 @@ Base = XObject.define(
         {
             var ret = { }; 
             var _this = this;
-            ['id', 'name', 'parent', 'title', 'path'].forEach( function(k) {
-                ret[k] = _this[k];
+            ['id', 'name', 'parent', 'title', 'path', 'items' , 'permname', 'modOrder' ].forEach( function(k) {
+                ret[k] = typeof(_this[k]) == 'undefined' ? '' : _this[k];
             });
             return ret;
         },
@@ -82,7 +86,19 @@ Base = XObject.define(
                 return a.path > b.path;// ? 1 : -1;
             });
         },
+        // should be in palete provider really..
         
+        guessName : function(ar) // turns the object into full name.
+        {
+             // eg. xns: Roo, xtype: XXX -> Roo.xxx
+            if (typeof( ar['|xns'] ) == 'undefined' || typeof( ar['xtype'] ) == 'undefined') {
+                return '';
+               }
+             
+            return ar['|xns'] +'.' + ar['xtype'];
+                            
+                                 
+        },
         
         /*
         Roo specific?
@@ -152,251 +168,210 @@ Base = XObject.define(
             
         },
         
-        
-        
-        
         /**
-         * munges a prop object, removing all the special stuff..
-         * putting props back where they should go...
+         * 
+         * munge JSON tree into Javascript code.
+         * 
+         * FIXME: + or / prefixes to properties hide it from renderer.
+         * FIXME: '*props' - not supported by this.. ?? - upto rendering code..
+         * FIXME: needs to understand what properties might be translatable (eg. double quotes)
+         * 
+         * @arg {object} obj the object or array to munge..
+         * @arg {boolean} isListener - is the array being sent a listener..
+         * @arg {string} pad - the padding to indent with. 
          */
         
-        mungePropObj : function(o)
+        
+        mungeToString:  function(obj, isListener, pad)
         {
-            
-           // console.log('mungePropObj: enter');
-            var ret = {};
-            // standard props do not do anyting.
-            for (var i in o){
-                if (['items', '*prop'].indexOf(i) > -1) {
-                    continue;
+            pad = pad || '    ';
+            var keys = [];
+            var isArray = false;
+            isListener = isListener || false;
+             
+            // am I munging a object or array...
+            if (obj.constructor.toString() === Array.toString()) {
+                for (var i= 0; i < obj.length; i++) {
+                    keys.push(i);
                 }
-                
-                ret[i] = o[i];
-            }
-            ret.items = [];
-            o.items = o.items || [];
-            var _this = this;
-            o.items.forEach( function(e) {
-                if (typeof(e) == 'undefined') {
-                    return;
+                isArray = true;
+            } else {
+                for (var i in obj) {
+                    keys.push(i);
                 }
-                
-                if (typeof(e) != 'object') {
-                    // should not really hapen?!!?
-                    ret.items.push(e); // could be 
-                    return;
+            }
+            
+            
+            var els = []; 
+            var skip = [];
+            if (!isArray && 
+                    typeof(obj['|xns']) != 'undefined' &&
+                    typeof(obj['xtype']) != 'undefined'
+                ) {
+                    this.mungeXtype(obj['|xns'] + '.' + obj['xtype'], els);
+                    //els.push('xtype: '+ obj['|xns'] + '.' + obj['xtype']);
+                    skip.push('|xns','xtype');
                 }
-                if (typeof(e['*prop']) != 'undefined') {
-                    var pn = e['*prop'];
-                    var val = _this.mungePropObj(e);
-                    
-                    if (e['xtype'].match(/^Array/)) {
-                        ret[pn] = val.items;
+            
+            
+            if (!isArray && obj.items && obj.items.length) {
+                // look for props..
+                var newitems = [];
+                obj.items.forEach(function(pl) {
+                    if (typeof(pl['*prop']) == 'undefined') {
+                        newitems.push(pl);
                         return;
                     }
+                    // we have a prop...
+                    var prop = pl['*prop'] + '';
+                    delete pl['*prop'];
+                    if (!prop.match(/\[\]$/)) {
+                        // it's a standard prop..
+                        obj[prop] = pl;
+                        keys.push(prop);
+                        return;
+                    }
+                    prop  = prop.substring(0, prop.length -2); //strip []
+                    // it's an array type..
+                    obj[prop] = obj[prop]  || [];
+                    obj[prop].push(pl);
+                    print("ADDNG PROP:" + prop + ' ' + keys.indexOf(prop) );
+                    if (keys.indexOf(prop) < 0) {
+                        keys.push(prop);
+                    }
                     
-                    ret[pn] = val;
-                    return;
+                    
+                    
+                });
+                obj.items = newitems;
+                if (!obj.items.length) {
+                    delete obj.items;
                 }
-                // handle fake arrays...
-                var val = _this.mungePropObj(e);
                 
-                ret.items.push(val); // again should not really happen...
-                     
-                
-            });
-            //console.log('mungePropObj: leave');
-            // do we munge '*' xtypes?
-            return ret;
-            
-        },
-        objectKeys : function(o) {
-            var ret = [];
-            for (var k in o) {
-                ret.push(k)
             }
-            return ret;
-        },
-        
-        objectToJsString : function (o, ind) 
-        {
-            ind = ind || 0;
             
             
-            var ret = '';
-            var ix = new Array(ind+1).join("    ");
-            var ix1 = new Array(ind).join("    ");
-            for (var k in o) {
-                var v = o[k];
-                if (k[0] == '+') { // + means  hide from renderer.. we do not save this.
-                    continue;
+            
+            
+            
+            var _this = this;
+            
+            var left =  '';
+            
+            keys.forEach(function(i) {
+              
+                if (typeof(obj[i]) == 'undefined') { // empty or removed.
+                    return;
                 }
-                if (k[0] == '/') { //  means  hide from renderer.. we prefix the col with it..
-                    continue;
+                var el = obj[i];
+                if (!isArray && skip.indexOf(i) > -1) { // things we do not write..
+                    return;
                 }
-            
-                
-                if (typeof(v) == 'object') {
+                if (!isArray) {
+                    // set the key to be quoted with singel quotes..
+                    var leftv = i[0] == '|' ? i.substring(1) : i;
+                    if (Lang.isKeyword(leftv) || Lang.isBuiltin(leftv)) {
+                        left = "'" + leftv + "'";
+                    } else if (leftv.match(/[^A-Z_]+/i)) { // not plain a-z... - quoted.
+                        var val = JSON.stringify(leftv);
+                        left = "'" + val.substring(1, val.length-1).replace(/'/g, "\\'") + "'";
+                    } else {
+                        left = '' + leftv;
+                    }
+                    left += ' : ';
                     
-                    if ((v.constructor != Array) && !this.objectKeys(v).length) {
-                        continue;
+                }
+                if (isListener) {
+                    // change the lines...
+                    var str= ('' + obj[i]).replace(/^\s+|\s+$/g,"");
+                    var lines = str.split("\n");
+                    if (lines.length > 1) {
+                        str = lines.join("\n" + pad);
                     }
-                    if ((v.constructor == Array) && !v.length && k == 'items') {
-                        continue;
-                    }   
+                    els.push(left  + str);
+                    return;
                 }
-                ret += ret.length ? ",\n" : '';
+                 
                 
-                var kk = k[0] == '|' ? k.substring(1) : k;
-                if (typeof(o['//' + kk]) != 'undefined') {
-                    ret += ix + o['//' + kk].split("\n").join( "\n" + ix) + "\n";
-                }
                 
-                switch(typeof(v)) {
-                    case 'object': 
-                        if (v.constructor == Array) {
-                            ret += ix + this.toJsProp(k) +  ' : ' + this.arrayToJsString(v, ind+1);
-                            continue;
-                        }
-                    
-                    
-                        ret += ix + this.toJsProp(k) +  ' : ' + this.objectToJsString(v, ind+1);
-                        continue;
-                    
-                    case 'boolean' : 
-                        ret += ix + this.toJsProp(k) +  ' : ' +  (v ? 'true' : 'false');
-                        continue;
-                    
-                    case 'number' : 
-                        ret += ix + this.toJsProp(k) +  ' : ' +  v;
-                        continue;
-                        
-                    
-                    case 'string': 
-                        if (k[0] == '|') {
-                            ret += ix + this.toJsProp(k) +  ' : ' +  v.split("\n").join( "\n" + ix);
-                            continue;
-                        }
-                        // fallthru
+                //var left = isArray ? '' : (JSON.stringify(i) + " : " )
+                
+                if (i[0] == '|') {
+                    // does not hapepnd with arrays..
+                    if (typeof(el) == 'string' && !obj[i].length) { //skip empty.
+                        return;
+                    }
+                    // this needs to go...
+                    //if (typeof(el) == 'string'  && obj[i].match(new RegExp("Gtk.main" + "_quit"))) { // we can not handle this very well..
+                    //    return;
+                    //}
                     
-                    default:
-                        // we should use special stuff here to determine if it's a singly or dobuley 
-                        // quoted string..
-                        ret += ix + this.toJsProp(k) +  ' : ' +  this.stringToJsString(v, k, o);
-                        continue;
-                        
-                     
+                    var str= ('' + obj[i]).replace(/^\s+|\s+$/g,"");;
+                    var lines = str.split("\n");
+                    if (lines.length > 1) {
+                        str = lines.join("\n" + pad);
                     }
-            }
-            return "{\n" + ret + "\n" + ix1 + '}'; 
-            
-        },
-        arrayToJsString : function (ar, ind)
-        {
-            var isobjar = false;
-            ar.forEach( function(o) {
-                if (typeof(o) == 'object' && (o.constructor != Array)) {
-                    isobjar = true;
-                }
-            });
-            var ix = '';
-            var ix1 = '';
-            var cr = ', ';
-            var lb = ' ';
-            if (isobjar) {
-                ix = new Array(ind+1).join("    ");
-                ix1 = new Array(ind).join("    ");
-                cr = ",\n";
-                lb = "\n";
-                 
-            }
-            // array of parts...
-            var ret =  '';
-            var _this = this;
-            ar.forEach( function(v, n) {
-                // skip blank last element in an array
-                if ((n == (ar.length -1))  && typeof(v) == 'undefined') {
+                    
+                    els.push(left + str);
                     return;
                 }
                 
-                // empty objects in array?
-                if (typeof(v) == 'object' && v.constructor != Array) {
-                    if (!_this.objectKeys(v).length) {
-                        return;
-                    }
-                }
-                    
                 
-                ret += ret.length ? cr : '';
                 
-                switch(typeof(v)) {
                 
-                    case 'object': 
-                        if (v.constructor == Array) {
-                            
-                            ret += ix + _this.arrayToJsString(v, ind+1);
-                            return;
-                        }
-                    
-                        ret += ix + _this.objectToJsString(v, ind+1);
-                        return;
-                    
-                    case 'boolean' : 
-                        ret += ix +  (v ? 'true' : 'false');
-                        return;
-                    
-                    case 'number' : 
-                        ret += ix +  v;
-                        return;
-                        
-                    
-                    case 'string': 
-                        if (k[0] == '|') {
-                            ret += ix + v.split("\n").join( "\n" + ix);
-                            return;
-                        }
-                        // fallthru
+                if (typeof(el) == 'object') {
                     
-                    default:
-                        // we should use special stuff here to determine if it's a singly or dobuley 
-                        // quoted string..
-                        ret += ix + JSON.stringify(v);
-                        return;
-                        
-                 
+                    // we can skip empty items lists and empty listeners..
+                    //if (!isArray && i == 'items' && !el.length) {
+                    //    return; 
+                    //}
+                   // 
+                    var right = _this.mungeToString(el, i == 'listeners', pad + '    ');
+                    if (typeof(right) != 'undefined') {
+                        els.push(left + right);
+                    }
+                
+                    return;
                 }
-                 
+                // standard. .
+                if (typeof(obj[i]) != 'string') {
+                    els.push(left + JSON.stringify(obj[i]));
+                    return;
+                }
+                // strings..
+                if (!_this.doubleStringProps) {
+                    els.push(left + JSON.stringify(obj[i]));
+                    return;
+                }
+                if (_this.doubleStringProps.indexOf(i) > -1) {
+                    els.push(left + JSON.stringify(obj[i]));
+                    return;
+                }
+                // single quote..
+                els.push(left + "'" + obj[i].replace(/'/g, "\\'") + "'");
+                
+
             });
-            return "[" + lb  + ret + lb + ix1 + "]";
             
-        },
-        stringToJsString :  function(v, k , o) {
-            // since most properties can use single quotes (non-translatable)
-            // we try to fix this here..
-            var val = JSON.stringify(v);
-            if (['xns', 'xtype'   ].indexOf(k) > -1) {
-                return "'" + val.substring(1, val.length-1).replace(/'/, "\\'") + "'";
+            if (!isArray && !els.length) {
+                return;
             }
-            return val;
+            //output the thing.
+            var spad = pad.substring(0, pad.length-4);
+            return (isArray ? '[' : '{') + "\n" +
+                pad  + els.join(",\n" + pad ) + 
+                "\n" + spad + (isArray ? ']' : '}');
+               
             
             
-        },
-        
-        
-        toJsProp:  function(v) {
-            var vv = v[0] == '|' ? v.substring(1) : v;
-            if (Lang.isKeyword(vv) || Lang.isBuiltin(vv)) {
-                return "'" + vv + "'";
-            }
-            if (vv.match(/[^A-Z_]+/i)) {
-                var val = JSON.stringify(vv);
-                return "'" + val.substring(1, val.length-1).replace(/'/, "\\'") + "'";
-            }
-            return vv;
-        }
+        } 
         
+         
         
     }
+    
+     
+    
 );