[Command] Creating Web-Based Terminals | jQuery Terminal Emulator

jQuery Terminal Emulator is a plugin for creating command-line compilers in your applications. It can automatically call JSON-RPC service when the user is typing commands or you can provide your own function with which you can analyze user commands.

How to make use of it:

Installation:

# NPM
$ npm install jquery.terminal

# Bower
$ bower install jquery.terminal

1. Include the jQuery JavaScript library and the terminal emulator plugin’s information on your web page.

<link href="css/jquery.terminal.min.css" rel="stylesheet" />
<script src="/path/to/cdn/jquery.min.js"></script>
<script src="js/jquery.terminal.min.js"></script>

2. Or from a CDN.

<link href="https://unpkg.com/jquery.terminal/css/jquery.terminal.min.css" rel="stylesheet" />
<script src="https://unpkg.com/jquery.terminal/js/jquery.terminal.min.js"></script>

3. Include the Mouse Wheel plugin for the mouse wheel help.

<script src="/path/to/jquery.mousewheel-min.js"></script>

4. Include the optionally available polyfills for legacy browsers.

<script src="https://unpkg.com/[email protected]/keyboard.js"></script>

5. Include optionally available extensions as per your needs.

<script src="js/ascii_table.js"></script>
<script src="js/autocomplete_menu.js"></script>
<script src="js/dterm.js"></script>
<script src="js/echo_newline.js"></script>
<script src="js/emoji.js"></script>
<script src="js/less.js"></script>
<script src="js/pipe.js"></script>
<script src="js/prism.js"></script>
<script src="js/unix_formatting.js"></script>
<script src="js/xml_formatting.js"></script>

6. Create a component for the terminal and generate a primary terminal utilizing the next JS codes.

jQuery(function($, undefined) {
  $('#example').terminal(function(command) {
      if (command !== '') {
          try {
              var result = window.eval(command);
              if (result !== undefined) {
                  this.echo(new String(result));
              }
          } catch(e) {
              this.error(new String(e));
          }
      } else {
         this.echo('');
      }
  }, {
     // options here
  });
});

7. Config the terminal with the next options and callbacks.

// you can set it to string or function with one parameter which is callback that must be called with string for your prompt (you can use ajax call to get prompt from the server
prompt: '> ',

// whether or not to store commands
history: true,

// if this option is set to false it don't use CTRL+D to exit from terminal and don't include 'exit' command
exit: true,

// whether or not to include 'clear' command
clear: true,

// enable/disable terminal
enabled: true,

// mask character
maskChar: '*',

// if set to false terminal will not wrap long lines (it can be overwritten by echo option)
wrap: true,

// if set to true it will check number of arguments in functions and in JSON-RPC if service return system.describe
checkArity: true,

// it will allow to display raw html
raw: false,

// tab index
tabindex: 1,

// enable using terminal and cmd methods in extended commands of echo
invokeMethods: false,

// executed instead of default print exception on terminal.
exceptionHandler: null,

// if set to false keypress, keydown and keymap will be executed when terminal is paused
pauseEvents: true,

// if set to true it will not hide command line when paused, usefull if you want to have progress animation using propmt
softPause: false,

// use localStorage nor Cookies and save everything in memory only
memory: false,

// cancelable AJAX requests
cancelableAjax: true,

// if set to true it will process arguments when using an object (replace regex with real regex object number with numbers and process escape characters in double quoted strings - like \x1b \033 will be Escape for ANSI codes) - default true
// if you pass function you can parse command line by yourself - it have one argument with string without name of the function and you need to return an array.
processArguments: true,

// whether or not to set noreferrer on links
linksNoReferrer: false,

// enable to enter links other than ftp or http(s) in echo
anyLinks: false,

// add nofolllow attribute to links
linksNoFollow: false,

// callback function that will be use with any result returned by JSON-RPC. So you can create better handler
processRPCResponse: null,

completionEscape: true,

// convert urls to tags
convertLinks: true,

// if set to true it will delete word when you hold key that should delete character e.g. delete or backspace key
mobileDelete: true,

// properties of this object are added to main interpreter 
extra: {},

// tab size
tabs: 4,

// used if you want to distinguish two or more terminals on one page or on one server
// if name them differently they will have different history and authentication
name: '',

// fixed number of rows and cols
numChars: null,
numRows: null,

// size of the history
historySize: 60,
scrollObject: null,

// whether or not to record all commands in url hash.
historyState: false,

// whether or not to import history in import_view exported by export_view
importHistory: false,

// if you return false in this function command will not be added into history.
historyFilter: null,

// if set to false terminal will not echo command you enter with prompt
echoCommand: true,

// indicate if terminals should scroll to bottom on echo or flush
// if set to false it will scroll to bottom if terminal was at the bottom
scrollOnEcho: true,

// can be function, string or boolean. 
// Function must have 3 arguments login password and callback which must be called with token (if login and password match) or falsy value (if authentication fail). 
// If interpreter is string with valid URI JSON-RPC service you can set login option to true (it will use login remote method) or name of RPC method. this in login function is terminal object.
login: null,

// If non negative it will limit the printing lines on terminal. 
If set to 0 it will print only lines that fit on one page (it will not create scrollbar if its enabled). 
outputLimit: -1,

// formatters
formatters: [$.terminal.nested_formatting],

// unix formatting API options
unixFormatting: {
  escapeBrackets: false,
  ansiParser: {},
  ansiArt: false
},

// enable image paste
pasteImage: true,

// indicate offset from bottom in which terminal will consider at bottom of the terminal
scrollBottomOffset: 20,

// if set to false it will autocomplete whole command before cursor, default set to true to autocomplete only word.
wordAutocomplete: true,
caseSensitiveAutocomplete: true,
caseSensitiveSearch: true,

// timeout in milliseconds
clickTimeout: 200,
holdTimeout: 400,
holdRepeatTimeout: 200,

repeatTimeoutKeys: ['HOLD+BACKSPACE'],
mobileIngoreAutoSpace: [],

// function executed when you press tab twice and there are more then one completion. 
// The function have 3 arguments completing string, array of completions and echo_command function. 
// If you pass false it will disable double tab.
doubleTab: null,

doubleTabEchoCommand: false,

// function with a callback that need to be executed with list of commands for tab completion (you need to pass array of commands to callback function)
// you can also use true (it will take completion from object or RPC, if it have system.describe, as interpreter) or array if you know what your commands are and don't need to call ajax to get them
completion: false,

// object where keys are uppercase shortcuts like CTRL+ALT+C and value is function execute on that shortcut
// the order of modifiers is CTRL, META, SHIFT, ALT
keymap: {},

request: $.noop, // parameters: jxhr, terminal, request
response: $.noop, // parameters: jxhr, terminal, response
processRPCResponse: null,
// It should be dot separated string that point to filed that have list of procedures, if you have normal JSON-RPC method you can use "result" or "result.procs". 
// It can be empty string it that case response will be taken as array of procedures. If the value is set to false it will not call system.describe method,
describe: 'procs',
keypress: $.noop,
keydown: $.noop,

// allowed attributes
allowedAttributes: ['title', /^aria-/, 'id', /^data-/],

// custom render handler
renderHandler: null,

// callbacks
onAfterCommand: $.noop, // parameter: command
onAfterLogout: $.noop, 
onAjaxError: null, // parameters: xhr, status, error
onBeforeCommand: $.noop, // parameter: command
onBeforeLogin: $.noop, , // parameter: terminal
onBeforeLogout: $.noop, 
onBeforeLogin: null,
onAfterLoginL null,
onBeforeEcho: null,
onAfterEcho: null,
onCommandNotFound: $.noop, // parameters: command, terminal
onInit: $.noop, // parameter: terminal
onClear: $.noop,
onBlur: $.noop,
onPause: $.noop,
onFocus: $.noop, // parameter: terminal
onTerminalChange: $.noop,
onExit: $.noop, // parameter: command
onResize: $.noop, // parameter: terminal
onResume: $.noop,
onExport: $.noop,
onImport: $.noop,
onPush: $.noop,
onPop: $.noop,
onRPCError: null,
onAfterRedraw: $.noop,
onEchoCommand: $.noop,
onCommandChange: null, // parameters: command, terminal
onPositionChange: null, // parameters: command, terminal
onFlush: $.noop,

// custom strings
strings: {
  comletionParameters: 'From version 1.0.0 completion function need to' +
      ' have two arguments',
  wrongPasswordTryAgain: 'Wrong password try again!',
  wrongPassword: 'Wrong password!',
  ajaxAbortError: 'Error while aborting ajax call!',
  wrongArity: "Wrong number of arguments. Function '%s' expects %s got" +
      ' %s!',
  commandNotFound: "Command '%s' Not Found!",
  oneRPCWithIgnore: 'You can use only one rpc with describe == false ' +
      'or rpc without system.describe',
  oneInterpreterFunction: "You can't use more than one function (rpc " +
      'without system.describe or with option describe == false count' +
       's as one)',
  loginFunctionMissing: "You didn't specify a login function",
  noTokenError: 'Access denied (no token)',
  serverResponse: 'Server responded',
  wrongGreetings: 'Wrong value of greetings parameter',
  notWhileLogin: "You can't call `%s' function while in login",
  loginIsNotAFunction: 'Authenticate must be a function',
  canExitError: "You can't exit from main interpreter",
  invalidCompletion: 'Invalid completion',
  invalidSelector: 'Sorry, but terminal said that you use invalid ' +
      'selector!',
  invalidTerminalId: 'Invalid Terminal ID',
  login: 'login',
  password: 'password',
  recursiveCall: 'Recursive call detected, skip',
  notAString: '%s function: argument is not a string',
  redrawError: 'Internal error, wrong position in cmd redraw',
  invalidStrings: 'Command %s have unclosed strings',
  defunctTerminal: "You can't call method on terminal that was destroyed"
}

8. API strategies.

// autologin if you get username and token in other way, like in sysend event.
instance.autologin([username, token])

// gets the string before the cursor
instance.before_cursor([boolean])

// if you pass string it will set name of the command line (name is use for tracking command line history) or if you call without argument it will return name.
instance.name([string])

// clears the terminal
instance.clear()

// clears saved history state
instance.clear_history_state()

// returns instance of history object.
instance.history()

// sets command line (optional parameter is is set to true will not change cursor position)
instance.set(string, [bool])

// inserts string to command line in place of the cursor if second argument is set to true it will not change position of the cursor
instance.insert(string, [bool])

// returns current command.
instance.get()

// returns number of characters and number of lines of the terminal
instance.cols()
instance.rows()

// utomplete text based on array
instance.complete([array, options])

// sets or gets function that will be called when user hit enter.
instance.commands([function])

// destroy the plugin
instance.destroy()

// moves virtual cursor to specied position or relative to curent position if second argument is true
instance.display_position([number], [boolean])

// sets prompt to function or string
// if called without argument it will return current prompt
instance.prompt([string|function])

// sets or gets position of the cursor
instance.position([number])

// sets numbers of characters
instance.resize([number])

// if argument is true it will mask all typed characters with provided string
// if called without argument it will return current mask.
instance.mask([string]) 

// displays string on terminal
instance.echo([string|function], [options])

// enable/disable the terminal
instance.enable()
instance.disable()

// displayes error string
instance.error([string|function])

// displays exception with stack trace on terminal 
instance.exception(Error, [Label])

// Executes command that like you where type it into terminal (it will execute user defined function). 
// second argument is optional if set to true, it will not display prompt and command that you execute. 
// If you want to have proper timing of executed function when commands are asynchronous (use ajax) then you need to call pause and resume (make sure that you call pause before ajax call and resume as last in ajax response).
instance.exec([string, bool])

// return object that can be use to restore the view using import_view.
instance.export_view()

// if you echo using option flush: false (it will not display text immediately) then you can send that text to the terminal output using this function.
instance.flush()

// it will activate next terminal if argument is false or disable previous terminal and activate current one
instance.focus([bool])

// disable/enable terminal that can't be enabled by clicking on terminal, frozen check if terminal has been frozen by freeze command.
instance.freeze([boolean])/frozen()

// get current command
instance.get_command()

// return string contains whatever was print on terminal, if argument is set to true it will return raw lines data.
instance.get_output([boolean])

// get current prompt
instance.get_prompt()

// same as token().
get_token([boolean])

// return command line History object
instance.history()

// disable or enable history sate save in hash. You can create commads that will start or stop the recording of commands, the commands itself will not be recorded.
instance.history_state([boolean])

// restore the view of the terminal using object returned prevoiusly by export_view.
instance.import_view([view])

// insert text in cursor position.
instance.insert(string)

// invoke shortcut, terminal.invoke_key('CTRL+L') will clear terminal.
instance.invoke_key([string])

// return true if terminal scroll is at the bottom. It use scrollBottomOffset option to calculate how much from bottom it will consider at bottom.
instance.is_bottom()

// return index of last line that can be use with update method after you echo something and you lost the reference using -1
instance.last_index()

// return how deeply nested in interpreters you correctly in (It start from 1).
instance.level()

// Execute login function the same as login option but first argument need to be a function. 
// The function will be called with 3 arguments, user, password and a function that need to be called with truthy value that will be stored as token. 
// Each interpreter can have it's own login function (you will need call push function and then login. 
// The token will be stored localy, you can get it passing true to token function. 
// Second argument indicate if terminal should ask for login and password infinitely.
instance.login([function(user, password, callback), boolean])

// return login name which was use in authentication. This is set to null if there is no login option.
instance.login_name()

// if you use authentication it will logout from terminal. If you don't set login option this function will throw exception.
instance.logout()

// return name of the interpreter.
instance.name()

// if you have more then one terminal instance it will switch to next terminal (in order of creation) and return reference to that terminal.
instance.next() 

// If your command will take some time to compute (like in AJAX call) you can pause terminal (terminal will be disable and command line will be hidden) and resume it in AJAX response is called. (if you want proper timing when call exec on array of commands you need to use those functions). 
// From version 0.11.1 pause accept optional boolean argument that indicate if command line should be visible (this can be used with animation).
instance.pause([boolean])/resume()

// return true if terminal is paused.
instance.paused()

// remove current interpreter from the stack and run previous one.
instance.pop()

// return name that is used for localStorage keys, if argument is true it will return name of local interpreter (added by push() method).
instance.prefix_name([boolean])

// remove all local storage left by terminal. 
// It will act like logout because it will remove login and token from local storage but you will not be logout until you refresh the page.
instance.purge()

// Push next interpreter on the stack and call that interpreter. 
// First argument is new interpreter (the same as first argument to terminal). 
// The second argument is a list of options as folow:
// name — to distinguish interpreters using command line history.
// prompt — new prompt for this terminal.
// onExit — callback function called on Exit.
// onStart — callback function called on Start.
// keydown — interpreter keydown event.
// historyFilter — the same as in terminal in next version.
// completion — the same as in terminal.
// login — same as login main option or calling login method after push.
// keymap — same as keymap in terminal.
// mousewheel — interpreter based mousewheel handler.
// infiniteLogin — if set to true it will ask infinetly for username and password if login is set.
instance.push([string|function], {object}) 

// wrapper over push, it set prompt to string and wait for text from user then call user function with entered string. 
// The function also return a promise that can be used interchangeably with callback functions. from version 1.16.0 read disable history.
instance.read([string, success_fn, cancel_fn])

// reset the terminal
instance.reset()

// resize the terminal
instance.resize([width, height]

// save current state of the terminal and update the hash
// if second argument is true it will not update hash.
instance.save_state([command, boolean])

// scroll the terminal
instance.scroll([number])

// scroll the terminal to the bottom
instance.scroll_to_bottom()

// set command
instance.set_command(string)

// override the current interpreter.
instance.set_interpreter([interpreter, login])

// toogle mask of command line if argument is true it will use maskChar as mask.
instance.set_mask([bool|string])

// change the prompt
instance.set_prompt([string|function(callback)])

// set prompt
instance.set_prompt([string|function])

// update token
instance.set_token([string, boolean])

// return settings object
instance.settings()

// return JQuery Singature depending on size of terminal.
instance.signature()

// return token which was set in authentication process or by calling login function. 
// This is set to null if there is no login option. If you pass true as an argument you will have local token for the interpreter (created using push function) it will return null if that interpreter don't have token.
instance.token([boolean])

// update line with specified number with given string. The line number can be negative (-1 will change last line) the lines are indexed from 0.
instance.update(line, string)

jQuery Command Line Interpreter Plugin, jQuery Terminal Emulator Plugin/Github


See Demo And Download

Official Website(jcubic): Click Here

This superior jQuery/javascript plugin is developed by jcubic. For extra Advanced Usages, please go to the official website.

Share