Commands now managed like plugins

This commit is contained in:
BlackLight 2010-12-22 02:28:45 +01:00
parent 7a10aa73c2
commit 099f0192a7
6 changed files with 327 additions and 245 deletions

View file

@ -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 );
}
}

View file

@ -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 &lt;page&gt;",
"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 &lt;command&gt;</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
View file

@ -0,0 +1,50 @@
{
"name" : "cd",
"info" : {
"syntax" : "cd &lt;directory&gt;",
"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
View 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
View file

@ -0,0 +1,64 @@
{
"name" : "man",
"info" : {
"syntax" : "man &lt;page&gt;",
"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 &lt;command&gt;</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
View 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/>';
}
},
}