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