{"id":2674,"date":"2012-12-20T17:30:54","date_gmt":"2012-12-20T23:30:54","guid":{"rendered":"http:\/\/bililite.com\/blog\/?p=2674"},"modified":"2012-12-23T09:50:03","modified_gmt":"2012-12-23T15:50:03","slug":"javascript-command-line","status":"publish","type":"post","link":"https:\/\/bililite.com\/blog\/2012\/12\/20\/javascript-command-line\/","title":{"rendered":"Javascript Command Line Interface"},"content":{"rendered":"<p>I was playing with a minor project and wanted to simulate a <a href=\"http:\/\/en.wikipedia.org\/wiki\/Command-line_interface\">command line interface<\/a>, like the old <a href=\"http:\/\/uni.xkcd.com\">April Fools xkcd<\/a>, and realized that their code was far more complicated than what you need if you use jQuery and <code>contenteditable<\/code>.<\/p>\r\n<p>My quick jQuery plugin to turn any <code class=\"language-html\" >&lt;div&gt;<\/code> into a terminal emulator is:<\/p>\r\n<pre><code class=\"language-javascript\" >\t$.fn.cli = function(handler, prompt, effect){\r\n\t\tif (!prompt) prompt = '&amp;gt;&amp;nbsp;';\r\n\t\tif (!effect) effect = $.fn.text;\r\n\t\treturn this.each(function(){\r\n\t\t\tvar self = $(this);\r\n\t\t\tfunction newline(){\r\n\t\t\t\tself.\r\n\t\t\t\t append('&lt;p class=input&gt;&lt;span class=prompt&gt;'+prompt+'&lt;\/span&gt;&lt;span  style=outline:none contenteditable&gt;&lt;\/span&gt;').\r\n\t\t\t\t find('[contenteditable]')[0].focus(); \/\/ focus only works on the element, not the jQuery object\r\n\t\t\t}\r\n\t\t\tnewline();\r\n\t\t\tself.on('keydown', '[contenteditable]', function(evt){\r\n\t\t\t\tif (evt.keyCode == 13){\r\n\t\t\t\t\tthis.removeAttribute('contenteditable'); \/\/ the old input line should not be editable\r\n\t\t\t\t\t\/\/ standards use textContent, IE uses innerText\r\n\t\t\t\t\teffect.call($('&lt;p class=response&gt;').appendTo(self),handler(this.textContent || this.innerText));\r\n\t\t\t\t\tnewline();\r\n\t\t\t\t\treturn false;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t});\r\n\t};\r\n<\/code><\/pre>\r\n<p>And you use it like:<\/p>\r\n<pre><code class=\"language-javascript\" >$('div').cli(function(text){\r\n  return 'You wrote: '+text;\r\n});<\/pre><\/code>\r\n<p>See <a href=\"\/wvm\/cli.html\">the demo<\/a>. The font there is <a href=\"http:\/\/www.google.com\/webfonts\/specimen\/VT323\">Peter Hull's VT323<\/a>.<\/p>\r\n<p><code>handler<\/code> is a function that is passed the text in the input line and should return the text to output. <code>prompt<\/code> is the prompt string. <code>effect<\/code> is the function that lets you do fancy things to the output. It is called with <code>this<\/code> set to a <code>&lt;p&gt;<\/code> element that is to contain the text, and is passed one parameter, the text to output. It defaults to <code>jQuery.fn.text<\/code>, just showing the text.<\/p>\r\n<p>It's not fancy; any actual processing of the text is up to you. Catching special characters like the up-arrow for history is also up to you. It doesn't have the old-fashioned blinking block cursor, since the insertion point caret is not styleable, and <a href=\"http:\/\/www.dynamicdrive.com\/forums\/showthread.php?17450-Emulating-a-terminal-like-caret-with-javascript-and-css\">faking it<\/a> is not worth the effort.<\/p>\r\n<p>If you want a mind-blowingly cool terminal emulator, see <a href=\"http:\/\/www.masswerk.at\/termlib\/\">mass:werk's termlib<\/a>. And check out their cool Space Invaders game on their <a href=\"http:\/\/www.masswerk.at\/404\">404 page<\/a>.<\/p>\r\n","protected":false},"excerpt":{"rendered":"I was playing with a minor project and wanted to simulate a command line interface, like the old April Fools xkcd, and realized that their code was far more complicated than what you need if you use jQuery and contenteditable. My quick jQuery plugin to turn any &lt;div&gt; into a terminal emulator is: $.fn.cli = [&hellip;]","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10,5],"tags":[],"_links":{"self":[{"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/posts\/2674"}],"collection":[{"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/comments?post=2674"}],"version-history":[{"count":13,"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/posts\/2674\/revisions"}],"predecessor-version":[{"id":2687,"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/posts\/2674\/revisions\/2687"}],"wp:attachment":[{"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/media?parent=2674"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/categories?post=2674"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/tags?post=2674"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}