/**
* Create a new shell with the class name given to the terminal tag.
* The terminal tag object passes events between the shell and the other tags.
*/
var shell = window[opts.shell] ? new window[opts.shell](this) : {}
this.welcome = shell.welcome || opts.welcome
this.prompt = shell.prompt || opts.prompt
this.id = 'term-' + Math.floor(Math.random() * 10000)
var ev = opts.events, self = this
this.contexts = {}
this.output = this.contexts['default'] = []
this.on('mount', function() { this.add(opts.welcome) })
ev.on('disp_add', function(text) { self.add(text) })
ev.on('disp_set', function(text) {
if (text) {
self.clear()
self.add(text)
}
})
ev.on('disp_clear', function() { self.clear() })
ev.on('context_swap', function(name) {
name = name || 'default'
if (!(name in self.contexts)) {
self.contexts[name] = []
}
self.update({ output: self.contexts[name] })
})
add(text) {
if (text) {
this.output.push({ 'content': text })
this.update()
}
}
clear() {
this.output.length = 0
this.update()
}
var ev = opts.events, self = this
this.contexts = {}
this.current = 'default'
this.contexts[this.current] = {}
this.visible = this.prompt_visible = true
this.prompt = opts.prompt || '$ '
this.on('mount', function() { this.command.focus() })
ev.on('prompt_set', function(text) {
self.prompt = text
self.tags.lhs.write(text)
})
ev.on('prompt_hide', function() { self.update({ prompt_visible: false }) })
ev.on('prompt_show', function() { self.update({ prompt_visible: true }) })
ev.on('cmd_add', function(text) { self.command.value += text })
ev.on('cmd_set', function(text) { self.command.value = text })
ev.on('cli_hide', function() { self.update({ visible: false }) })
ev.on('cli_show', function() {
self.update({ visible: true })
self.command.focus()
})
ev.on('context_swap', function(name) {
name = name || 'default'
// Initialise a new context
if (!(name in self.contexts)) {
self.contexts[name] = { visible: true, prompt: '', prompt_visible: true }
}
// Save current values and load target context
['visible', 'prompt', 'prompt_visible'].forEach(function(p) {
self.contexts[self.current][p] = self[p]
self[p] = self.contexts[name][p]
})
// Update the display.
self.current = name
self.tags.lhs.write(self.prompt)
if (self.visible) {
self.command.focus()
}
})
process() {
var prompt = this.prompt_visible ? this.prompt : ''
var command = this.encode(this.command.value)
ev.trigger('disp_add', prompt + command + '\n')
ev.trigger('cmd_entered', command)
this.command.value = ''
// Refocus to scroll display and keep input in view.
this.command.blur()
this.command.focus()
}
encode(text) {
return text.replace(/&/g,'&').replace(//g,'>')
}
// Set initial html using `content` option, and...
this.on('mount', function() { this.write(opts.content) })
// Call `write()` manually to update the html.
write(text) { this.root.innerHTML = text }