「JsonDriver - Webアプリケーションをテストする」用にWebDriverJSを組み込んだテストプログラム側で、リモートコンソール機能があれば便利です。「JavaScriptコンソール」でポップアップにJavaScriptのコマンドプロンプトを表示する試みを行いましたが、いわゆるシェルの部分とUIが分離していないため、全体に手を入れないと使えないのが残念です。
そこで、
という2点に重点を置いて書き換えました。
terminal.js:
/*
* terminal.js - simple terminal
* licence : Apache v2
* author : shorindo.com
*/
var terminal = (function(shell) {
var _ID = "terminal";
var frame;
var line;
var prompt;
var command;
var jsonify = function(o){
var seen = [];
var jso = JSON.stringify(o, function(k,v) {
if (typeof v =='object') {
if ( !seen.indexOf(v) ) { return '__cycle__'; }
seen.push(v);
} return v;
}, 4);
return jso;
};
return {
init : function() {
frame = document.getElementById(_ID);
if (!frame) {
frame = document.appendChild(document.createElement("div"));
frame.id = _ID;
}
frame.style.border = "1px solid gray";
frame.style.width = "100%";
frame.style.height = "150px";
frame.addEventListener("click", function() {
command.focus();
}, false);
this.prompt();
},
prompt : function() {
if (command) {
command.contentEditable = false;
}
line = frame.appendChild(document.createElement("li"));
prompt = line.appendChild(document.createElement("span"));
prompt.className = "prompt";
prompt.innerHTML = shell.prompt();
command = line.appendChild(document.createElement("span"));
command.className = "command";
command.contentEditable = true;
command.addEventListener("keypress", function(evt) {
if (evt.keyCode == 13) {
if (!command.textContent || !command.textContent.trim()) {
terminal.prompt();
} else if ("execute" in shell) {
terminal.print(shell.execute(command.textContent));
} else if ("executeAsync" in shell) {
shell.executeAsync(command.textContent, function(result) {
terminal.print(result);
});
}
return false;
}
}, false);
command.focus();
},
print : function(message) {
if (command) {
command.contentEditable = false;
}
switch(typeof message) {
case 'object':
message = jsonify(message, null, 4);
break;
}
line = frame.appendChild(document.createElement("li"));
line.appendChild(document.createElement("pre"))
.innerHTML = message;
terminal.prompt();
}
};
})({
prompt : function() {
return "js> ";
},
execute : function(command) {
try {
return eval(command);
} catch (err) {
return err.toString();
}
}
}
);
window.addEventListener("load", function() { terminal.init(); }, false);
terminl.css:
#terminal {
overflow-y : auto;
line-height : 1.2em;
}
#terminal li {
color: black;
font-family: monospace;
list-style-type: none;
text-align: left;
word-wrap: break-word;
}
#terminal li pre {
margin : 0;
}
#terminal li span {
margin : 0;
padding : 0;
outline : none;
}