なんか Javascript との対話環境でもつくってみようかと思った

http://konbu.s13.xrea.com/lib/js/terminal.html
たぶん俺以外のちゃんとした人が、ちゃんとしたの作ってるだろうなあと思いつつ勉強がてら、Javascriptとの対話環境づくりをしてみた。全然できてないできてない。
IMEとかを切らないとまったくピクリとも動かなかったりする。あとIEだとまったく動かない。べつにFirefoxでだって使えやしないけど。
もうね、event.keyCode の挙動がががががというかんじ。onkeydown だと取れて onkeypress だと取れなくて、onkeyup だけで取れる keyCode があったりなかったりで。keyCode が取れたと思ったら、いったいそれはどこの国のキーボード配列だみたいな文字を読み取ってくれたりして、なんでだろうなあ。別に 101-us でもない。
おとなしく textarea にスクリプト書いて、なんかボタンおすか、適当な組み合せのキーを押せば実行、とかの形態にすれば簡単なんだけど。あー、うんそっちが簡単だな。そうしよう。ていうかじゃないと無理だ。
以下適当なソース

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>talk with js</title>
<style type="text/css">
body{
  background: #EFEFF0;
  color: #004624;
}
h1,h2{
  font-size: 100%;
  margin-bottom: 0px;
}
.box{
  margin: 10%;
}
#terminal{
  background: black;
  color: white;
  width: 50%;
  height: 20em;
}
#cursor{
  background: gray;
}
</style>
<script type="text/javascript"><!--
  var PS1="$ ";
  function Terminal(terminalid, inputid, nowlineid, historyid){
    this.SPKey = {8:"this.backspace()", 13:"this.run()"};
    this.CSPKey = {72:"this.backspace()", 77:"this.run()"};
    this.SSPKey = {0x31:"!", 0x32:"\"", 0x33:"#", 0x34:"$",
      0x35:"%", 0x36:"&", 0x37:"'", 0x38:"(", 0x39:")", 0x30:""};
    this.onmodkey = {shift: false, ctrl: false, alt: false};
    this.modkey = {shift: 16, ctrl: 17, alt: 18,};
    this.keydown = function(keycode){
      if(0x20 <= keycode && keycode <= 0x7E){
        if(this.onmodkey.ctrl){
          eval(this.CSPKey[keycode]);
        }
        else if(this.onmodkey.shift && 0x30 <= keycode && keycode <= 0x39){
          var key = this.SSPKey[keycode];
          this.inputch(key);
          console.log(keycode,key);
        }
        else{
          var key = String.fromCharCode(keycode);
          key = term.onmodkey.shift?key:key.toLowerCase();
          this.inputch(key);
          console.log(keycode,key);
        }
      }
      else if(keycode == 16) this.onmodkey.shift = true;
      else if(keycode == 17) this.onmodkey.ctrl = true;
      else if(keycode == 18) this.onmodkey.alt = true;
      else if(keycode == 8) this.backspace();
      else if(keycode == 13) this.run();
      else{
        eval(this.SPKey[keycode]);
        console.log(keycode,"???");
      }
      console.log(this.onmodkey);
    };
    this.keyup = function(keycode){
      if(0x20 <= keycode && keycode <= 0x7E){
      }
      if(this.onmodkey.shift) if(keycode == 16) this.onmodkey.shift = false;
      if(this.onmodkey.ctrl) if(keycode == 17) this.onmodkey.ctrl = false;
      if(this.onmodkey.alt) if(keycode == 18) this.onmodkey.alt = false;
    };
    this.keypress = function(keycode){
    };
    this.run = function(){
      var result = eval(this.input());
      this.history(this.history()+PS1+this.input()+"<br>"+result+"<br>");
      this.initline();
      return result;
    };
    this.writefunc = function(id){
      return function(text){
        if(text != undefined) document.getElementById(id).innerHTML = text;
        return document.getElementById(id).innerHTML;
      };
    };
    this.html = this.writefunc(terminalid);
    this.input = this.writefunc(inputid);
    this.inputch = function(key){
      this.input(this.input()+key);
    };
    this.history = this.writefunc(historyid);
    this.backspace = function(){
      var text = this.input();
      text = text.substring(0,text.length-1);
      this.input(text);
    };
    this.initline = function(){
      this.input("");
      this.writefunc(nowlineid)(this.writefunc(nowlineid)());
    };
  };
  var term = new Terminal("terminal", "input","nowline", "history");
  document.onkeydown = function(event){
    term.keydown(event.keyCode);
  };
  document.onkeyup = function(event){
    term.keyup(event.keyCode);
  };
  document.onkeypress = function(event){
    term.keypress(event.keyCode);
  };
  window.onload = function(){
    term.initline();
    console.log(term.html());
  }
// -->
</script>
</head>
<body>
<h1>jstalk</h1>
<div class="box">
<h2>terminal</h2>
<div id="terminal">
<span id="history"></span>
<span id="nowline">
  $ <span id="input"></span>
  <span id="cursor"> </span>
</span>
</div>
</div>
<script type="text/javascript"><!--
// -->
</script>
</body></html>

諸事情により(ファイル管理がめんどくさかったので)htmlファイルにまとめた。Javascript のオブジェクトというものを知った。とりあえず使ったらひどいかたちになった。
textarea と input 組み合わせてやるか。

test