2007-05-04
■[JS][Ruby] JS Commander
コンソール上から JavaScript で Web ブラウザを操作できる、JS Commander というプログラムを作ってみました。
JS Commander を立ち上げるとプロキシサーバが同時に起動し、このプロキシサーバを使うように Web ブラウザを設定すると、コンソール上で JavaScript のコードが入力できるようになります。
Web ブラウザ上の JavaScript を自由に実行できるコンソールには FireBug, FireBug Lite, jsh, MozRepl などがありますが、JS Commander の特徴は以下のような感じです。
- ブラウザ非依存 - XmlHttpRequest が使えるブラウザであればたぶん動きます。
- readline を使った操作 - bash などのシェルと同じような emacs 風キーバインドが使えます。
- 別のマシンにあるブラウザも操作可能 - Wii を PC から操作することもできます。
というか、もともと Wii で URL を打ち込むのが面倒なので PC から Wii を操作したいなーと思ったのが動機です。
Firefox 2 / Safari 2.0.4 / IE 6 / Opera 9 あたりでそれなりに動くことを確認してます。
ダウンロード
実行には Ruby が必要です。ただし、fork を使っているので mswin32 版では動きません。Windows で動かす場合は cygwin を使ってください。Ruby のバージョンは 1.8.4 以降であればたぶん動くと思います。
gem 版と tar.gz 版があるのでお好きな方をダウンロードしてください。使うだけなら gem をダウンロードして gem install jscmd-0.0.1.gem とするのが一番簡単です。
http://www.kbmj.com/~shinya/jscmd/jscmd-0.0.1.gem
http://www.kbmj.com/~shinya/jscmd/jscmd-0.0.1.tgz
5/8 追記: RubyForge に up したので gem install jscmd でインストールできます。
使用方法
コマンドラインから jscmd を実行してください。
$ jscmd [2007-05-04 14:38:02] INFO WEBrick 1.3.1 [2007-05-04 14:38:02] INFO ruby 1.8.5 (2006-08-25) [powerpc-darwin8.7.0] [2007-05-04 14:38:02] INFO JSCommander::ProxyServer#start: pid=681 port=9000 Press Ctrl+D to exit. >
gem をインストールした場合はパスに入っているはずです。tgz を解凍した場合は bin の下に入っています。
デフォルトでは 9000 番ポートでプロキシサーバが立ち上がります。お使いのブラウザの HTTP のプロキシサーバを、jscmd を立ち上げたマシンの 9000 番ポートに設定してください。-p オプションでポートを変えられます。
ブラウザがサーバに接続すると、以下のようにブラウザで開いているページのホスト名が表示されてコマンドが入力可能な状態になります。
[rimo.tv]>
ここで JavaScript の文を入力すると、ブラウザ上で実行されて結果が表示されます。
[rimo.tv]> document.title Rimo [rimo.tv]>
以下のように別のサイトに移動することもできます。別のサイトに移動する場合はブラウザとの通信が一旦切れるため、aborted という表示が出て再接続されるまで少し待つことになります。
[rimo.tv]> location = "http://www.yahoo.com/" http://www.yahoo.com/ [rimo.tv]> aborted > [www.yahoo.com]>
Ctrl+P でコマンドの履歴を呼び出すこともできます。readline を使っているので、emacs っぽいキーバインドで操作できます。
入力中に tab を押すとプロパティ名を補完できます。例えば、window.a まで入力して tab を押すと以下のように表示されます。
[rimo.tv]> window.a (ここで tab) window.addEventListener window.addToBookmark window.attachEvent window.addEventStream window.alert [rimo.tv]> window.a
Ctrl+D を押すと修了します。
組み込み API
ページ内の JavaScript のコードから、FireBug と同様に console.{debug,info,warn,error,log} 関数が使用できます。例えば console.info("foo") と実行すると、コンソール上に 「[info] foo」と表示されます。ただし、FireBug がすでにインストールされている (console オブジェクトがすでに存在する) 場合はそちらが優先されるので、jscmd 側には表示されません。
また、コンソール上からは dir という関数を使ってオブジェクト内のプロパティを調べることができます。例えば dir(window) とすると、window オブジェクト内の全てのプロパティとその内容を表示します。
[rimo.tv]> dir(window)
0 [object Window]
CSSPrimitiveValue \nfunction CSSPrimitiveValue() { [native code] }
DOMParser \nfunction DOMParser() { [native code] }
FlashObject \nfunction (_1,id,w,h,_5,c,_7,_8,_9,_a,_b)\n{\n if (! document.getElementById)\n {\n return ;\n }\n this.DETECT_KEY = _b ? _b : "detectflash";\n this.skipDetect = deconcept.util.getReque...
Image \nfunction Image() { [native code] }
Option \nfunction Option() { [native code] }
...以下略...
制限
- SSL には対応していません。
- ページ内で例外が発生するとコンソールに表示されますが、Opera は window.onerror に対応していないので、残念ながら Wii で起こった JavaScript の例外を補足することはできません。プロキシで try - catch を使うように書き換えればいけそうな気がしますが、そこまでの気力はなかった...
- 複数のウィンドウ(タブ)を同時に表示することはあまり考慮していないので、特定のタブに対してコマンドを実行するような機能はありません。
謝辞
プロパティ名の補完で DontEnum なプロパティも表示するために、id:brazil さんの jsh で使われているコードを使わせていただきました。ありがとうございます → http://d.hatena.ne.jp/brazil/20061020
僕はproxomitron使ってて、カンタンなjavascriptを間に入れたりしてるんですけど、こっちのがすごいベンリそうですね