jam/js/com/nav.js

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
}