1401 lines
48 KiB
Plaintext
1401 lines
48 KiB
Plaintext
**** mass:werk termlib.js - JS-WebTerminal Object v1.07 ****
|
|
|
|
(c) Norbert Landsteiner 2003-2005
|
|
mass:werk - media environments
|
|
<http://www.masswerk.at>
|
|
|
|
|
|
|
|
|
|
Contents:
|
|
|
|
1 About
|
|
2 Creating a new Terminal Instance
|
|
2.1 Configuration Values
|
|
3 Using the Terminal
|
|
3.1 The Default Handler
|
|
3.2 Input Modes
|
|
3.2.1 Normal Line Input (Command Line Mode)
|
|
3.2.1.2 Special Keys (ctrlHandler)
|
|
3.2.2 Raw Mode
|
|
3.2.3 Character Mode
|
|
3.3 Other Handlers
|
|
3.3.1 initHandler
|
|
3.3.2 exitHandler
|
|
3.4 Flags for Behaviour Control
|
|
4 Output Methods
|
|
4.1 Terminal.type()
|
|
4.2 Terminal.write()
|
|
4.3 Terminal.typeAt()
|
|
4.4 Terminal.setChar()
|
|
4.5 Terminal.newLine()
|
|
4.6 Terminal.clear()
|
|
4.7 Terminal.statusLine()
|
|
4.8 Terminal.printRowFromString()
|
|
4.9 Terminal.redraw()
|
|
5 Cursor Methods and Editing
|
|
5.1 Terminal.cursorOn()
|
|
5.2 Terminal.cursorOff()
|
|
5.3 Terminal.cursorSet()
|
|
5.4 Terminal.cursorLeft()
|
|
5.5 Terminal.cursorRight()
|
|
5.6 Terminal.backspace()
|
|
5.7 Terminal.fwdDelete()
|
|
5.8 Terminal.isPrintable()
|
|
6 Other Methods of the Terminal Object
|
|
6.1 Terminal.prompt()
|
|
6.2 Terminal.reset()
|
|
6.3 Terminal.open()
|
|
6.4 Terminal.close()
|
|
6.5 Terminal.focus()
|
|
6.6 Terminal.moveTo()
|
|
6.7 Terminal.resizeTo()
|
|
6.8 Terminal.getDimensions()
|
|
6.9 Terminal.rebuild()
|
|
7 Global Static Methods (TermGlobals)
|
|
7.1 TermGlobals.setFocus()
|
|
7.2 TermGlobals.keylock (Global Locking Flag)
|
|
7.3 TermGlobalsText Methods
|
|
7.3.1 TermGlobals.normalize()
|
|
7.3.2 TermGlobals.fillLeft()
|
|
7.3.3 TermGlobals.center()
|
|
7.3.4 TermGlobals.stringReplace()
|
|
8 Localization
|
|
9 Cross Browser Functions
|
|
10 Architecture, Internals
|
|
10.1 Global Entities
|
|
10.2 I/O Architecture
|
|
10.3 Compatibility
|
|
11 History
|
|
12 Example for a Command Line Parser
|
|
13 License
|
|
14 Disclaimer
|
|
15 References
|
|
|
|
|
|
|
|
|
|
1 About
|
|
|
|
The Terminal library "termlib.js" provides an object oriented constructor and control
|
|
methods for a terminal-like DHTML interface.
|
|
|
|
"termlib.js" features direct keyboard input and powerful output methods for multiple
|
|
instances of the `Terminal' object (including focus control).
|
|
|
|
The library was written with the aim of simple usage and a maximum of compatibility with
|
|
minimal foot print in the global namespace.
|
|
|
|
|
|
A simple example:
|
|
|
|
// creating a terminal and using it
|
|
|
|
var term = new Terminal( {handler: termHandler} );
|
|
term.open();
|
|
|
|
function termHandler() {
|
|
var line = this.lineBuffer;
|
|
this.newLine();
|
|
if (line == "help") {
|
|
this.write(helpPage)
|
|
}
|
|
else if (line == "exit") {
|
|
this.close();
|
|
return;
|
|
}
|
|
else if (line != "") {
|
|
this.write("You typed: "+line);
|
|
}
|
|
this.prompt();
|
|
}
|
|
|
|
var helpPage = [
|
|
"This is the monstrous help page for my groovy terminal.",
|
|
"Commands available:",
|
|
" help ... print this monstrous help page",
|
|
" exit ... leave this groovy terminal",
|
|
" ",
|
|
"Have fun!"
|
|
];
|
|
|
|
|
|
You should provide CSS font definitions for the classes ".term" (normal video) and
|
|
".termReverse" (reverse video) in a monospaced font.
|
|
A sample stylesheet "term_styles.css" comes with this library.
|
|
|
|
See the sample application "multiterm_test.html" for a demo of multiple terminals.
|
|
|
|
v.1.01: If you configure to use another font class (see 2.1 Configuration Values),
|
|
you must provide a subclass ".termReverse" for reversed video.
|
|
|
|
p.e.: .myFontClass .termReverse {
|
|
/* your definitions for reverse video here */
|
|
}
|
|
|
|
With the addition of `conf.fontClass' you can now create multiple
|
|
instances with independend appearences.
|
|
|
|
|
|
|
|
|
|
2 Creating a new Terminal Instance
|
|
|
|
Use the `new' constructor to create a new instance of the Terminal object. You will want
|
|
to supply a configuration object as an argument to the constructor. If the `new'
|
|
constructor is called without an object as its first argument, default values are used.
|
|
|
|
p.e.:
|
|
|
|
// creating a new instance of Terminal
|
|
|
|
var conf= {
|
|
x: 100,
|
|
y: 100,
|
|
cols: 80,
|
|
rows: 24
|
|
}
|
|
|
|
var term = new Term(conf);
|
|
term.open();
|
|
|
|
`Terminal.open()' initializes the terminal and makes it visible to the user.
|
|
This is handled in by separate method to allow the re-initilization of instances
|
|
previously closed.
|
|
|
|
NOTE:
|
|
The division element (or NS-layer) that holds the terminal must be present when calling
|
|
`Terminal.open()'. So you must not call this method from the header of a HTML-document at
|
|
compile time.
|
|
|
|
|
|
|
|
2.1 Configuration Values
|
|
|
|
Set any of these values in your configuration object to override:
|
|
|
|
|
|
LABEL DEFAULT VALUE COMMENT
|
|
|
|
x 100 terminal's position x in px
|
|
y 100 terminal's position y in px
|
|
divDiv 'termDiv' id of terminals CSS division
|
|
bgColor '#181818' background color (HTML hex value)
|
|
frameColor '#555555' frame color (HTML hex value)
|
|
frameWidth 1 frame border width in px
|
|
fontClass 'term' class name of CSS font definition to use
|
|
cols 80 number of cols per row
|
|
rows 24 number of rows
|
|
rowHeight 15 a row's line-height in px
|
|
blinkDelay 500 delay for cursor blinking in milliseconds
|
|
crsrBlinkMode false true for blinking cursor
|
|
crsrBlockMode true true for block-cursor else underscore
|
|
DELisBS false handle <DEL> as <BACKSPACE>
|
|
printTab true handle <TAB> as printable (prints as space)
|
|
printEuro true handle unicode 0x20AC (Euro sign) as printable
|
|
catchCtrlH true handle ^H as <BACKSPACE>
|
|
closeOnESC true close terminal on <ESC>
|
|
historyUnique false prevent consecutive and identical entries in history
|
|
id 0 terminal id
|
|
ps '>' prompt string
|
|
greeting '%+r Terminal ready. %-r' string for greeting if no initHandler is used
|
|
handler termDefaultHandler reference to handler for command interpretation
|
|
ctrlHandler null reference to handler called on uncatched special keys
|
|
initHandler null reference to handler called at end of init()
|
|
exitHandler null reference to handler called on close()
|
|
|
|
|
|
At least you will want to specify `handler' to implement your own command parser.
|
|
|
|
Note: While `id' is not used by the Termninal object, it provides an easy way to identify
|
|
multiple terminals by the use of "this.id". (e.g.: "if (this.id == 1) startupterm = true;")
|
|
|
|
p.e.:
|
|
|
|
// creating two individual Terminal instances
|
|
|
|
var term1 = new Terminal(
|
|
{
|
|
id: 1,
|
|
x: 200,
|
|
y: 10,
|
|
cols: 80,
|
|
rows: 12,
|
|
greeting: "*** This is Terminal 1 ***",
|
|
handler: myTerminalHandler
|
|
}
|
|
);
|
|
term1.open();
|
|
|
|
var term2 = new Terminal(
|
|
{
|
|
id: 2,
|
|
x, 200,
|
|
y: 220,
|
|
cols: 80
|
|
rows: 12,
|
|
greeting: "*** This is Terminal 2 ***",
|
|
handler: myTerminalHandler
|
|
}
|
|
);
|
|
term2.open();
|
|
|
|
|
|
|
|
|
|
3 Using the Terminal
|
|
|
|
There are 4 different handlers that are called by a Terminal instance to process input and
|
|
some flags to control the input mode and behaviour.
|
|
|
|
|
|
|
|
3.1 The Default Handler (a simlple example for input handling)
|
|
|
|
If no handlers are defined in the configuration object, a default handler is called to
|
|
handle a line of user input. The default command line handler `termDefaultHandler' just
|
|
closes the command line with a new line and echos the input back to the user:
|
|
|
|
function termDefaultHandler() {
|
|
this.newLine();
|
|
if (this.lineBuffer != '') {
|
|
this.type('You typed: '+this.lineBuffer);
|
|
this.newLine();
|
|
}
|
|
this.prompt();
|
|
}
|
|
|
|
First you may note that the instance is refered to as `this'. So you need not worry about
|
|
which Terminal instance is calling your handler. As the handler is entered, the terminal
|
|
is locked for user input and the cursor is off. The current input is available as a string
|
|
value in `this.lineBuffer'.
|
|
|
|
The method `type(<text>)' just does what it says and types a string at the current cursor
|
|
position to the terminal screen.
|
|
|
|
`newLine()' moves the cursor to a new line.
|
|
|
|
The method `prompt()' adds a new line if the cursor isn't at the start of a line, outputs
|
|
the prompt string (as specified in the configuration), activates the cursor, and unlocks
|
|
the terminal for further input. While you're doing normal command line processing, always
|
|
call `prompt()' when leaving your handler.
|
|
|
|
In fact this is all you need to create your own terminal application. Please see at least
|
|
the method `write()' for a more powerful output method.
|
|
|
|
Below we will refer to all methods of the Terminal object as `Terminal.<method>()'.
|
|
You can call them as `this.<method>()' in a handler or as methods of your named instance
|
|
in other context (e.g.: "myTerminal.close()").
|
|
|
|
[In technical terms these methods are methods of the Terminal's prototype object, while
|
|
the properties are properties of a Termninal instance. Since this doesn't make any
|
|
difference to your script, we'll refer to both as `Terminal.<method-or-property>'.]
|
|
|
|
|
|
|
|
3.2 Input Modes
|
|
|
|
3.2.1 Normal Line Input (Command Line Mode)
|
|
|
|
By default the terminal is in normal input mode. Any printable characters in the range of
|
|
ASCII 0x20 - 0xff are echoed to the terminal and may be edited with the use of the cursor
|
|
keys and the <BACKSPACE> key.
|
|
The cursor keys UP and DOWN let the user browse in the command line history (the list of
|
|
all commands issued previously in this Terminal instance).
|
|
|
|
If the user presses <CR> or <ENTER>, the line is read from the terminal buffer, converted
|
|
to a string, and placed in `Terminal.lineBuffer' (-> `this.lineBuffer') for further use.
|
|
The terminal is then locked for further input and the specified handler
|
|
(`Terminal.handler') is called.
|
|
|
|
|
|
3.2.1.2 Special Keys (ctrlHandler)
|
|
|
|
If a special character (ASCII<0x20) or an according combination of <CTRL> and a key is
|
|
pressed, which is not caught for editing or "enter", and a handler for `ctrlHandler' is
|
|
specified, this handler is called.
|
|
The ASCII value of the special character is available in `Terminal.inputChar'. Please note
|
|
that the terminal is neither locked, nor is the cursor off - all further actions have to
|
|
be controlled by `ctrlHandler'. (The tracking of <CTRL>-<key> combinations as "^C" usually
|
|
works but cannot be taken for granted.)
|
|
|
|
A named reference of the special control values in POSIX form (as well as the values of
|
|
the cursor keys [LEFT, RIGHT, UP, DOWN]) is available in the `termKey' object.
|
|
|
|
p.e.:
|
|
|
|
// a simple ctrlHandler
|
|
|
|
function myCtrlHandler() {
|
|
if (this.inputChar == termKey.ETX) {
|
|
// exit on ^C (^C == ASCII 0x03 == <ETX>)
|
|
this.close();
|
|
}
|
|
}
|
|
|
|
If no `ctrlHandler' is specified, control keys are ignored (default).
|
|
|
|
|
|
3.2.2 Raw Mode
|
|
|
|
If the flag `Terminal.rawMode' is set to a value evaluating to `true', no special keys are
|
|
tracked but <CR> and <ENTER> (and <ESC>, if the flag `Terminal.closeOnESC' is set).
|
|
The input is NOT echoed to the terminal. All printable key values [0x20-0xff] are
|
|
transformed to characters and added to `Terminal.lineBuffer' sequentially. The command
|
|
line input is NOT added to the history.
|
|
|
|
This mode is especially suitable for password input.
|
|
|
|
p.e.:
|
|
|
|
// using raw mode for password input
|
|
|
|
function myTermHandler() {
|
|
this.newLine();
|
|
// we stored a flag in Terminal.env to track the status
|
|
if (this.env.getpassword) {
|
|
// leave raw mode
|
|
this.rawMode = false;
|
|
if (passwords[this.env.user] == this.lineBuffer) {
|
|
// matched
|
|
this.type('Welcome '+this.env.user);
|
|
this.env.loggedin = true;
|
|
}
|
|
else {
|
|
this.type('Sorry.');
|
|
}
|
|
this.env.getpassword = false;
|
|
}
|
|
else {
|
|
// simple parsing
|
|
var args = this.lineBuffer.split(' ');
|
|
var cmd = args[0];
|
|
if (cmd == 'login') {
|
|
var user = args[1];
|
|
if (!user) {
|
|
this.type('usage: login <username>');
|
|
}
|
|
else {
|
|
this.env.user = user;
|
|
this.env.getpassword = true;
|
|
this.type('password? ');
|
|
// enter raw mode
|
|
this.rawMode = true;
|
|
// leave without prompt so we must unlock first
|
|
this.lock = false;
|
|
return;
|
|
}
|
|
}
|
|
/*
|
|
other actions ...
|
|
*/
|
|
}
|
|
this.prompt();
|
|
}
|
|
|
|
In this example a handler is set up to process the command "login <username>" and ask for
|
|
a password for the given user name in raw mode. Note the use of the object `Terminal.env'
|
|
which is just an empty object set up at the creation of the Terminal instance. Its only
|
|
purpose is to provide an individual namespace for private data to be stored by a Terminal
|
|
instance.
|
|
|
|
NOTE: The flag `Terminal.lock' is used to control the keyboard locking. If we would not
|
|
set this to `false' before leaving in raw mode, we would be caught in dead-lock, since no
|
|
input could be entered and our handler wouldn't be called again. - A dreadful end of our
|
|
terminal session.
|
|
|
|
NOTE: Raw mode utilizes the property `Terminal.lastLine' to collect the input string.
|
|
This is normally emty, when a handler is called. This is not the case if your script left
|
|
the input process on a call of ctrlHandler. You should clear `Terminal.lastLine' in such
|
|
a case, if you're going to enter raw mode immediatly after this.
|
|
|
|
|
|
3.2.3 Character Mode
|
|
|
|
If the flag `Terminal.charMode' is set to a value evaluating to `true', the terminal is in
|
|
character mode. In this mode the numeric ASCII value of the next key typed is stored in
|
|
`Terminal.inputChar'. The input is NOT echoed to the terminal. NO locking or cursor
|
|
control is performed and left to the handler.
|
|
You can use this mode to implement your editor or a console game.
|
|
`Terminal.charMode' takes precedence over `Terminal.rawMode'.
|
|
|
|
p.e.:
|
|
|
|
// using char mode
|
|
|
|
function myTermHandler() {
|
|
// this is the normal handler
|
|
this.newLine();
|
|
// simple parsing
|
|
var args = this.lineBuffer.split(' ');
|
|
var cmd = args[0];
|
|
if (cmd == 'edit') {
|
|
// init the editor
|
|
myEditor(this);
|
|
// redirect the handler to editor
|
|
this.handler = myEditor;
|
|
// leave in char mode
|
|
this.charMode = true;
|
|
// show cursor
|
|
this.cursorOn();
|
|
// don't forget unlocking
|
|
this.lock = false;
|
|
return;
|
|
}
|
|
/*
|
|
other actions ...
|
|
*/
|
|
this.prompt();
|
|
}
|
|
|
|
function myEditor(initterm) {
|
|
// our dummy editor (featuring modal behaviour)
|
|
if (initterm) {
|
|
// perform initialization tasks
|
|
initterm.clear();
|
|
initterm.write('this is a simple test editor; leave with <ESC> then "q"%n%n');
|
|
initterm.env.mode = '';
|
|
// store a reference of the calling handler
|
|
initterm.env.handler = initterm.handler;
|
|
return;
|
|
}
|
|
// called as handler -> lock first
|
|
this.lock=true;
|
|
// hide cursor
|
|
this.cursorOff();
|
|
var key = this.inputChar;
|
|
if (this.env.mode == 'ctrl') {
|
|
// control mode
|
|
if (key == 113) {
|
|
// "q" => quit
|
|
// leave charMode and reset the handler to normal
|
|
this.charMode = false;
|
|
this.handler = this.env.handler;
|
|
// clear the screen
|
|
this.clear();
|
|
// prompt and return
|
|
this.prompt();
|
|
return;
|
|
}
|
|
else {
|
|
// leave control mode
|
|
this.env.mode = '';
|
|
}
|
|
}
|
|
else {
|
|
// edit mode
|
|
if (key == termKey.ESC) {
|
|
// enter control mode
|
|
// we'd better indicate this in a status line ...
|
|
this.env.mode = 'ctrl';
|
|
}
|
|
else if (key == termKey.LEFT) {
|
|
// cursor left
|
|
}
|
|
else if (key == termKey.RIGHT) {
|
|
// cursor right
|
|
}
|
|
if (key == termKey.UP) {
|
|
// cursor up
|
|
}
|
|
else if (key == termKey.DOWN) {
|
|
// cursor down
|
|
}
|
|
else if (key == termKey.CR) {
|
|
// cr or enter
|
|
}
|
|
else if (key == termKey.BS) {
|
|
// backspace
|
|
}
|
|
else if (key == termKey.DEL) {
|
|
// fwd delete
|
|
// conf.DELisBS is not evaluated in charMode!
|
|
}
|
|
else if (this.isPrintable(key)) {
|
|
// printable char - just type it
|
|
var ch = String.fromCharCode(key);
|
|
this.type(ch);
|
|
}
|
|
}
|
|
// leave unlocked with cursor
|
|
this.lock = false;
|
|
this.cursorOn();
|
|
}
|
|
|
|
|
|
Note the redirecting of the input handler to replace the command line handler by the
|
|
editor. The method `Terminal.clear()' clears the terminal.
|
|
`Terminal.cursorOn()' and `Terminal.cursorOff()' are used to show and hide the cursor.
|
|
|
|
|
|
|
|
3.3 Other Handlers
|
|
|
|
There are two more handlers that can be specified in the configuration object:
|
|
|
|
|
|
3.3.1 initHandler
|
|
|
|
`initHandler' is called at the end of the initialization triggered by `Terminal.open()'.
|
|
The default action - if no `initHandler' is specified - is:
|
|
|
|
// default initilization
|
|
|
|
this.write(this.conf.greeting);
|
|
this.newLine();
|
|
this.prompt();
|
|
|
|
Use `initHandler' to perform your own start up tasks (e.g. show a start up screen). Keep
|
|
in mind that you should unlock the terminal and possibly show a cursor to give the
|
|
impression of a usable terminal.
|
|
|
|
|
|
3.3.2 exitHandler
|
|
|
|
`exitHandler' is called by `Terminal.close()' just before hiding the terminal. You can use
|
|
this handler to implement any tasks to be performed on exit. Note that this handler is
|
|
called even if the terminal is closed on <ESC> outside of your inputHandlers control.
|
|
|
|
See the file "multiterm_test.html" for an example.
|
|
|
|
|
|
|
|
3.4 Overview: Flags for Behaviour Control
|
|
|
|
These falgs are accessible as `Terminal.<flag>' at runtime. If not stated else, the
|
|
initial value may be specified in the configuration object.
|
|
The configuration object and its properties are accessible at runtime via `Terminal.conf'.
|
|
|
|
|
|
NAME DEFAULT VALUE MEANING
|
|
|
|
blink_delay 500 delay for cursor blinking in milliseconds.
|
|
|
|
crsrBlinkMode false true for blinking cursor.
|
|
if false, cursor is static.
|
|
|
|
crsrBlockMode true true for block-cursor else underscore.
|
|
|
|
DELisBS false handle <DEL> as <BACKSPACE>.
|
|
|
|
printTab true handle <TAB> as printable (prints as space)
|
|
if false <TAB> is handled as a control character
|
|
|
|
printEuro true handle the euro sign as valid input char.
|
|
if false char 0x20AC is printed, but not accepted
|
|
in the command line
|
|
|
|
catchCtrlH true handle ^H as <BACKSPACE>.
|
|
if false, ^H must be tracked by a custom
|
|
ctrlHandler.
|
|
|
|
closeOnESC true close terminal on <ESC>.
|
|
if true, <ESC> is not available for ctrHandler.
|
|
|
|
|
|
historyUnique false unique history entries.
|
|
if true, entries that are identical to the last
|
|
entry in the user history will not be added.
|
|
|
|
charMode false terminal in character mode (tracks next key-code).
|
|
(runtime only)
|
|
|
|
rawMode false terminal in raw mode (no echo, no editing).
|
|
(runtime only)
|
|
|
|
|
|
Not exactly a flag but useful:
|
|
|
|
ps '>' prompt string.
|
|
|
|
|
|
|
|
|
|
4 Output Methods
|
|
|
|
Please note that any output to the terminal implies an advance of the cursor. This means,
|
|
that if your output reaches the last column of your terminal, the cursor is advanced and
|
|
a new line is opened automatically. This procedure may include scrolling to make room for
|
|
the new line. While this is not of much interest for most purposes, please note that, if
|
|
you output a string of length 80 to a 80-columns-terminal, and a new line, and another
|
|
string, this will result in an empty line between the two strings.
|
|
|
|
|
|
4.1 Terminal.type( <text> [,<stylevector>] )
|
|
|
|
Types the string <text> at the current cursor position to the terminal. Long lines are
|
|
broken where the last column of the terminal is reached and continued in the next line.
|
|
`Terminal.write()' does not support any kind of arbitrary line breaks. (This is just a
|
|
basic output routine. See `Terminal.write()' for a more powerful output method.)
|
|
|
|
A bitvector may be supplied as an optional second argument to represent a style or a
|
|
combination of styles. The meanings of the bits set are interpreted as follows:
|
|
|
|
<stylevector>:
|
|
|
|
1 ... reverse (2 power 0)
|
|
2 ... underline (2 power 1)
|
|
4 ... italics (2 power 2)
|
|
8 ... strike (2 power 3)
|
|
|
|
So "Terminal.type( 'text', 5 )" types "text" in italics and reverse video.
|
|
|
|
Note:
|
|
There is no bold, for most monospaced fonts (including Courier) tend to render wider in
|
|
bold. Since this would bring the terminal's layout out of balance, we just can't use bold
|
|
as a style. - Sorry.
|
|
|
|
The HTML-representation of this styles are defined in "TermGlobals.termStyleOpen" and
|
|
"TermGlobals.termStyleClose".
|
|
|
|
|
|
4.2 Terminal.write( <text> [,<usemore>] )
|
|
|
|
Writes a text with markup to the terminal. If an optional second argument evaluates to
|
|
true, a UN*X-style utility like `more' is used to page the text. The text may be supplied
|
|
as a single string (with newline character "\n") or as an array of lines. Any other input
|
|
is transformed to a string value before output.
|
|
|
|
4.2.1 Mark-up:
|
|
|
|
`Terminal.write()' employs a simple mark-up with the following syntax:
|
|
|
|
<markup>: %([+|-]<style>|n|CS|%)
|
|
|
|
where "+" and '-' are used to switch on and off a style, where
|
|
|
|
<style>:
|
|
|
|
"i" ... italics
|
|
"r" ... reverse
|
|
"s" ... strike
|
|
"u" ... underline
|
|
|
|
"p" ... reset to plain ("%+p" == "%-p")
|
|
|
|
styles may be combined and may overlap. (e.g. "This is %+rREVERSE%-r, %+uUNDER%+iSCORE%-u%-i.")
|
|
|
|
"%n" represents a new line (in fact "\n" is translated to "%n" before processing)
|
|
|
|
"%CS" clears the terminal screen
|
|
|
|
"%%" represents the percent character ('%')
|
|
|
|
|
|
4.2.2 Buffering:
|
|
|
|
`Terminal.write()' writes via buffered output to the terminal. This means that the
|
|
provided text is rendered to a buffer first and then only the visible parts are transfered
|
|
to the terminal display buffers. This avoids scrolling delays for long output.
|
|
|
|
4.2.3 UseMore Mode:
|
|
|
|
The buffering of `Terminal.write()' allows for pagewise output, which may be specified by
|
|
a second boolean argument. If <usemore> evaluates to `true' and the output exceeds the
|
|
range of empty rows on the terminal screen, `Terminal.write()' performs like the UN*X
|
|
utility `more'. The next page may be accessed by hitting <SPACE> while <q> terminates
|
|
paging and returns with the prompt (-> `Terminal.prompt()').
|
|
|
|
To use this facillity make sure to return immediatly after calling `Terminal.write()' in
|
|
order to allow the more-routine to track the user input.
|
|
The terminal is set to "charMode == false" afterwards.
|
|
|
|
p.e.:
|
|
|
|
// using Terminal.write as a pager
|
|
|
|
function myTermHandler() {
|
|
this.newLine();
|
|
var args = this.lineBuffer.split(' ');
|
|
var cmd = args[0];
|
|
if (cmd == 'more') {
|
|
var page = args[1];
|
|
if (myPages[page]) {
|
|
// Terminal.write as a pager
|
|
this.write(myPages[page], true);
|
|
return;
|
|
}
|
|
else {
|
|
// Terminal.write for simple output
|
|
this.write('no such page.');
|
|
}
|
|
}
|
|
/*
|
|
other actions ...
|
|
*/
|
|
this.prompt();
|
|
}
|
|
|
|
|
|
4.3 Terminal.typeAt( <r>, <c>, <text> [,<stylevector>] )
|
|
|
|
Output the string <text> at row <r>, col <c>.
|
|
For <stylevector> see `Terminal.type()'.
|
|
`Terminal.typeAt()' does not move the cursor.
|
|
|
|
|
|
4.4 Terminal.setChar( <charcode>, <r>, <c> [,<stylevector>] )
|
|
|
|
Output a single character represented by the ASCII value of <charcode> at row <r>, col <c>.
|
|
For <stylevector> see `Terminal.type()'.
|
|
|
|
|
|
4.5 Terminal.newLine()
|
|
|
|
Moves the cursor to the first column of the next line and performs scrolling, if needed.
|
|
|
|
|
|
4.6 Terminal.clear()
|
|
|
|
Clears the terminal screen. (Returns with cursor off.)
|
|
|
|
|
|
4.7 Terminal.statusLine( <text> [,<stylevector> [,<lineoffset>]] )
|
|
|
|
All output acts on a logical screen with the origin at row 0 / col 0. While the origin is
|
|
fixed, the logical width and height of the terminal are defined by `Terminal.maxCols' and
|
|
`Terminal.maxLines'. These are set to the configuration dimensions at initilization and by
|
|
`Terminal.reset()', but may be altered at any moment. Please note that there are no bounds
|
|
checked, so make sure that `Terminal.maxCols' and `Terminal.maxLines' are less or equal
|
|
to the configuration dimensions.
|
|
|
|
You may want to decrement `Terminal.maxLines' to keep space for a reserved status line.
|
|
`Terminal.statusLine( <text>, <style> )' offers a simple way to type a text to the last
|
|
line of the screen as defined by the configuration dimensions.
|
|
|
|
// using statusLine()
|
|
|
|
function myHandler() {
|
|
// ...
|
|
// reserve last line
|
|
this.maxLines = term.conf.rows-1;
|
|
// print to status line in reverse video
|
|
this.statusLine("Status: <none>", 1);
|
|
// ...
|
|
}
|
|
|
|
For multiple status lines the optional argument <lineoffset> specifies the addressed row,
|
|
where 1 is the line closest to the bottom, 2 the second line from the bottom and so on.
|
|
(default: 1)
|
|
|
|
|
|
4.8 Terminal.printRowFromString( <r> , <text> [,<stylevector>] )
|
|
|
|
Outputs the string <text> to row <r> in the style of an optional <stylevector>.
|
|
If the string's length exceeds the length of the row (up to `Terminal.conf.cols'), extra
|
|
characteres are ignored, else any extra space is filled with character code 0 (prints as
|
|
<SPACE>).
|
|
The valid range for <row> is: 0 >= <row> < `Terminal.maxLines'.
|
|
`Terminal.printRowFromString()' does not set the cursor.
|
|
|
|
You could, for example, use this method to output a line of a text editor's buffer.
|
|
|
|
p.e.:
|
|
|
|
// page refresh function of a text editor
|
|
|
|
function myEditorRefresh(termref, topline) {
|
|
// termref: reference to Terminal instance
|
|
// topline: index of first line to print
|
|
// lines of text are stored in termref.env.lines
|
|
for (var r=0; r<termref.maxLines; r++) {
|
|
var i = topline + r;
|
|
if (i < termref.env.lines.length) {
|
|
// output stored line
|
|
termref.printRowFromString(r, termref.env.lines[i]);
|
|
}
|
|
else {
|
|
// output <tilde> for empty line
|
|
termref.printRowFromString(r, '~');
|
|
}
|
|
}
|
|
// set cursor to origin
|
|
termref.r = termref.c = 0; // same as termref.cursorSet(0, 0);
|
|
}
|
|
|
|
|
|
4.9 Terminal.redraw( <row> )
|
|
|
|
Basic function to redraw a terminal row <row> according to screen buffer values.
|
|
For hackers only. (e.g.: for a console game, hack screen buffers first and redraw all
|
|
changed rows at once.)
|
|
|
|
|
|
|
|
|
|
5 Cursor Methods and Editing
|
|
|
|
|
|
5.1 Terminal.cursorOn()
|
|
|
|
Show the cursor.
|
|
|
|
|
|
5.2 Terminal.cursorOff()
|
|
|
|
Hide the cursor.
|
|
|
|
|
|
5.3 Terminal.cursorSet( <r>, <c> )
|
|
|
|
Set the cursor position to row <r> column <c>.
|
|
`Terminal.cursorSet()' preserves the cursor's active state (on/off).
|
|
|
|
|
|
5.4 Terminal.cursorLeft()
|
|
|
|
Move the cursor left. (Movement is restricted to the logical input line.)
|
|
`Terminal.cursorLeft()' preserves the cursor's active state (on/off).
|
|
|
|
|
|
5.5 Terminal.cursorRight()
|
|
|
|
Move the cursor right. (Movement is restricted to the logical input line.)
|
|
`Terminal.cursorRight()' preserves the cursor's active state (on/off).
|
|
|
|
|
|
5.6 Terminal.backspace()
|
|
|
|
Delete the character left from the cursor, if the cursor is not in first position of the
|
|
logical input line.
|
|
`Terminal.backspace()' preserves the cursor's active state (on/off).
|
|
|
|
|
|
5.7 Terminal.fwdDelete()
|
|
|
|
Delete the character under the cursor.
|
|
`Terminal.fwdDelete()' preserves the cursor's active state (on/off).
|
|
|
|
|
|
5.8 Terminal.isPrintable( <key code> [,<unicode page 1 only>] )
|
|
|
|
Returns `true' if the character represented by <key code> is printable with the current
|
|
settings. An optional second argument <unicode page 1 only> limits the range of valid
|
|
values to 255 with the exception of the Euro sign, if the flag `Terminal.printEuro' is set.
|
|
(This second flag is used for input methods but not for output methods. So you may only
|
|
enter portable characters, but you may print others to the terminals screen.)
|
|
|
|
|
|
|
|
|
|
6 Other Methods of the Terminal Object
|
|
|
|
6.1 Terminal.prompt()
|
|
|
|
Performes the following actions:
|
|
|
|
* advance the cursor to a new line, if the cursor is not at 1st column
|
|
* type the prompt string (as specified in the configuaration object)
|
|
* show the cursor
|
|
* unlock the terminal
|
|
|
|
(The value of the prompt string can be accessed and changed in `Terminal.ps'.)
|
|
|
|
|
|
6.2 Terminal.reset()
|
|
|
|
Resets the terminal to sane values and clears the terminal screen.
|
|
|
|
|
|
6.3 Terminal.open()
|
|
|
|
Opens the terminal. If this is a fresh instance, the HTML code for the terminal is
|
|
generated. On re-entry the terminal's visibility is set to `true'. Initialization tasks
|
|
are performed and the optional initHandler called. If no initHandler is specified in the
|
|
configuration object, the greeting (configuration or default value) is shown and the user
|
|
is prompted for input.
|
|
|
|
v.1.01: `Terminal.open()' now checks for the existence of the DHTML element as defined in
|
|
`Terminal.conf.termDiv' and returns success.
|
|
|
|
|
|
6.4 Terminal.close()
|
|
|
|
Closes the terminal and hides its visibility. An optional exitHandler (specified in the
|
|
configuration object) is called, and finally the flag `Terminal.closed' is set to true. So
|
|
you can check for existing terminal instances as you would check for a `window' object
|
|
created by `window.open()'.
|
|
|
|
p.e.:
|
|
|
|
// check for a terminals state
|
|
// let array "term" hold references to terminals
|
|
|
|
if (term[n]) {
|
|
if (term[n].closed) {
|
|
// terminal exists and is closed
|
|
// re-enter via "term[n].open()"
|
|
}
|
|
else {
|
|
// terminal exists and is currently open
|
|
}
|
|
}
|
|
else {
|
|
// no such terminal
|
|
// create it via "term[n] = new Terminal()"
|
|
}
|
|
|
|
|
|
6.5 Terminal.focus()
|
|
|
|
Set the keyboard focus to this instance of Terminal. (As `window.focus()'.)
|
|
|
|
|
|
6.6 Terminal.moveTo( <x>, <y> )
|
|
|
|
Move the terminal to position <x>/<y> in px.
|
|
(As `window.moveTo()', but inside the HTML page.)
|
|
|
|
|
|
6.7 Terminal.resizeTo( <x>, <y> )
|
|
|
|
Resize the terminal to dimensions <x> cols and <y> rows.
|
|
<x> must be at least 4, <y> at least 2.
|
|
`Terminal.resizeTo()' resets `Terminal.conf.rows', `Terminal.conf.cols',
|
|
`Terminal.maxLines', and `Terminal.maxCols' to <y> and <x>, but leaves the instance' state
|
|
else unchanged. Clears the terminal's screen and returns success.
|
|
|
|
(A bit like `window.resizeTo()', but with rows and cols instead of px.)
|
|
|
|
|
|
6.8 Terminal.getDimensions()
|
|
|
|
Returns an object with properties "width" and "height" with numeric values for the
|
|
terminal's outer dimensions in px. Values are zero (0) if the element is not present or
|
|
if the method fails otherwise.
|
|
|
|
|
|
6.9 Terminal.rebuild()
|
|
|
|
Rebuilds the Terminal object's GUI preserving its state and content.
|
|
Use this to change the color theme on the fly.
|
|
|
|
p.e.:
|
|
|
|
// change color settings on the fly
|
|
// here: set bgColor to white and font style to "termWhite"
|
|
// method rebuild() updates the GUI without side effects
|
|
|
|
term.conf.bgColor = '#ffffff';
|
|
term.conf.fontClass = 'termWhite';
|
|
term.rebuild();
|
|
|
|
|
|
|
|
|
|
7 Global Static Methods (TermGlobals)
|
|
|
|
|
|
7.1 TermGlobals.setFocus( <termref> )
|
|
|
|
Sets the keyboard focus to the instance referenced by <termref>.
|
|
The focus is controlled by `TermGlobals.activeTerm' which may be accessed directly.
|
|
See also: `Terminal.focus()'
|
|
|
|
|
|
7.2 TermGlobals.keylock (Global Locking Flag)
|
|
|
|
The global flag `TermGlobals.keylock' allows temporary keyboard locking without any
|
|
other change of state. Use this to free the keyboard for any other resources.
|
|
(added in v.1.03)
|
|
|
|
|
|
7.3 TermGlobals Text Methods
|
|
|
|
There is a small set of methods for common terminal related string tasks:
|
|
|
|
|
|
7.3.1 TermGlobals.normalize( <n>, <fieldlength> )
|
|
|
|
Converts a number to a string, which is filled at its left with zeros ("0") to the total
|
|
length of <filedlength>. (e.g.: "TermGlobals.normalize(1, 2)" => "01")
|
|
|
|
|
|
7.3.2 TermGlobals.fillLeft( <value>, <fieldlength> )
|
|
|
|
Converts a value to a string and fills it to the left with blanks to <fieldlength>.
|
|
|
|
|
|
7.3.3 TermGlobals.center( <text>, <length> )
|
|
|
|
Adds blanks at the left of the string <text> until the text would be centered at a line
|
|
of length <length>. (No blanks are added to the the right.)
|
|
|
|
|
|
7.3.4 TermGlobals.stringReplace( <string1>, <string2>, <text> )
|
|
|
|
Replaces all occurences of the string <string1> in <text> with <string2>.
|
|
This is just a tiny work around for browsers with no support of RegExp.
|
|
|
|
|
|
|
|
|
|
8 Localization
|
|
|
|
The strings and key-codes used by the more utility of `Terminal.write()' are the only
|
|
properties of "termlib.js" that may need localization. These properties are defined in
|
|
`TermGlobals'. You may override them as needed:
|
|
|
|
PROPERTY STANDARD VALUE COMMENT
|
|
|
|
TermGlobals.lcMorePrompt1 ' -- MORE -- ' 1st string
|
|
TermGlobals.lcMorePromtp1Style 1 reverse
|
|
TermGlobals.lcMorePrompt2 ' (Type: space to continue, \'q\' to quit)' appended string
|
|
TermGlobals.lcMorePrompt2Style 0 plain
|
|
TermGlobals.lcMoreKeyAbort 113 (key-code: q)
|
|
TermGlobals.lcMoreKeyContinue 32 (key-code <SPACE>)
|
|
|
|
|
|
As "TermGlobals.lcMorePrompt2" is appended to "TermGlobals.lcMorePrompt1" make sure that
|
|
the length of the combined strings does not exceed `Terminal.conf.cols'.
|
|
|
|
|
|
|
|
|
|
9 Cross Browser Functions
|
|
|
|
For DHTML rendering some methods - as needed by the Terminal library - are provided.
|
|
These may also be accessed for other purposes.
|
|
|
|
|
|
9.1 TermGlobals.writeElement( <element id>, <text> [,<NS4 parent document>] )
|
|
|
|
Writes <text> to the DHTML element with id/name <element id>.
|
|
<NS4 parent document> is used for NS4 only and specifies an optional reference to a parent
|
|
document (default `window.document').
|
|
|
|
9.2 TermGlobals.setElementXY( <element id>, <x>, <y> )
|
|
|
|
Sets the DHTML element with id/name <element id> to position <x>/<y>.
|
|
For NS4 works only with children of the top document (window.document).
|
|
|
|
|
|
9.3 TermGlobals.setVisible( <element id>, <value> )
|
|
|
|
If <value> evaluates to `true' show DHTML element with id/name <element id> else hide it.
|
|
For NS4 works only with children of the top document (window.document).
|
|
|
|
|
|
9.4 Custom Fixes for Missing String Methods
|
|
|
|
Although `String.fromCharCode' and `String.prototype.charCodeAt' are defined by ECMA-262-2
|
|
specifications, a few number of browsers lack them in their JavaScript implementation. At
|
|
compile time custom methods are installed to fix this. Please note that they work only
|
|
with ASCII characters and values in the range of [0x20-0xff].
|
|
|
|
|
|
9.5 TermGlobals.setDisplay( <element id>, <value> )
|
|
|
|
Sets the style.display property of the element with id/name <element id> to the given
|
|
<value>. (added with v. 1.06)
|
|
|
|
|
|
|
|
|
|
10 Architecture, Internals
|
|
|
|
10.1 Global Entities
|
|
|
|
The library is designed to leave only a small foot print in the namespace while providing
|
|
suitable usability:
|
|
|
|
Globals defined in this library:
|
|
|
|
Terminal (Terminal object, `new' constructor and prototype methods)
|
|
TerminalDefaults (default configuration, static object)
|
|
termDefaultHandler (default command line handler, static function)
|
|
TermGlobals (common vars and code for all instances, static object and methods)
|
|
termKey (named mappings for special keys, static object)
|
|
termDomKeyRef (special key mapping for DOM key constants, static object)
|
|
|
|
|
|
Globals defined for fixing String methods, if missing
|
|
(String.fromCharCode, String.prototype.charCodeAt):
|
|
|
|
termString_keyref, termString_keycoderef, termString_makeKeyref
|
|
|
|
|
|
Required CSS classes for font definitions: ".term", ".termReverse".
|
|
|
|
|
|
|
|
10.2 I/O Architecture
|
|
|
|
The Terminal object renders keyboard input from keyCodes to a line buffer and/or to a
|
|
special keyCode buffer. In normal input mode printable input is echoed to the screen
|
|
buffers. Special characters like <LEFT>, <RIGHT>, <BACKSPACE> are processed for command
|
|
line editing by the internal key-handler `TermGlobals.keyHandler' and act directly on the
|
|
screen buffers. On <CR> or <ENTER> the start and end positions of the current line are
|
|
evaluated (terminated by ASCII 0x01 at the beginning which separates the prompt from the
|
|
user input, and any value less than ASCII 0x20 (<SPACE>) at the right end). Then the
|
|
character representation for the buffer values in this range are evaluated and
|
|
concatenated to a string stored in `Terminal.lineBuffer'. As this involves some
|
|
ASCII-to-String-transformations, the range of valid printable input characters is limited
|
|
to the first page of unicode characters (0x0020-0x00ff).
|
|
|
|
There are two screen buffers for output, one for character codes (ASCII values) and one
|
|
for style codes. Style codes represent combination of styles as a bitvector (see
|
|
`Terminal.type' for bit values.) The method `Terminal.redraw(<row>)' finally renders the
|
|
buffers values to a string of HTML code, which is written to the HTML entity holding the
|
|
according terminal row. The character buffer is a 2 dimensional array
|
|
`Terminal.charBuf[<row>][<col>]' with ranges for <row> from 0 to less than
|
|
`Terminal.conf.rows' and for <col> from 0 to less than `Terminal.conf.cols'. The style
|
|
buffer is a 2 dimensional array `Terminal.styleBuf[<row>][<col>]' with according ranges.
|
|
|
|
So every single character is represented by a ASCII code in `Terminal.charBuf' and a
|
|
style-vector in `Terminal.styleBuf'. The range of printable character codes is unlimitted
|
|
but should be kept to the first page of unicode characters (0x0020-0x00ff) for
|
|
compatibility purpose. (c.f. 8.4)
|
|
|
|
Keyboard input is first handled on the `KEYDOWN' event by the handler `TermGlobals.keyFix'
|
|
to remap the keyCodes of cursor keys to consistent values. (To make them distinctable from
|
|
any other possibly printable values, the values of POSIX <IS4> to <IS1> where chosen.)
|
|
The mapping of the cursor keys is stored in the properties LEFT, RIGHT, UP, and DOWN of
|
|
the global static object `termKey'.
|
|
|
|
The main keyboard handler `TermGlobals.keyHandler' (invoked on `KEYPRESS' or by
|
|
`TermGlobals.keyFix') does some final mapping first. Then the input is evaluated as
|
|
controlled by the flags `Terminal.rawMode' and `Terminal.charMode' with precedence of the
|
|
latter. In dependancy of the mode defined and the handlers currently defined, the input
|
|
either is ignored, or is internally processed for command line editing, or one of the
|
|
handlers is called.
|
|
|
|
In the case of the simultanous presecence of two instances of Terminal, the keyboard focus
|
|
is controlled via a reference stored in `TermGlobals.activeTerm'. This reference is also
|
|
used to evaluate the `this'-context of the key handlers which are methods of the static
|
|
Object `TermGlobals'.
|
|
|
|
A terminal's screen consists of a HTML-table element residing in the HTML/CSS division
|
|
spcified in `Terminal.conf.termDiv'. Any output is handled on a per row bases. The
|
|
individual rows are either nested sub-divisions of the main divisions (used for NS4 or
|
|
browsers not compatible to the "Gecko" engine) or the indiviual table data elements (<TD>)
|
|
of the terminal's inner table (used for browsers employing the "Gecko" engine).
|
|
(This implementation was chosen for rendering speed and in order to minimize any screen
|
|
flicker.) Any output or change of state in a raw results in the inner HTML contents of a
|
|
row's HTML element to be rewritten. Please note that as a result of this a blinking cursor
|
|
may cause a flicker in the line containing the cursor's position while displayed by a
|
|
browser, which employs the "Gecko" engine.
|
|
|
|
|
|
|
|
10.3 Compatibility
|
|
|
|
Standard web browsers with a JavaScript implementation compliant to ECMA-262 2nd edition
|
|
[ECMA262-2] and support for the anonymous array and object constructs and the anonymous
|
|
function construct in the form of "myfunc = function(x) {}" (c.f. ECMA-262 3rd edion
|
|
[ECMA262-3] for details). This comprises almost all current browsers but Konquerer (khtml)
|
|
and versions of Apple Safari for Mac OS 10.0-10.28 (Safari < 1.1) which lack support for
|
|
keyboard events.
|
|
|
|
To provide a maximum of compatibilty the extend of language keywords used was kept to a
|
|
minimum and does not exceed the lexical conventions of ECMA-262-2. Especially there is no
|
|
use of the `switch' statement or the `RegExp' method of the global object. Also the use of
|
|
advanced Array methods like `push', `shift', `splice' was avoided.
|
|
|
|
|
|
|
|
|
|
11 History
|
|
|
|
This library evolved from the terminal script "TermApp" ((c) N. Landsteiner 2003) and is
|
|
in its current form a down scaled spinn-off of the "JS/UIX" project [JS/UIX] (evolution
|
|
"JS/UIX v0.5"). c.f.: <http://www.masswerk.at/jsuix>
|
|
|
|
v 1.01: added Terminal.prototype.resizeTo(x,y)
|
|
added Terminal.conf.fontClass (=> configureable class name)
|
|
Terminal.prototype.open() now checks for element conf.termDiv in advance
|
|
and returns success.
|
|
|
|
v 1.02: added support for <TAB> and Euro sign
|
|
Terminal.conf.printTab
|
|
Terminal.conf.printEuro
|
|
and method Terminal.prototype.isPrintable(keycode)
|
|
added support for getopt to sample parser ("parser_sample.html")
|
|
|
|
|
|
v 1.03: added global keyboard locking (TermGlobals.keylock)
|
|
modified Terminal.prototype.redraw for speed (use of locals)
|
|
|
|
|
|
v 1.04: modified the key handler to fix a bug with MSIE5/Mac
|
|
fixed a bug in TermGlobals.setVisible with older MSIE-alike browsers without
|
|
DOM support.
|
|
moved the script of the sample parser to an individual document
|
|
=> "termlib_parser.js" (HTML document is "parser_sample.html" as before)
|
|
|
|
v 1.05: added config flag historyUnique.
|
|
|
|
v 1.06: fixed CTRl+ALT (Windows alt gr) isn't CTRL any more
|
|
-> better support for international keyboards with MSIE/Win.
|
|
fixed double backspace bug for Safari;
|
|
added TermGlobals.setDisplay for setting style.display props
|
|
termlib.js now outputs lower case html (xhtml compatibility)
|
|
(date: 12'2006)
|
|
|
|
v 1.07: added method Terminal.rebuild() to rebuild the GUI with new color settings.
|
|
(date: 01'2007)
|
|
|
|
|
|
|
|
|
|
12 Example for a Command Line Parser
|
|
|
|
// parser example, splits command line to args with quoting and escape
|
|
// for use as `Terminal.handler'
|
|
|
|
function commandHandler() {
|
|
this.newLine();
|
|
var argv = ['']; // arguments vector
|
|
var argQL = ['']; // quoting level
|
|
var argc = 0; // arguments cursor
|
|
var escape = false ; // escape flag
|
|
for (var i=0; i<this.lineBuffer.length; i++) {
|
|
var ch= this.lineBuffer.charAt(i);
|
|
if (escape) {
|
|
argv[argc] += ch;
|
|
escape = false;
|
|
}
|
|
else if ((ch == '"') || (ch == "'") || (ch == "`")) {
|
|
if (argQL[argc]) {
|
|
if (argQL[argc] == ch) {
|
|
argc ++;
|
|
argv[argc] = argQL[argc] = '';
|
|
}
|
|
else {
|
|
argv[argc] += ch;
|
|
}
|
|
}
|
|
else {
|
|
if (argv[argc] != '') {
|
|
argc ++;
|
|
argv[argc] = '';
|
|
argQL[argc] = ch;
|
|
}
|
|
else {
|
|
argQL[argc] = ch;
|
|
}
|
|
}
|
|
}
|
|
else if ((ch == ' ') || (ch == '\t')) {
|
|
if (argQL[argc]) {
|
|
argv[argc] += ch;
|
|
}
|
|
else if (argv[argc] != '') {
|
|
argc++;
|
|
argv[argc] = argQL[argc] = '';
|
|
}
|
|
}
|
|
else if (ch == '\\') {
|
|
escape = true;
|
|
}
|
|
else {
|
|
argv[argc] += ch;
|
|
}
|
|
}
|
|
if ((argv[argc] == '') && (!argQL[argc])) {
|
|
argv.length--;
|
|
argQL.length--;
|
|
}
|
|
if (argv.length == 0) {
|
|
// no commmand line input
|
|
}
|
|
else if (argQL[0]) {
|
|
// first argument quoted -> error
|
|
this.write("Error: first argument quoted by "+argQL[0]);
|
|
}
|
|
else {
|
|
argc = 0;
|
|
var cmd = argv[argc++];
|
|
/*
|
|
parse commands
|
|
1st argument is argv[argc]
|
|
arguments' quoting levels in argQL[argc] are of (<empty> | ' | " | `)
|
|
*/
|
|
if (cmd == 'help') {
|
|
this.write(helpPage);
|
|
}
|
|
else if (cmd == 'clear') {
|
|
this.clear();
|
|
}
|
|
else if (cmd == 'exit') {
|
|
this.close();
|
|
return;
|
|
}
|
|
else {
|
|
// for test purpose just output argv as list
|
|
// assemple a string of style-escaped lines and output it in more-mode
|
|
s=' ARG QL VALUE%n';
|
|
for (var i=0; i<argv.length; i++) {
|
|
s += TermGlobals.stringReplace('%', '%%',
|
|
TermGlobals.fillLeft(i, 6) +
|
|
TermGlobals.fillLeft((argQL[i])? argQL[i]:'-', 4) +
|
|
' "' + argv[i] + '"'
|
|
) + '%n';
|
|
}
|
|
this.write(s, 1);
|
|
return;
|
|
}
|
|
}
|
|
this.prompt();
|
|
}
|
|
|
|
|
|
The file "parser_sample.html" features a stand-alone parser ("termlib_parser.js") very
|
|
much like this. You are free to use it according to the termlib-license (see sect. 13).
|
|
It provides configurable values for quotes and esape characters and imports the parsed
|
|
argument list into a Terminal instance's namespace. ("parser_sample.html" and
|
|
"termlib_parser.js" should accompany this file.)
|
|
|
|
|
|
|
|
|
|
13 License
|
|
|
|
This JavaScript-library is free for private and academic use.
|
|
Please include a readable copyright statement and a backlink to <http://www.masswerk.at>
|
|
in the web page. The library should always be accompanied by the 'readme.txt' and the
|
|
sample HTML-documents.
|
|
|
|
The term "private use" includes any personal or non-commercial use, which is not related
|
|
to commercial activites, but excludes intranet, extranet and/or public net applications
|
|
that are related to any kind of commercial or profit oriented activity.
|
|
|
|
For commercial use see <http://www.masswerk.at> for contact information.
|
|
|
|
Any changes to the library should be commented and be documented in the readme-file.
|
|
Any changes must be reflected in the `Terminal.version' string as
|
|
"Version.Subversion (compatibility)".
|
|
|
|
|
|
|
|
|
|
14 Disclaimer
|
|
|
|
This software is distributed AS IS and in the hope that it will be useful, but WITHOUT ANY
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE. The entire risk as to the quality and performance of the product is borne by the
|
|
user. No use of the product is authorized hereunder except under this disclaimer.
|
|
|
|
|
|
|
|
|
|
15 References
|
|
|
|
[ECMA262-2] "ECMAScript Language Specification" Standard ECMA-262 2nd Edition
|
|
August 1998 (ISO/IEC 16262 - April 1998)
|
|
|
|
[ECMA262-3] "ECMAScript Language Specification" Standard ECMA-262 3rd Edition Final
|
|
24 March 2000
|
|
|
|
[JS/UIX] JS/UIX - JavaScript Uniplexed Interface eXtension
|
|
<http://www.masswerk.at/jsuix>
|
|
|
|
|
|
|
|
|
|
|
|
Norbert Landsteiner / Vienna, August 2005
|
|
mass:werk - media environments
|
|
<http://www.masswerk.at>
|
|
See web site for contact information.
|