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
|
|
}
|