266 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			266 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /**
 | |
|  **      ==================================
 | |
|  **      OOOO   OOOO OOOO  O      O   OOOO
 | |
|  **      O   O  O    O     O     O O  O   O
 | |
|  **      O   O  O    O     O     O O  O   O
 | |
|  **      OOOO   OOOO OOOO  O     OOO  OOOO
 | |
|  **      O   O     O    O  O    O   O O   O
 | |
|  **      O   O     O    O  O    O   O O   O
 | |
|  **      OOOO   OOOO OOOO  OOOO O   O OOOO
 | |
|  **      ==================================
 | |
|  **      BSSLAB, Dr. Stefan Bosse http://www.bsslab.de
 | |
|  **
 | |
|  **      COPYRIGHT: THIS SOFTWARE, EXECUTABLE AND SOURCE CODE IS OWNED
 | |
|  **                 BY THE AUTHOR.
 | |
|  **                 THIS SOURCE CODE MAY NOT BE COPIED, EXTRACTED,
 | |
|  **                 MODIFIED, OR OTHERWISE USED IN A CONTEXT
 | |
|  **                 OUTSIDE OF THE SOFTWARE SYSTEM.
 | |
|  **
 | |
|  **    $AUTHORS:     Stefan Bosse
 | |
|  **    $INITIAL:     (C) 2006-2016 BSSLAB
 | |
|  **    $CREATED:     by sbosse on 12/11/15
 | |
|  **    $REVESIO:     1.1.7
 | |
|  **
 | |
|  **    $INFO:
 | |
|  **
 | |
|  **  AST: Tree-based Navigator
 | |
|  **
 | |
|  **    $ENDOFINFO
 | |
|  */
 | |
| "use strict";
 | |
| var Io = Require('com/io');
 | |
| var Comp = Require('com/compat');
 | |
| var Hashtbl = Comp.hashtbl;
 | |
| var Array = Comp.array;
 | |
| var Hashtbl = Comp.hashtbl;
 | |
| var String = Comp.string;
 | |
| var Perv = Comp.pervasives;
 | |
| var Obj = Comp.obj;
 | |
| var Rnd = Comp.random;
 | |
| var Filename = Comp.filename;
 | |
| var Err = Require('com/err');
 | |
| var Printf = Comp.printf;
 | |
| var blessed = Require('term/blessed');
 | |
| 
 | |
| 
 | |
| /** A JS Tree-Object Navigator
 | |
|  *
 | |
|  * options:{title:string,info:string,showfun:boolean}
 | |
|  */
 | |
| 
 | |
| var navigator = function (data,options) {
 | |
|   var self=this;
 | |
|   this.log='';
 | |
|   var mem;
 | |
|   this.options=options||{};
 | |
|   if (this.options.showfun==undefined) this.options.showfun=true;
 | |
|   this.info = function (element) {
 | |
|     if (Obj.isObject(element)) return '{..}';
 | |
|     else if(Obj.isArray(element)) return '[..]';
 | |
|     else if (element != undefined) {
 | |
|       var name=element.toString();
 | |
|       var funpat = /function [0-9A-Z_$]*\(/i;
 | |
|       var isfun=Obj.isFunction(element)||funpat.test(name);
 | |
|         if (isfun) {
 | |
|           return String.sub(name,0,name.indexOf('{'));
 | |
|         } else return element 
 | |
|     } else return 'undefined';
 | |
|   };
 | |
|   this.maketree = function (element) {
 | |
|     var content,children;
 | |
|     children={};
 | |
|     if (Obj.isObject(element)  || Obj.isArray(element)) {
 | |
|       for (var p in element) {
 | |
|          children[p]={};
 | |
|       }
 | |
|       content={
 | |
|          children : children,
 | |
|          data : element
 | |
|       }
 | |
|     } else if (element != undefined) {
 | |
|       var name=element.toString();
 | |
|       var funpat = /function [0-9A-Z_$]*\(/i;
 | |
|       var isfun=Obj.isFunction(element)||funpat.test(name);
 | |
|       if (isfun) {
 | |
|         element=String.sub(name,0,name.indexOf('{'));
 | |
|       }
 | |
|       if (!isfun || (isfun && self.options.showfun)) {
 | |
|         children[element]={};
 | |
|         content={children : children};
 | |
|       }
 | |
|     } else {
 | |
|       children[element]={};
 | |
|       content={children : children};    
 | |
|     }
 | |
|     return content;
 | |
|   };
 | |
|   this.screen = blessed.screen({
 | |
|     smartCSR: false,
 | |
|     terminal: 'xterm-color'
 | |
|     });
 | |
| 
 | |
|   this.screen.title = this.options.title||'my window title';
 | |
|   this.screen.cursor.color='red';  
 | |
|   this.tree = blessed.tree({
 | |
|     top: 3,
 | |
|     left: 'left',
 | |
|     width: '100%',
 | |
|     height: this.screen.height>20?'75%':'60%',
 | |
|     label: this.options.info||'AST',
 | |
|     focus:true,
 | |
|     border: {
 | |
|       type: 'line'
 | |
|     },
 | |
|     style: {
 | |
|       border: {
 | |
|         fg: 'black'
 | |
|       },
 | |
|       hover: {
 | |
|         border: {
 | |
|           fg: 'red'
 | |
|         }
 | |
|       },
 | |
|       focus : {
 | |
|         border: {
 | |
|           fg: 'red'
 | |
|         }      
 | |
|       }
 | |
|     }
 | |
|     });
 | |
|   this.tree.focus();
 | |
|   // Create sub-trees
 | |
|   this.tree.on('preselect',function(node){  
 | |
|     var content,children;  
 | |
|     if (node.name != '/' && !node.extended)  {
 | |
|       // Io.out(node.extended);
 | |
|       var data = node.data;
 | |
|       if (data != none && (Obj.isObject(data) || Obj.isArray(data))) {
 | |
|         node.children = {};
 | |
|         if (Obj.isArray(data) && Array.empty(data) && Hashtbl.empty(data)) {
 | |
|           node.children={'[]' : {}};
 | |
|         } else for (var p in data) {
 | |
|          var element = data[p];
 | |
|          content=self.maketree(element);
 | |
|          if (content) node.children[p]=content;
 | |
|         } 
 | |
|       }
 | |
|     }
 | |
|   });
 | |
|   // Update preview
 | |
|   this.tree.on('selected',function(node){
 | |
|     mem=Io.mem();
 | |
|     self.stats.setValue('Data: '+Perv.int_of_float(mem.data/1024)+' MB'+
 | |
|                         '   Heap: '+Perv.int_of_float(mem.heap/1024)+ ' MB');
 | |
|     self.preview.setValue(node.name);
 | |
|     if (node.data) {
 | |
|       for (var p in node.data) {
 | |
|         self.preview.setValue(p+':'+self.info(node.data[p]));
 | |
|         break;
 | |
|       }
 | |
|     } else if (node.children) self.preview.setValue(node.name+':'+Obj.head(node.children));
 | |
|     self.screen.render();
 | |
|   });
 | |
|   this.tree.DATA = {
 | |
|     name:'/',
 | |
|     extended:true,
 | |
|     children: {}
 | |
|   };
 | |
|   this.lastobj = data;
 | |
|   for (var p in data) {
 | |
|     var element=data[p];
 | |
|     var content=this.maketree(element);
 | |
|     if (content) this.tree.DATA.children[p]=content;
 | |
|   }
 | |
|   
 | |
|   this.screen.append(this.tree);
 | |
|   this.screen.key(['escape', 'q', 'C-c'], function(ch, key) {
 | |
|     return process.exit(0);
 | |
|   });
 | |
| 
 | |
|   this.tree.setData(this.tree.DATA);
 | |
| 
 | |
|   
 | |
|   this.preview = blessed.textbox({
 | |
|     top: this.screen.height>20?'90%':'80%',
 | |
|     left: 'left',
 | |
|     width: '100%',
 | |
|     height: 3,
 | |
|     label: 'Preview',
 | |
|     focus:false,
 | |
|     border: {
 | |
|       type: 'line'
 | |
|     },
 | |
|     style: {
 | |
|       fg:'blue'
 | |
|     }
 | |
|   });
 | |
|   this.screen.append(this.preview);
 | |
|   this.preview.setValue('');
 | |
| 
 | |
|   this.stats = blessed.textbox({
 | |
|     top: 0,
 | |
|     left: this.screen.width-40,
 | |
|     width: 40,
 | |
|     height: 3,
 | |
|     label: 'Statistics',
 | |
|     focus:false,
 | |
|     border: {
 | |
|       type: 'line'
 | |
|     },
 | |
|     style: {
 | |
|       fg:'blue'
 | |
|     }
 | |
|   });
 | |
|   this.screen.append(this.stats);
 | |
|   mem=Io.mem();
 | |
|   this.stats.setValue('Data: '+Perv.int_of_float(mem.data/1024)+' MB'+
 | |
|                       '   Heap: '+Perv.int_of_float(mem.heap/1024)+ ' MB');
 | |
|   
 | |
|   this.but1 = blessed.button({
 | |
|     width: 8,
 | |
|     top: 0,
 | |
|     height: 3,
 | |
|     align: 'center',
 | |
|     content: 'QUIT',
 | |
|     mouse:true,
 | |
|     focus:true,
 | |
|     border: {
 | |
|       type: 'line'
 | |
|     },
 | |
|     style: {
 | |
|       fg: 'white',
 | |
|       bg: 'blue',
 | |
|       bold:true,
 | |
|       border: {
 | |
|         fg: 'black'
 | |
|       },
 | |
|       hover: {
 | |
|         border: {
 | |
|           fg: 'red'
 | |
|         }
 | |
|       },
 | |
|       focus : {
 | |
|         border: {
 | |
|           fg: 'red'
 | |
|         }      
 | |
|       }
 | |
|     }
 | |
|   });
 | |
|   this.but1.on('press', function(data) {
 | |
|     return process.exit(0);  
 | |
|   });
 | |
|   this.screen.append(this.but1);
 | |
|   this.screen.render(); 
 | |
|   
 | |
| }
 | |
| 
 | |
| var Navigator = function(data,options){
 | |
|     var obj = new navigator(data,options);
 | |
|     // Object.preventExtensions(obj);
 | |
|     return obj;
 | |
| };
 | |
| 
 | |
| module.exports = {
 | |
|   Navigator:Navigator
 | |
| }
 |