-
Notifications
You must be signed in to change notification settings - Fork 17
/
terminal.js
117 lines (97 loc) · 3.74 KB
/
terminal.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
var Terminal = (function() {
var history = (localStorage.getItem("history") ? localStorage.getItem("history").split(",") : []),
historyIndex = history.length;
self = {};
var KEY_UP = 38,
KEY_DOWN = 40,
KEY_TAB = 9;
// Auxiliary functions
var resetPrompt = function(terminal, prompt) {
var newPrompt = prompt.parentNode.cloneNode(true);
prompt.setAttribute("contenteditable", false);
if(self.prompt) {
newPrompt.querySelector(".prompt").textContent = self.prompt;
}
terminal.appendChild(newPrompt);
newPrompt.querySelector(".input").innerHTML = " ";
newPrompt.querySelector(".input").focus();
};
var runCommand = function(terminal, cmd, args) {
terminal.innerHTML += (self.commands[cmd](args));
};
var updateHistory = function(cmd) {
history.push(cmd);
localStorage.setItem("history", history);
historyIndex = history.length;
};
var browseHistory = function(prompt, direction) {
var changedPrompt = false;
if(direction == KEY_UP && historyIndex > 0) {
prompt.textContent = history[--historyIndex];
changedPrompt = true;
} else if(direction == KEY_DOWN) {
if(historyIndex < history.length) ++historyIndex;
if(historyIndex < history.length) prompt.textContent = history[historyIndex];
else prompt.textContent = " ";
changedPrompt = true;
}
if(changedPrompt) {
var range = document.createRange();
var sel = window.getSelection();
range.setStart(prompt.childNodes[0], prompt.textContent.length);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
};
var autoCompleteInput = function(input) {
var cmds = self.commands,
re = new RegExp("^" + input, "ig"),
suggestions = [];
for(var cmd in cmds) {
if(cmds.hasOwnProperty(cmd) && cmd.match(re)) {
suggestions.push(cmd);
}
}
return suggestions;
};
// Terminal functions
self.init = function(elem, commands) {
self.commands = commands;
elem.addEventListener("keydown", function(event) {
if(event.keyCode == KEY_TAB) {
var prompt = event.target;
var suggestions = autoCompleteInput(prompt.textContent.replace(/\s+/g, ""));
if(suggestions.length == 1) {
prompt.textContent = suggestions[0];
var range = document.createRange();
var sel = window.getSelection();
range.setStart(prompt.childNodes[0], suggestions[0].length);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
event.preventDefault(true);
return false;
}
});
elem.addEventListener("keyup", function(event) {
if(historyIndex < 0) return;
browseHistory(event.target, event.keyCode);
});
elem.addEventListener("keypress", function(event) {
var prompt = event.target;
if(event.keyCode != 13) return false;
updateHistory(prompt.textContent);
var input = prompt.textContent.split(" ");
if(input[0] && input[0] in self.commands) {
runCommand(elem, input[0], input);
}
resetPrompt(elem, prompt);
event.preventDefault();
});
elem.querySelector(".input").focus();
return self;
};
return self;
})();