Pman.Builder.View.js
[Pman.Builder] / Pman.Builder.View.js
1 /**
2  * The code that renders the view  - used to be in the Builder.View etc...
3  *
4  * used to be inside the Interface, but has proved to be to difficult to manage.
5  *
6  * In principle, simple event handling code is put in the interface, and any hard
7  * lifting is done in nice files...
8  *
9  * It might be better to just extend 'tree', and use the extended class..
10  * 
11  */
12
13 Pman.Builder.View = {
14     
15     panel : false,
16     
17     panelroot : false,
18     dialogroot : false,
19     
20     
21     renderObj : false,
22     
23     doc : function() {
24         var iframe = this.container.el.select('iframe',true).first().dom;
25         
26         return iframe.contentDocument || iframe.contentWindow.document;
27     },
28     win : function() {
29         var iframe = this.container.el.select('iframe',true).first().dom;
30         return iframe.contentWindow;
31     },
32     
33     init : function (comp) {
34         if (this.panel || !comp.layout) {
35             return;
36         }
37         this.panel = comp.panel;
38         this.layout  = comp.panel.layout;
39         // see if we can render a iframe..
40         
41         var app = 'test';
42         
43         this.container = comp.layout.getRegion('center').getPanel(0);
44         this.container.setContent(
45                 '<iframe width="100%" height="100%" src="'+baseURL+'/Builder/App/' + app + '?no_parts=1"></iframe>'
46         );
47         var iframe = this.container.el.select('iframe',true).first()
48         
49         iframe.setSize( this.panel.el.getSize());
50         
51         //this.doc = iframe.contentDocument || iframe.contentWindow.document;
52         
53         
54     },
55     
56     clearAll : function(isAuto) {
57         try {
58             this.win().Pman.Builder.View.frameClearAll(isAuto);
59         } catch(e) {
60             //alert(e);
61         }
62         
63        
64     },
65     
66     frameToHTML : function()
67     {
68         return this.win().Pman.Builder.View.toHTML();  
69         
70         
71         
72     },
73     toHTML : function ()  {
74         var ret = '';
75         Roo.select('body > div',true).each(function(el) {
76             this.traverseDOMTree(function(s) { ret+=s; }, el.dom, 1);
77             ret+="\n";
78         }, this);
79         return ret;
80         
81     },
82     traverseDOMTree : function(cb, currentElement, depth) {
83         if (currentElement) {
84             
85             if (currentElement.className.match(/roo-dynamic/)) {
86                 return;
87             }
88             //Roo.log(currentElement);
89             var j;
90             var nodeName = currentElement.nodeName;
91             var tagName = currentElement.tagName;
92             
93             if  (nodeName == '#text') {
94                 cb(currentElement.nodeValue);
95                 return;
96             
97             }
98             var i = 0;
99           // Prints the node tagName, such as <A>, <IMG>, etc
100             if (tagName) {
101                 var attr = [];
102                 for(i = 0; i < currentElement.attributes.length;i++) {
103                     var aname = currentElement.attributes.item(i).name;
104                     if (aname=='id') {
105                         aname= 'xbuilderid';
106                     }
107                     attr.push(aname + '="' + currentElement.attributes.item(i).value + '"' );
108                 }
109                 
110                 
111                 cb("<"+currentElement.tagName+ ( attr.length ? (' ' + attr.join(' ') ) : '') + ">");
112             } 
113             else {
114               cb("[unknown tag]");
115             }
116             // Traverse the tree
117             i = 0;
118             var currentElementChild = currentElement.childNodes[i];
119             var allText = true;
120             while (currentElementChild) {
121                 // Formatting code (indent the tree so it looks nice on the screen)
122                 
123                 if  (currentElementChild.nodeName == '#text') {
124                     cb(currentElementChild.nodeValue);
125                     i++;
126                     currentElementChild=currentElement.childNodes[i];
127                     continue;
128                 }   
129                 allText = false;
130                 cb("\n");
131                 for (j = 0; j < depth; j++) {
132                   // &#166 is just a vertical line
133                   cb("  ");
134                 }               
135                 
136                     
137                 // Recursively traverse the tree structure of the child node
138                 this.traverseDOMTree(cb, currentElementChild, depth+1);
139                 i++;
140                 currentElementChild=currentElement.childNodes[i];
141             }
142             if (!allText) {
143                 // The remaining code is mostly for formatting the tree
144                 cb("\n");
145                 for (j = 0; j < depth - 1; j++) {
146                   cb("  ");
147                 }     
148             }
149             if (tagName) {
150                 cb("</"+tagName+">");
151             }
152         }
153     },
154
155      
156     
157     frameClearAll : function(isAuto) {
158 //        this.renderObj = { isBuilder : true };
159
160         
161         if (this.panelroot) {
162             this.scroll = this.panelroot.el.getScroll();
163             this.layout.remove('center', this.panelroot);
164             this.panelroot = false;
165         }
166         if (this.dialogroot) {
167             this.dialogroot.remove();
168             this.dialogroot = false;
169         }
170         Roo.select('body > div').remove();
171         
172     },
173     munge : function(cfg, keyname, add_xattr) {
174         keyname = keyname || false;
175         
176         this.renderObj = this.renderObj || {};
177         
178         var xitems = false;
179         if (cfg.items) {
180             xitems = cfg.items;
181             delete cfg.items;
182         }
183         
184         if (typeof(cfg.background) != 'undefined') {
185             cfg.background = false;
186         }
187         
188         
189         for(var p in cfg){
190             // key is not string?!?!?!!?
191             if (typeof(p) != 'string') {
192                 continue;
193             }
194             
195             if (typeof(cfg[p]) == 'object') { // listeners!!!
196                 this.munge(cfg[p], p, add_xattr);
197                 continue;
198             }
199             // SPECIAL - PIPE
200             if (p.charAt(0) == '|' || keyname=='listeners') {
201                 
202                 if (!cfg[p].length) {
203                     delete cfg[p];
204                     continue;
205                 }
206                 var str = cfg[p];
207                 if (str.match(/\s*function/)) {
208                     var btz = str.split('{');
209                     str = btz.shift()  +'{ try {' + btz.join('{') + 
210                         ' catch (e) { Roo.log(e) } }';
211                 }
212                 try {
213                     Roo.log("interpret? " + str);
214                     var _tmp = false;
215                     var _this = this.renderObj; /// fake '_this' object..
216                     // stupid IE can not return objects evaluated..
217                     /**
218                      eval:var:_this  
219                      eval:var:_tmp 
220                     **/
221                     
222                     
223                     eval('_tmp =(' + str + ')');
224                     cfg[p.replace(/^\|/, '')] = _tmp;
225                     if (typeof(_tmp) == 'undefined') {
226                         alert(cfg[p]);
227                     }
228                    
229                 } catch(e) {  console.log('Error evaluating: '  + str); };
230                 //if (p.charAt(0) == '|' ) {
231                 //    delete cfg[p];
232                 //}
233                     
234                 
235                 continue;
236             }
237             // skip '*'
238             if ((p.charAt(0) == '*') || (p.charAt(0) == '+')) {
239                 delete cfg[p];
240                 continue;
241             }
242             // normal..
243               
244         }
245         
246         // add xattr data?
247         if (add_xattr) {
248             
249             if(typeof(cfg.xattr) != 'undefined'){
250                 cfg.xattr.xtype = cfg['|xns'] + '.' + cfg.xtype;
251             }else{
252                 cfg.xattr = {
253                     xtype : cfg['|xns'] + '.' + cfg.xtype 
254                 };
255             }
256             
257         }
258         
259         
260         
261         // now for all the children.. (items)
262         if (xitems === false) {
263             return;
264         }
265         cfg.items = [];
266         for (var i = 0; i < xitems.length; i++) {
267             // if +builderhide set !!!! drop it!!
268             
269             
270             var xi = xitems[i];
271             if (typeof(xi['*prop']) != 'undefined') {
272                 var pr = xi['*prop'];
273                 this.munge(xi, false, add_xattr);
274                 // if prop is an array - then it's items are really the value..
275                 if (pr.match(/\[\]$/)) {
276                     pr = pr.replace(/\[\]$/, '');
277                     if (typeof(cfg[pr]) == 'undefined') {
278                         cfg[pr] = [];
279                     }
280                     cfg[pr].push(xi);
281                     continue;
282                 }
283                 if (xi.xtype && xi.xtype  == 'Array') {
284                     cfg[pr] = xi.items;
285                 } else {
286                     cfg[pr] = xi;
287                 }
288                 
289                 
290                 continue;
291             }
292             this.munge(xi, false, add_xattr);
293             cfg.items.push(xi);
294         }
295         
296         if (cfg.items.length == 0) {
297             delete cfg.items;
298         }
299         // remove listeners if there are none..
300         if (typeof(cfg['listeners']) != 'undefined') {
301             var n =0;
302             for (var i in cfg.listeners) { n++; }
303             if (!n) {
304                 delete cfg['listeners'];
305             }
306             
307         }
308         
309         if (typeof(cfg.id) != 'undefined') {
310             cfg.id = 'pman-dyn-' + cfg.id;
311         }
312             
313             
314     },
315     toJS : function(n)
316     {
317     
318         if (!n) {
319             return Pman.Builder.Tree.toJS(Pman.Tab.BuilderTree.tree.root);
320         }
321    
322         var _this = this;
323         var ret = Pman.Builder.Tree.cloneConfig(n.elConfig);
324         
325         // flag to prevent rendering..
326         if ((typeof(ret['+buildershow']) != 'undefined') && !ret['+buildershow']) {
327             return false;
328         }
329     
330         ret.id = typeof(ret.id) == 'undefined' ? 'builder-' + n.id : ret.id;
331     
332         if (n.childNodes.length) {
333             ret.items = [];
334             n.eachChild(function(cn) {
335                 var add = _this.toJS(cn);
336                 if (add === false) {
337                     return;
338                 }
339                 
340                 
341                 ret.items.push(add);
342             });
343                 
344         }
345         return ret;
346     },
347
348     redraw : function(isAuto)
349     {
350         this.container.el.select('iframe',true).first().setSize(this.panel.el.getSize());
351  
352        // return;
353         // top level is not relivant
354
355 //          var btop =  Pman.Tab.BuilderTop2;
356   //      if (isAuto && btop.redrawBtn  && !btop.redrawBtn.auto) {
357     //        return; /// auto redraw is turned off..
358       //  }
359         
360         this.clearAll(isAuto);
361         
362         var cfg =  this.toJS();
363         
364         this.win().Pman.Builder.View.draw( cfg );
365         
366     },
367     draw :function(cfg)
368     {
369         Roo.log(cfg);
370         
371         if (!cfg.items[0]) {
372             return;
373         }
374         
375         
376         this.munge(cfg.items[0],false , true );
377         
378         Roo.log(cfg);
379         //  return;
380         // we draw either a dialog or a tab..
381         
382         if (cfg.items[0].xtype == 'LayoutDialog') {
383             
384             cfg.items[0].modal = false;
385             var xy  = this.el.getXY();
386             cfg.items[0].x = xy[0];
387             cfg.items[0].y = xy[1];
388             cfg.items[0].constraintoviewport = false;
389             
390             this.dialogroot = Roo.get( this.doc).createChild();
391             try { 
392                 this.dialog = new Roo[cfg.items[0].xtype](this.dialogroot, cfg.items[0]);
393               //  this.dialog.el.on('click', this.panelClick, this);
394                 this.dialog.show();
395                 var dlg = this.dialog;
396                 (function () {
397                     dlg.moveTo(xy[0], xy[1]);
398                 }).defer(100);
399             } catch(e) {
400                 Roo.log("Error rendering dialog: " + e.toString());
401                 Roo.log(e);
402             }
403             return;
404             
405             
406         }
407         if (cfg.items[0]['|xns'] == 'Roo.bootstrap') {
408             
409             if (cfg.items[0].xtype =='Modal' ) {
410                 this.bootstrapModal = Roo.factory(cfg.items[0]);
411                 this.bootstrapModal.show();
412                 return;
413             }
414             Roo.log("bootstrap build!?");
415             var top = new Roo.bootstrap.Body({});
416             top.onRender(false,false);
417             
418             this.bootstrapModal = top.addxtype(cfg.items[0]);
419             
420             this.applyFlexy(top);
421             
422             
423             
424             return;
425         }
426         
427         
428         
429         // should we render this into a dialog???
430              // force center region..
431         cfg.items[0].region = 'center';
432         cfg.items[0].background = false;
433         
434         try {
435             
436             cfg.parent = '#';
437             
438             
439             this.panelroot = this.layout.addxtype(cfg.items[0]);
440         
441         } catch(e) {
442             Roo.log("Error rendering: " + e.toString());
443             Roo.log(e);
444         }
445         //this.highlightElement(Pman.Tab.BuilderTree.currentNode);
446         
447         if (this.panelroot && this.panelroot.el) {
448                 this.panelroot.el.scrollTo('top', 0);
449                 this.panelroot.el.scrollTo('left', 0);
450             
451         }
452     },
453     frameUpdateTheme: function(name)
454     {
455          return this.win().Pman.Builder.View.updateTheme(name);  
456     },
457     updateTheme : function(name)
458     {
459        Roo.select('head link[rel=stylesheet]').each(function(e) {
460             if (!e.dom.href.match(/bootstrap\.\min.css$/)) {
461                 return;
462             }
463             e.dom.setAttribute('href', rootURL +'/bootswatch/' + name + '/bootstrap.min.css' );
464             
465         
466        });
467     },
468     
469     applyFlexy: function(tree)
470     {
471         if (typeof(tree['flexy:foreach']) != 'undefined') {
472             tree.el.attr('flexy:foreach', tree['flexy:foreach']);
473         }
474         if (typeof(tree['flexy:if']) != 'undefined') {
475             tree.el.attr('flexy:if', tree['flexy:if']);
476         }
477         if (!tree.items || !tree.items.length) { return; }
478         
479         for (var i = 0; i < tree.items.length; i++){
480             this.applyFlexy(tree.items[i]);
481         }
482     }
483     
484     
485     
486 }