Commands now managed like plugins
This commit is contained in:
parent
7a10aa73c2
commit
099f0192a7
6 changed files with 327 additions and 245 deletions
41
blash.js
41
blash.js
|
@ -9,6 +9,9 @@ function blash ()
|
|||
/** Shell window object */
|
||||
this.window = document.getElementById ( "blashWindow" );
|
||||
|
||||
/** Array containing the codes of the shell commands */
|
||||
this.commands = new Array();
|
||||
|
||||
/** Escape sequences to be parsed in the prompt text */
|
||||
this.promptSequences = new Array();
|
||||
|
||||
|
@ -34,6 +37,25 @@ function blash ()
|
|||
this.__open_spans = 0;
|
||||
/**************************************/
|
||||
|
||||
this.loadCommand = function ( cmd )
|
||||
{
|
||||
var cmd_file = window.location.href;
|
||||
cmd_file = cmd_file.replace ( /\/([a-zA-Z\.]+)$/, '/commands/' + cmd + ".json" );
|
||||
|
||||
var http = new XMLHttpRequest();
|
||||
http.open ( "GET", cmd_file, true );
|
||||
|
||||
http.onreadystatechange = function ()
|
||||
{
|
||||
if ( http.readyState == 4 && http.status == 200 )
|
||||
{
|
||||
shell.commands.push ( eval ( '(' + http.responseText + ')' ));
|
||||
}
|
||||
}
|
||||
|
||||
http.send ( null );
|
||||
}
|
||||
|
||||
this.prompt.focus();
|
||||
|
||||
var json_config = window.location.href;
|
||||
|
@ -58,11 +80,16 @@ function blash ()
|
|||
banner.innerHTML = shell.json.banner;
|
||||
shell.window.insertBefore ( banner, shell.promptText );
|
||||
}
|
||||
|
||||
for ( var i in shell.json.commands )
|
||||
{
|
||||
shell.loadCommand ( shell.json.commands[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
http.send ( null );
|
||||
|
||||
|
||||
this.getKey = function ( e )
|
||||
{
|
||||
var evt = ( window.event ) ? window.event : e;
|
||||
|
@ -79,12 +106,12 @@ function blash ()
|
|||
this.history.push ( this.prompt.value );
|
||||
this.history_index = -1;
|
||||
|
||||
for ( i=0; i < this.json.commands.length && !cmd_found; i++ )
|
||||
for ( i=0; i < this.commands.length && !cmd_found; i++ )
|
||||
{
|
||||
if ( this.json.commands[i].name == cmd )
|
||||
if ( this.commands[i].name == cmd )
|
||||
{
|
||||
cmd_found = true;
|
||||
var out = this.json.commands[i].action ( arg );
|
||||
var out = this.commands[i].action ( arg );
|
||||
|
||||
if ( out.length > 0 )
|
||||
{
|
||||
|
@ -189,13 +216,13 @@ function blash ()
|
|||
} else {
|
||||
var cmds = new Array();
|
||||
|
||||
for ( var i in this.json.commands )
|
||||
for ( var i in this.commands )
|
||||
{
|
||||
var re = new RegExp ( '^' + this.prompt.value );
|
||||
|
||||
if ( this.json.commands[i].name.match ( re ))
|
||||
if ( this.commands[i].name.match ( re ))
|
||||
{
|
||||
cmds.push ( this.json.commands[i].name );
|
||||
cmds.push ( this.commands[i].name );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
242
blash.json
242
blash.json
|
@ -63,244 +63,10 @@
|
|||
],
|
||||
|
||||
"commands" : [
|
||||
{
|
||||
"name" : "pwd",
|
||||
|
||||
"info" : {
|
||||
"syntax" : "pwd",
|
||||
"brief" : "Print name of current/working directory",
|
||||
},
|
||||
|
||||
"action" : function ( arg ) {
|
||||
if ( arg )
|
||||
{
|
||||
if ( arg.length > 0 )
|
||||
{
|
||||
return this.name + ": Too many arguments<br/>";
|
||||
} else {
|
||||
return shell.path + '<br/>';
|
||||
}
|
||||
} else {
|
||||
return shell.path + '<br/>';
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
"name" : "man",
|
||||
|
||||
"info" : {
|
||||
"syntax" : "man <page>",
|
||||
"brief" : "Display the manual page for the command 'page'",
|
||||
},
|
||||
|
||||
"action" : function ( arg ) {
|
||||
var out = '';
|
||||
|
||||
if ( arg == undefined || arg.length == 0 )
|
||||
{
|
||||
return "What manual page do you want?<br/>\n";
|
||||
}
|
||||
|
||||
var cmd = shell.json.commands;
|
||||
|
||||
if ( arg == 'blash' )
|
||||
{
|
||||
var commands = new Array();
|
||||
out = '<span class="brief">Type "<span class="syntax">man <command></span>" for a more detailed help on these commands</span><br/><br/>';
|
||||
|
||||
for ( var i=0; i < cmd.length; i++ )
|
||||
{
|
||||
commands.push ( cmd[i].info.syntax );
|
||||
}
|
||||
|
||||
commands.sort();
|
||||
|
||||
for ( var i in commands )
|
||||
{
|
||||
out += '<span class="syntax">' + commands[i] + '</span><br/>';
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
var found = false;
|
||||
|
||||
for ( var i=0; i < cmd.length && !found; i++ )
|
||||
{
|
||||
if ( arg == cmd[i].name )
|
||||
{
|
||||
if ( cmd[i].info.syntax.length > 0 && cmd[i].info.brief.length > 0 )
|
||||
{
|
||||
found = true;
|
||||
|
||||
out =
|
||||
'<span class="syntax">' + cmd[i].info.syntax + '</span><br/><br/>' +
|
||||
'<span class="brief">' + cmd[i].info.brief + '</span><br/>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !found )
|
||||
{
|
||||
return "No manual entry for " + arg + "<br/>\n";
|
||||
}
|
||||
|
||||
return out;
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
"name" : "ls",
|
||||
|
||||
"info" : {
|
||||
"syntax" : "ls [path]",
|
||||
"brief" : "List directory contents",
|
||||
},
|
||||
|
||||
"action" : function ( arg )
|
||||
{
|
||||
var dirs = new Array();
|
||||
var out = '';
|
||||
var exists = false;
|
||||
|
||||
arg = arg.replace ( /\/$/, '' );
|
||||
|
||||
if ( !arg || arg.length == 0 )
|
||||
{
|
||||
var re = new RegExp ( '^' + shell.path + '[^/]+$' );
|
||||
} else if ( arg && arg.length > 0 ) {
|
||||
var re = null;
|
||||
|
||||
if ( arg.match ( /^\// ))
|
||||
{
|
||||
re = new RegExp ( '^' + arg + '/[^/]+$' );
|
||||
} else {
|
||||
re = new RegExp ( '^' + shell.path +
|
||||
(( shell.path == '/' ) ? '' : '/' ) +
|
||||
arg + '/[^/]+$' );
|
||||
}
|
||||
}
|
||||
|
||||
for ( var i=0; i < shell.json.directories.length; i++ )
|
||||
{
|
||||
var dir = shell.json.directories[i];
|
||||
|
||||
if ( dir.path.match ( re ))
|
||||
{
|
||||
exists = true;
|
||||
dir.path.match ( /\/([^\/]+)$/ );
|
||||
dirs.push ({
|
||||
"path" : RegExp.$1,
|
||||
"type" : dir.type,
|
||||
"href" : dir.href,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if ( dirs.length > 0 )
|
||||
{
|
||||
var ordered = false;
|
||||
|
||||
// Directories go first
|
||||
while ( !ordered )
|
||||
{
|
||||
ordered = true;
|
||||
|
||||
for ( var i=0; i < dirs.length-1; i++ )
|
||||
{
|
||||
for ( var j=i+1; j < dirs.length; j++ )
|
||||
{
|
||||
if ( dirs[i].type == 'file' && dirs[j].type == 'directory' )
|
||||
{
|
||||
var tmp = dirs[i];
|
||||
dirs[i] = dirs[j];
|
||||
dirs[j] = tmp;
|
||||
ordered = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ordered = false;
|
||||
|
||||
// Sort the names
|
||||
while ( !ordered )
|
||||
{
|
||||
ordered = true;
|
||||
|
||||
for ( var i=0; i < dirs.length-1; i++ )
|
||||
{
|
||||
for ( var j=i+1; j < dirs.length; j++ )
|
||||
{
|
||||
if ( dirs[i].type == dirs[j].type && dirs[i].path > dirs[j].path )
|
||||
{
|
||||
var tmp = dirs[i];
|
||||
dirs[i] = dirs[j];
|
||||
dirs[j] = tmp;
|
||||
ordered = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( var i in dirs )
|
||||
{
|
||||
if ( dirs[i] )
|
||||
{
|
||||
if ( dirs[i].path.length > 0 )
|
||||
{
|
||||
if ( dirs[i].type == 'directory' )
|
||||
{
|
||||
out += '<span class="directory">' + dirs[i].path + '</span>/<br/>';
|
||||
} else {
|
||||
if ( dirs[i].href && dirs[i].href.length > 0 )
|
||||
{
|
||||
out += '<a href="' + dirs[i].href + '" class="file" target="_new">' + dirs[i].path + '</a>*<br/>';
|
||||
} else {
|
||||
out += '<span class="file">' + dirs[i].path + '</span><br/>';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !exists )
|
||||
{
|
||||
var re = null;
|
||||
|
||||
if ( arg.match ( /^\// ))
|
||||
{
|
||||
re = new RegExp ( '^' + arg );
|
||||
} else {
|
||||
re = new RegExp ( '^' + shell.path +
|
||||
(( shell.path == '/' ) ? '' : '/' ) + arg );
|
||||
}
|
||||
|
||||
for ( var i=0; i < shell.json.directories.length; i++ )
|
||||
{
|
||||
var dir = shell.json.directories[i];
|
||||
|
||||
if ( dir.path.match ( re ))
|
||||
{
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !exists )
|
||||
{
|
||||
out = this.name + ": cannot access " + arg +
|
||||
": No such file or directory<br/>";
|
||||
} else {
|
||||
out = '';
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
}
|
||||
"cd",
|
||||
"ls",
|
||||
"man",
|
||||
"pwd",
|
||||
],
|
||||
}
|
||||
|
||||
|
|
50
commands/cd.json
Normal file
50
commands/cd.json
Normal file
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"name" : "cd",
|
||||
|
||||
"info" : {
|
||||
"syntax" : "cd <directory>",
|
||||
"brief" : "Change the current directory to the specified one",
|
||||
},
|
||||
|
||||
"action" : function ( arg )
|
||||
{
|
||||
var out = '';
|
||||
|
||||
if ( !arg || arg.length == 0 )
|
||||
{
|
||||
return "Parameter expected<br/>\n";
|
||||
}
|
||||
|
||||
arg = arg.replace ( /\/$/, '' );
|
||||
|
||||
if ( arg.match ( /^[^\/]/ ))
|
||||
{
|
||||
arg = this.path + '/' + arg;
|
||||
arg = arg.replace ( /\/+/, '/' );
|
||||
}
|
||||
|
||||
var found = false;
|
||||
|
||||
for ( var i=0; i < shell.json.directories.length && !found; i++ )
|
||||
{
|
||||
if ( shell.json.directories[i].path == arg )
|
||||
{
|
||||
found = true;
|
||||
|
||||
if ( shell.json.directories[i].type != 'directory' )
|
||||
{
|
||||
return "cd: not a directory: " + arg + "<br/>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !found )
|
||||
{
|
||||
return "cd: no such file or directory: " + arg + "<br/>\n";
|
||||
}
|
||||
|
||||
shell.path = arg;
|
||||
return out;
|
||||
},
|
||||
}
|
||||
|
152
commands/ls.json
Normal file
152
commands/ls.json
Normal file
|
@ -0,0 +1,152 @@
|
|||
{
|
||||
"name" : "ls",
|
||||
|
||||
"info" : {
|
||||
"syntax" : "ls [path]",
|
||||
"brief" : "List directory contents",
|
||||
},
|
||||
|
||||
"action" : function ( arg )
|
||||
{
|
||||
var dirs = new Array();
|
||||
var out = '';
|
||||
var exists = false;
|
||||
|
||||
arg = arg.replace ( /\/$/, '' );
|
||||
|
||||
if ( !arg || arg.length == 0 )
|
||||
{
|
||||
var re = new RegExp ( '^' + shell.path + '[^/]+$' );
|
||||
} else if ( arg && arg.length > 0 ) {
|
||||
var re = null;
|
||||
|
||||
if ( arg.match ( /^\// ))
|
||||
{
|
||||
re = new RegExp ( '^' + arg + '/[^/]+$' );
|
||||
} else {
|
||||
re = new RegExp ( '^' + shell.path +
|
||||
(( shell.path == '/' ) ? '' : '/' ) +
|
||||
arg + '/[^/]+$' );
|
||||
}
|
||||
}
|
||||
|
||||
for ( var i=0; i < shell.json.directories.length; i++ )
|
||||
{
|
||||
var dir = shell.json.directories[i];
|
||||
|
||||
if ( dir.path.match ( re ))
|
||||
{
|
||||
exists = true;
|
||||
dir.path.match ( /\/([^\/]+)$/ );
|
||||
dirs.push ({
|
||||
"path" : RegExp.$1,
|
||||
"type" : dir.type,
|
||||
"href" : dir.href,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if ( dirs.length > 0 )
|
||||
{
|
||||
var ordered = false;
|
||||
|
||||
// Directories go first
|
||||
while ( !ordered )
|
||||
{
|
||||
ordered = true;
|
||||
|
||||
for ( var i=0; i < dirs.length-1; i++ )
|
||||
{
|
||||
for ( var j=i+1; j < dirs.length; j++ )
|
||||
{
|
||||
if ( dirs[i].type == 'file' && dirs[j].type == 'directory' )
|
||||
{
|
||||
var tmp = dirs[i];
|
||||
dirs[i] = dirs[j];
|
||||
dirs[j] = tmp;
|
||||
ordered = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ordered = false;
|
||||
|
||||
// Sort the names
|
||||
while ( !ordered )
|
||||
{
|
||||
ordered = true;
|
||||
|
||||
for ( var i=0; i < dirs.length-1; i++ )
|
||||
{
|
||||
for ( var j=i+1; j < dirs.length; j++ )
|
||||
{
|
||||
if ( dirs[i].type == dirs[j].type && dirs[i].path > dirs[j].path )
|
||||
{
|
||||
var tmp = dirs[i];
|
||||
dirs[i] = dirs[j];
|
||||
dirs[j] = tmp;
|
||||
ordered = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( var i in dirs )
|
||||
{
|
||||
if ( dirs[i] )
|
||||
{
|
||||
if ( dirs[i].path.length > 0 )
|
||||
{
|
||||
if ( dirs[i].type == 'directory' )
|
||||
{
|
||||
out += '<span class="directory">' + dirs[i].path + '</span>/<br/>';
|
||||
} else {
|
||||
if ( dirs[i].href && dirs[i].href.length > 0 )
|
||||
{
|
||||
out += '<a href="' + dirs[i].href + '" class="file" target="_new">' + dirs[i].path + '</a>*<br/>';
|
||||
} else {
|
||||
out += '<span class="file">' + dirs[i].path + '</span><br/>';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !exists )
|
||||
{
|
||||
var re = null;
|
||||
|
||||
if ( arg.match ( /^\// ))
|
||||
{
|
||||
re = new RegExp ( '^' + arg );
|
||||
} else {
|
||||
re = new RegExp ( '^' + shell.path +
|
||||
(( shell.path == '/' ) ? '' : '/' ) + arg );
|
||||
}
|
||||
|
||||
for ( var i=0; i < shell.json.directories.length; i++ )
|
||||
{
|
||||
var dir = shell.json.directories[i];
|
||||
|
||||
if ( dir.path.match ( re ))
|
||||
{
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !exists )
|
||||
{
|
||||
out = this.name + ": cannot access " + arg +
|
||||
": No such file or directory<br/>";
|
||||
} else {
|
||||
out = '';
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
64
commands/man.json
Normal file
64
commands/man.json
Normal file
|
@ -0,0 +1,64 @@
|
|||
{
|
||||
"name" : "man",
|
||||
|
||||
"info" : {
|
||||
"syntax" : "man <page>",
|
||||
"brief" : "Display the manual page for the command 'page'",
|
||||
},
|
||||
|
||||
"action" : function ( arg ) {
|
||||
var out = '';
|
||||
|
||||
if ( arg == undefined || arg.length == 0 )
|
||||
{
|
||||
return "What manual page do you want?<br/>\n";
|
||||
}
|
||||
|
||||
var cmd = shell.json.commands;
|
||||
|
||||
if ( arg == 'blash' )
|
||||
{
|
||||
var commands = new Array();
|
||||
out = '<span class="brief">Type "<span class="syntax">man <command></span>" for a more detailed help on these commands</span><br/><br/>';
|
||||
|
||||
for ( var i=0; i < cmd.length; i++ )
|
||||
{
|
||||
commands.push ( cmd[i].info.syntax );
|
||||
}
|
||||
|
||||
commands.sort();
|
||||
|
||||
for ( var i in commands )
|
||||
{
|
||||
out += '<span class="syntax">' + commands[i] + '</span><br/>';
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
var found = false;
|
||||
|
||||
for ( var i=0; i < cmd.length && !found; i++ )
|
||||
{
|
||||
if ( arg == cmd[i].name )
|
||||
{
|
||||
if ( cmd[i].info.syntax.length > 0 && cmd[i].info.brief.length > 0 )
|
||||
{
|
||||
found = true;
|
||||
|
||||
out =
|
||||
'<span class="syntax">' + cmd[i].info.syntax + '</span><br/><br/>' +
|
||||
'<span class="brief">' + cmd[i].info.brief + '</span><br/>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !found )
|
||||
{
|
||||
return "No manual entry for " + arg + "<br/>\n";
|
||||
}
|
||||
|
||||
return out;
|
||||
},
|
||||
}
|
||||
|
23
commands/pwd.json
Normal file
23
commands/pwd.json
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"name" : "pwd",
|
||||
|
||||
"info" : {
|
||||
"syntax" : "pwd",
|
||||
"brief" : "Print name of current/working directory",
|
||||
},
|
||||
|
||||
"action" : function ( arg ) {
|
||||
if ( arg )
|
||||
{
|
||||
if ( arg.length > 0 )
|
||||
{
|
||||
return this.name + ": Too many arguments<br/>";
|
||||
} else {
|
||||
return shell.path + '<br/>';
|
||||
}
|
||||
} else {
|
||||
return shell.path + '<br/>';
|
||||
}
|
||||
},
|
||||
}
|
||||
|
Loading…
Reference in a new issue