/**
* Create a new shell object using the class name given to terminal-ui.
* The terminal-ui object is itself passed to this shell class.
* The terminal-ui object, being an Observable, allows the shell object and
* other tags to fire events to each other.
*/
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.refs.command.focus() })
ev.on('prompt_set', function(text) { self.prompt = 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.refs.command.value += text })
ev.on('cmd_set', function(text) { self.refs.command.value = text })
ev.on('cli_hide', function() { self.update({ visible: false }) })
ev.on('cli_show', function() {
self.update({ visible: true })
self.refs.command.focus()
})
ev.on('context_swap', function(name) {
name = name || 'default'
// Initialise a new context if a given name does not already exist.
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
if (self.visible) {
self.refs.command.focus()
}
})
process(event) {
var prompt = this.prompt_visible ? this.prompt : ''
var command = this.encode(this.refs.command.value)
ev.trigger('disp_add', prompt + command + '\n')
ev.trigger('cmd_entered', command)
this.refs.command.value = ''
// Refocus to scroll display and keep input in view.
this.refs.command.blur()
this.refs.command.focus()
event.preventDefault()
}
encode(text) {
return text.replace(/&/g,'&').replace(//g,'>')
}
this.on('mount', function() { this.write() })
this.on('update', function() { this.write() })
write() { this.root.innerHTML = opts.content }