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