Last active
December 14, 2015 04:59
-
-
Save pce/5032084 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| "use strict"; | |
| function trace(s) { | |
| if (typeof console != "undefined") {console.log(s);} | |
| } | |
| var TerminalHistory = function () { | |
| this.cmd = []; | |
| this.cmdIndex = 0; | |
| // add empty line | |
| this.cmd[this.cmdIndex] = ""; | |
| this.cmdIndex++; | |
| }; | |
| TerminalHistory.prototype = { | |
| add:function(cmd) { | |
| this.cmd[this.cmdIndex]=cmd; | |
| this.cmdIndex++; | |
| }, | |
| get:function() { | |
| return this.cmd[this.cmdIndex]; | |
| }, | |
| up:function() { | |
| this.cmdIndex--; | |
| if (this.cmdIndex < 0) this.cmdIndex = 0; | |
| var cmd = this.cmd[this.cmdIndex]; | |
| return cmd; | |
| }, | |
| down:function() { | |
| this.cmdIndex++; | |
| if (this.cmdIndex > this.cmd.length -1) this.cmdIndex = this.cmd.length -1; | |
| var cmd = this.cmd[this.cmdIndex]; | |
| return cmd; | |
| } | |
| }; | |
| var Terminal = function (id, history) { | |
| this.id = id; | |
| this.history = history || false; | |
| this.timeStamp = new Date().getTime(); | |
| this.line = []; | |
| this.curLine = 0; | |
| // workarround lines with prompt | |
| this.userLine = []; | |
| }; | |
| Terminal.prototype = { | |
| prompt: '$ ', | |
| rows:24, | |
| cols:80, | |
| cursorChar:'_', | |
| maxLength:1024, | |
| onKeyPressEvent:function(event) { | |
| trace(event); | |
| event = event || window.event; | |
| var key = event.charCode; | |
| switch (key) { | |
| default: | |
| if (key > 32) | |
| this.line[this.curLine] += String.fromCharCode(key); | |
| break; | |
| } | |
| this.update(); | |
| }, | |
| onKeyDownEvent:function(event) { | |
| trace(event); | |
| event = event || window.event; | |
| var key = event.keyCode; | |
| switch (key) { | |
| case 6: | |
| case 8: | |
| if (this.line[this.curLine].length) | |
| this.line[this.curLine] = this.line[this.curLine].slice(0, -1); | |
| break; | |
| case 9: | |
| // tab | |
| // this.onReadLine(); | |
| break; | |
| case 13: | |
| // enter | |
| this.onEnter(); | |
| break; | |
| case 16: | |
| // shift | |
| break; | |
| case 17: | |
| // ctrl | |
| break; | |
| case 18: | |
| // alt | |
| break; | |
| case 27: | |
| // escape | |
| break; | |
| case 32: | |
| this.line[this.curLine] += " ";//" "; | |
| break; | |
| case 37: | |
| // left arrow | |
| break; | |
| case 38: | |
| // history (up arrow) | |
| if (this.history) | |
| this.line[this.curLine] = this.history.up(); | |
| break; | |
| case 40: | |
| // history (down arrow) | |
| if (this.history) | |
| this.line[this.curLine] = this.history.down(); | |
| break; | |
| case 39: | |
| // right arrow | |
| break; | |
| case 46: | |
| // del | |
| break; | |
| case 60: | |
| this.line[this.curLine] += "<";// "<"; | |
| break; | |
| case 62: | |
| this.line[this.curLine] += ">";// ">"; | |
| break; | |
| default: | |
| // console.log(key); | |
| break; | |
| } | |
| this.update(); | |
| }, | |
| registerDefaultEvents:function() { | |
| document.onkeydown=this.onKeyDownEvent.bind(this); | |
| document.onkeypress=this.onKeyPressEvent.bind(this); | |
| }, | |
| init:function() { | |
| var self; | |
| this.line[this.curLine] = ""; | |
| this.userLine.push(this.curLine); | |
| document.getElementById(this.id).focus(); | |
| this.registerDefaultEvents(); | |
| self = this; | |
| setInterval(function () { | |
| self.update(); | |
| }, 1000); | |
| }, | |
| echo:function(text) { | |
| this.curLine++; | |
| this.line[this.curLine] = text; | |
| //this.curLine++; | |
| //this.line[this.curLine] = ""; | |
| }, | |
| onEnter:function() { | |
| this.userLine.push(this.curLine); | |
| this.parseLine(); | |
| this.curLine++; | |
| this.line[this.curLine] = ""; | |
| this.userLine.push(this.curLine); | |
| }, | |
| cmd: { | |
| echo:function(self, argv) { | |
| argv = argv.slice(1, argv.length).join(" "); | |
| self.echo(argv); | |
| }, | |
| help:function(self, argv) { | |
| self.echo("JavaScript Fun Terminal, version 0.1"); | |
| self.echo("These shell commands are defined internally."); | |
| self.echo("`help' prints this list."); | |
| self.echo("ls - list clickable related links"); | |
| self.echo("echo [arg...] - prints to stdout"); | |
| }, | |
| ls:function(self, argv) { | |
| self.echo('<a href="http://3nv.org" target="_blank">music</a>'); | |
| self.echo('<a href="http://github.com/pce" target="_blank">code</a>'); | |
| } | |
| }, | |
| addCommand:function(cmd, func) { | |
| this.cmd[cmd] = func; | |
| }, | |
| parseLine:function() { | |
| if (!this.line[this.curLine].length) return; | |
| if (this.history) | |
| this.history.add(this.line[this.curLine]); | |
| // todo command sep,-operators [";", "&&", "||"] | |
| var cl = this.line[this.curLine].split(" "); | |
| if (typeof this.cmd[cl[0]] != "undefined" && typeof this.cmd[cl[0]] == "function") { | |
| this.cmd[cl[0]](this, cl); | |
| } else { | |
| this.echo("command not found"); | |
| } | |
| }, | |
| escapeLine:function(curLine) { | |
| return this.line[curLine].replace(/&/g, "&").replace(/>/g, ">").replace(/</g, "<").replace(/"/g, """); | |
| }, | |
| isUserLine:function(curLine) { | |
| for(var p=0; p < this.userLine.length; p++) | |
| if (curLine == this.userLine[p]) | |
| return true; | |
| return false; | |
| }, | |
| update:function() { | |
| document.getElementById(this.id).innerHTML = ""; | |
| for (var lineIndex=0; lineIndex < this.line.length; lineIndex++) { | |
| if (this.isUserLine(lineIndex)) { | |
| document.getElementById(this.id).innerHTML += this.prompt; | |
| document.getElementById(this.id).innerHTML += this.escapeLine(lineIndex); | |
| } else { | |
| document.getElementById(this.id).innerHTML += this.line[lineIndex]; | |
| } | |
| if (lineIndex == this.line.length-1) { | |
| document.getElementById(this.id).innerHTML += this.cursorChar; | |
| } else | |
| document.getElementById(this.id).innerHTML += "<br/>"; | |
| } | |
| if (new Date().getTime() - this.timeStamp >= 50) { | |
| this.timeStamp = new Date().getTime(); // Reset the time stamp | |
| if (this.cursor == false) { | |
| this.cursor = true; | |
| if (this.line[this.curLine].length < this.maxLength) | |
| this.cursorChar += "_"; | |
| } else { | |
| this.cursor = false; | |
| if (this.cursorChar.length != 0) | |
| this.cursorChar = ""; | |
| } | |
| } | |
| } | |
| }; | |
| // #IF TEST | |
| // ---------------------------------------- | |
| /* | |
| <style> | |
| body { | |
| background-color:black; | |
| font-family: "DejaVu Sans Mono", | |
| Monaco, | |
| "Bitstream Vera Sans Mono", | |
| "Lucida Console", | |
| Terminal, | |
| monospace; | |
| color:#ccc; | |
| } | |
| .terminal { | |
| color:#ccc; | |
| white-space:pre; | |
| } | |
| a {text-decoration:none;} | |
| </style> | |
| <section id="terminal" class="terminal"></section> | |
| */ | |
| // var terminal; // global for console access | |
| window.onload = function() { | |
| var history = new TerminalHistory(); | |
| history.add("ls"); | |
| var terminal = new Terminal("terminal", history); | |
| terminal.init(); | |
| terminal.addCommand("date", function(self, argv) { | |
| self.echo(new Date().toLocaleString()); | |
| }); | |
| } | |
| // #ENDIF | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment