From 099f0192a79c0b4b7c9dcaca8cc798f84f107569 Mon Sep 17 00:00:00 2001 From: BlackLight Date: Wed, 22 Dec 2010 02:28:45 +0100 Subject: [PATCH] Commands now managed like plugins --- blash.js | 41 ++++++-- blash.json | 242 +--------------------------------------------- commands/cd.json | 50 ++++++++++ commands/ls.json | 152 +++++++++++++++++++++++++++++ commands/man.json | 64 ++++++++++++ commands/pwd.json | 23 +++++ 6 files changed, 327 insertions(+), 245 deletions(-) create mode 100644 commands/cd.json create mode 100644 commands/ls.json create mode 100644 commands/man.json create mode 100644 commands/pwd.json diff --git a/blash.js b/blash.js index 6e2c3a9..fa27ef5 100644 --- a/blash.js +++ b/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 ); } } diff --git a/blash.json b/blash.json index 82aa1f3..2b42288 100644 --- a/blash.json +++ b/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
"; - } else { - return shell.path + '
'; - } - } else { - return shell.path + '
'; - } - }, - }, - - { - "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?
\n"; - } - - var cmd = shell.json.commands; - - if ( arg == 'blash' ) - { - var commands = new Array(); - out = 'Type "man <command>" for a more detailed help on these commands

'; - - for ( var i=0; i < cmd.length; i++ ) - { - commands.push ( cmd[i].info.syntax ); - } - - commands.sort(); - - for ( var i in commands ) - { - out += '' + commands[i] + '
'; - } - - 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 = - '' + cmd[i].info.syntax + '

' + - '' + cmd[i].info.brief + '
'; - } - } - } - - if ( !found ) - { - return "No manual entry for " + arg + "
\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 += '' + dirs[i].path + '/
'; - } else { - if ( dirs[i].href && dirs[i].href.length > 0 ) - { - out += '' + dirs[i].path + '*
'; - } else { - out += '' + dirs[i].path + '
'; - } - } - } - } - } - } - - 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
"; - } else { - out = ''; - } - } - - return out; - } - } + "cd", + "ls", + "man", + "pwd", ], } diff --git a/commands/cd.json b/commands/cd.json new file mode 100644 index 0000000..881bf44 --- /dev/null +++ b/commands/cd.json @@ -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
\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 + "
\n"; + } + } + } + + if ( !found ) + { + return "cd: no such file or directory: " + arg + "
\n"; + } + + shell.path = arg; + return out; + }, +} + diff --git a/commands/ls.json b/commands/ls.json new file mode 100644 index 0000000..d04d696 --- /dev/null +++ b/commands/ls.json @@ -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 += '' + dirs[i].path + '/
'; + } else { + if ( dirs[i].href && dirs[i].href.length > 0 ) + { + out += '' + dirs[i].path + '*
'; + } else { + out += '' + dirs[i].path + '
'; + } + } + } + } + } + } + + 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
"; + } else { + out = ''; + } + } + + return out; + } +} + diff --git a/commands/man.json b/commands/man.json new file mode 100644 index 0000000..e6d8e2f --- /dev/null +++ b/commands/man.json @@ -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?
\n"; + } + + var cmd = shell.json.commands; + + if ( arg == 'blash' ) + { + var commands = new Array(); + out = 'Type "man <command>" for a more detailed help on these commands

'; + + for ( var i=0; i < cmd.length; i++ ) + { + commands.push ( cmd[i].info.syntax ); + } + + commands.sort(); + + for ( var i in commands ) + { + out += '' + commands[i] + '
'; + } + + 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 = + '' + cmd[i].info.syntax + '

' + + '' + cmd[i].info.brief + '
'; + } + } + } + + if ( !found ) + { + return "No manual entry for " + arg + "
\n"; + } + + return out; + }, +} + diff --git a/commands/pwd.json b/commands/pwd.json new file mode 100644 index 0000000..67e0a98 --- /dev/null +++ b/commands/pwd.json @@ -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
"; + } else { + return shell.path + '
'; + } + } else { + return shell.path + '
'; + } + }, +} +