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