From 14e5155f75ee390e4d7bf05274811b6507229149 Mon Sep 17 00:00:00 2001 From: Innovation Inc Date: Tue, 23 Apr 2019 10:02:54 -0500 Subject: [PATCH] Create terminal.js --- js/terminal.js | 190 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 js/terminal.js diff --git a/js/terminal.js b/js/terminal.js new file mode 100644 index 0000000..6e8a078 --- /dev/null +++ b/js/terminal.js @@ -0,0 +1,190 @@ +var util = util || {}; +util.toArray = function(list) { + return Array.prototype.slice.call(list || [], 0); +}; + +var Terminal = Terminal || function(cmdLineContainer, outputContainer) { + window.URL = window.URL || window.webkitURL; + window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; + + var cmdLine_ = document.querySelector(cmdLineContainer); + var output_ = document.querySelector(outputContainer); + + const CMDS_ = [ + 'cat', 'clear', 'clock', 'date', 'echo', 'help', 'uname', 'whoami' + ]; + + var fs_ = null; + var cwd_ = null; + var history_ = []; + var histpos_ = 0; + var histtemp_ = 0; + + window.addEventListener('click', function(e) { + cmdLine_.focus(); + }, false); + + cmdLine_.addEventListener('click', inputTextClick_, false); + cmdLine_.addEventListener('keydown', historyHandler_, false); + cmdLine_.addEventListener('keydown', processNewCommand_, false); + + // + function inputTextClick_(e) { + this.value = this.value; + } + + // + function historyHandler_(e) { + if (history_.length) { + if (e.keyCode == 38 || e.keyCode == 40) { + if (history_[histpos_]) { + history_[histpos_] = this.value; + } else { + histtemp_ = this.value; + } + } + + if (e.keyCode == 38) { // up + histpos_--; + if (histpos_ < 0) { + histpos_ = 0; + } + } else if (e.keyCode == 40) { // down + histpos_++; + if (histpos_ > history_.length) { + histpos_ = history_.length; + } + } + + if (e.keyCode == 38 || e.keyCode == 40) { + this.value = history_[histpos_] ? history_[histpos_] : histtemp_; + this.value = this.value; // Sets cursor to end of input. + } + } + } + + // + function processNewCommand_(e) { + + if (e.keyCode == 9) { // tab + e.preventDefault(); + // Implement tab suggest. + } else if (e.keyCode == 13) { // enter + // Save shell history. + if (this.value) { + history_[history_.length] = this.value; + histpos_ = history_.length; + } + + // Duplicate current input and append to output section. + var line = this.parentNode.parentNode.cloneNode(true); + line.removeAttribute('id') + line.classList.add('line'); + var input = line.querySelector('input.cmdline'); + input.autofocus = false; + input.readOnly = true; + output_.appendChild(line); + + if (this.value && this.value.trim()) { + var args = this.value.split(' ').filter(function(val, i) { + return val; + }); + var cmd = args[0].toLowerCase(); + args = args.splice(1); // Remove cmd from arg list. + } + + switch (cmd) { + case 'cat': + var url = args.join(' '); + if (!url) { + output('Usage: ' + cmd + ' https://s.codepen.io/...'); + output('Example: ' + cmd + ' https://s.codepen.io/AndrewBarfield/pen/LEbPJx.js'); + break; + } + $.get( url, function(data) { + var encodedStr = data.replace(/[\u00A0-\u9999<>\&]/gim, function(i) { + return '&#'+i.charCodeAt(0)+';'; + }); + output('
' + encodedStr + '
'); + }); + break; + case 'clear': + output_.innerHTML = ''; + this.value = ''; + return; + case 'clock': + var appendDiv = jQuery($('.clock-container')[0].outerHTML); + appendDiv.attr('style', 'display:inline-block'); + output_.appendChild(appendDiv[0]); + break; + case 'date': + output( new Date() ); + break; + case 'echo': + output( args.join(' ') ); + break; + case 'help': + output('
' + CMDS_.join('
') + '
'); + break; + case 'uname': + output(navigator.appVersion); + break; + case 'whoami': + var result = "

"; + for (var prop in codehelper_ip) + result += prop + ": " + codehelper_ip[prop] + "
"; + output(result); + break; + default: + if (cmd) { + output(cmd + ': command not found'); + } + }; + + window.scrollTo(0, getDocHeight_()); + this.value = ''; // Clear/setup line for next input. + } + } + + // + function formatColumns_(entries) { + var maxName = entries[0].name; + util.toArray(entries).forEach(function(entry, i) { + if (entry.name.length > maxName.length) { + maxName = entry.name; + } + }); + + var height = entries.length <= 3 ? + 'height: ' + (entries.length * 15) + 'px;' : ''; + + // 12px monospace font yields ~7px screen width. + var colWidth = maxName.length * 7; + + return ['
']; + } + + // + function output(html) { + output_.insertAdjacentHTML('beforeEnd', '

' + html + '

'); + } + + // Cross-browser impl to get document's height. + function getDocHeight_() { + var d = document; + return Math.max( + Math.max(d.body.scrollHeight, d.documentElement.scrollHeight), + Math.max(d.body.offsetHeight, d.documentElement.offsetHeight), + Math.max(d.body.clientHeight, d.documentElement.clientHeight) + ); + } + + // + return { + init: function() { + output('

HTML5 Web Terminal

' + new Date() + '

Enter "help" for more information.

'); + }, + output: output + } +};