From 224eb8b71b7c18f8b0ffa132a3d69f03881e62fb Mon Sep 17 00:00:00 2001 From: serapath Date: Sat, 2 Sep 2017 20:31:00 +0200 Subject: [PATCH] REFACTOR terminal api + build index structure for filtering --- src/app/execution/txLogger.js | 16 ++-- src/app/panels/editor-panel.js | 8 +- src/app/panels/terminal.js | 140 +++++++++++++++++++-------------- 3 files changed, 91 insertions(+), 73 deletions(-) diff --git a/src/app/execution/txLogger.js b/src/app/execution/txLogger.js index 84781976b9..3a4e35885c 100644 --- a/src/app/execution/txLogger.js +++ b/src/app/execution/txLogger.js @@ -16,11 +16,15 @@ class TxLogger { constructor (opts = {}) { this.event = new EventManager() this.opts = opts - opts.api.editorpanel.registerLogType('knownTransaction', (data) => { - return renderKnownTransaction(this, data) + this.logKnownTX = opts.api.editorpanel.registerCommand('knownTransaction', (args, cmds, append) => { + var data = args[0] + var el = renderKnownTransaction(this, data) + append(el) }) - opts.api.editorpanel.registerLogType('unknownTransaction', (data) => { - return renderUnknownTransaction(this, data) + this.logUnknownTX = opts.api.editorpanel.registerCommand('unknownTransaction', (args, cmds, append) => { + var data = args[0] + var el = renderUnknownTransaction(this, data) + append(el) }) opts.api.editorpanel.registerLogType('emptyBlock', (data) => { return renderEmptyBlock(this, data) @@ -43,12 +47,12 @@ function log (self, tx, api) { if (resolvedTransaction) { api.parseLogs(tx, resolvedTransaction.contractName, api.compiledContracts(), (error, logs) => { if (!error) { - api.editorpanel.log({type: 'knownTransaction', value: { tx: tx, resolvedData: resolvedTransaction, logs: logs }}) + self.logKnownTX({ tx: tx, resolvedData: resolvedTransaction, logs: logs }) } }) } else { // contract unknown - just displaying raw tx. - api.editorpanel.log({ type: 'unknownTransaction', value: { tx: tx } }) + self.logUnknownTX({ tx: tx }) } } diff --git a/src/app/panels/editor-panel.js b/src/app/panels/editor-panel.js index 4674232e05..94795b2420 100644 --- a/src/app/panels/editor-panel.js +++ b/src/app/panels/editor-panel.js @@ -215,13 +215,9 @@ class EditorPanel { self._adjustLayout('top', self.data._layout.top.offset) return self._view.el } - registerLogType (typename, template) { + registerCommand (name, command) { var self = this - self._components.terminal.registerType(typename, template) - } - log () { - var self = this - self._components.terminal._output.apply(self._components.terminal, arguments) + return self._components.terminal.registerCommand(name, command) } _renderTabsbar () { var self = this diff --git a/src/app/panels/terminal.js b/src/app/panels/terminal.js index 053509213a..f26103e94a 100644 --- a/src/app/panels/terminal.js +++ b/src/app/panels/terminal.js @@ -91,17 +91,7 @@ var css = csjs` outline : none; font-family : monospace; } - - .error { - color : red; - } - .info { - color : blue; - } - .log { - color : black; - } - + .dragbarHorizontal { position : absolute; top : 0; @@ -201,10 +191,23 @@ class Terminal { console.log('select', label) }) self._view = { el: null, bar: null, input: null, term: null, journal: null, cli: null } - self._templates = {} - self.logger = {} - ;['log', 'info', 'error'].forEach(typename => { - self.registerType(typename, self._blocksRenderer(typename)) + self._commands = {} + self.commands = {} + self._INDEX = {} + self._INDEX.all = [] + self._INDEX.allMain = [] + self._INDEX.commands = {} + self._INDEX.commandsMain = {} + self.registerCommand('log', self._blocksRenderer('log')) + self.registerCommand('info', self._blocksRenderer('info')) + self.registerCommand('error', self._blocksRenderer('error')) + self.registerCommand('script', function execute (args, scopedCommands, append) { + var script = String(args[0]) + scopedCommands.log(`> ${script}`) + self._shell(script, function (error, output) { + if (error) scopedCommands.error(error) + else scopedCommands.log(output) + }) }) self._jsSandboxContext = {} self._jsSandbox = vm.createContext(self._jsSandboxContext) @@ -253,7 +256,7 @@ class Terminal { ${self._view.term} ` - self._output(self.data.banner) + self.commands.log(self.data.banner) function throttle (fn, wait) { var time = Date.now() @@ -466,12 +469,17 @@ class Terminal { editable.focus() } } + scroll2bottom () { + var self = this + setTimeout(function () { + self._view.term.scrollTop = self._view.term.scrollHeight + }, 0) + } _blocksRenderer (mode) { var self = this - var modes = { log: true, info: true, error: true } - if (modes[mode]) { - return function render () { - var args = [].slice.call(arguments) + mode = { log: 'black', info: 'blue', error: 'red' }[mode] // defaults + if (mode) { + return function logger (args, scopedCommands, append) { var types = args.map(type) var values = javascriptserialize.apply(null, args).map(function (val, idx) { if (typeof args[idx] === 'string') val = args[idx] @@ -480,59 +488,67 @@ class Terminal { var lines = val.match(new RegExp(pattern, 'g')) return lines.map(str => document.createTextNode(`${str}\n`)) }) - return values + append(yo`${values}`) } } else { throw new Error('mode is not supported') } } - execute (script) { + _scopeCommands (append) { var self = this - script = String(script) - self._output({ type: 'log', value: `> ${script}` }) - self._shell(script, function (error, output) { - if (error) { - self._output({ type: 'error', value: error }) - return error - } else { - self._output({ type: 'log', value: output }) - return output + var scopedCommands = {} + Object.keys(self.commands).forEach(function makeScopedCommand (cmd) { + var command = self._commands[cmd] + scopedCommands[cmd] = function _command () { + var args = arguments + command(args, scopedCommands, el => append(cmd, args, el)) } }) + return scopedCommands } - registerType (typename, template) { - var self = this - if (typeof template !== 'function') throw new Error('invalid template') - self._templates[typename] = template - self.logger[typename] = function () { - var args = [...arguments].map(x => ({ type: typename, value: x })) - self._output.apply(self, args) - } - } - _output () { + registerCommand (name, command) { var self = this - var args = [...arguments] - self.data.session.push(args) - args.forEach(function (data) { - if (!data || !data.type) data = { type: 'log', value: data } - var render = self._templates[data.type] - var blocks = render(data.value) - blocks = [].concat(blocks) - blocks.forEach(function (block) { + name = String(name) + if (self._commands[name]) throw new Error(`command "${name}" exists already`) + if (typeof command !== 'function') throw new Error(`invalid command: ${command}`) + self._commands[name] = command + self._INDEX.commands[name] = [] + self._INDEX.commandsMain[name] = [] + self.commands[name] = function _command () { + var args = [...arguments] + var steps = [] + var root = { steps, cmd: name } + var ITEM = { root, cmd: name } + root.gidx = self._INDEX.allMain.push(ITEM) - 1 + root.idx = self._INDEX.commandsMain[name].push(ITEM) - 1 + function append (cmd, params, el) { + var item + if (cmd) { // subcommand + item = { el, cmd, root } + } else { // command + item = ITEM + item.el = el + cmd = name + } + item.gidx = self._INDEX.all.push(item) - 1 + item.idx = self._INDEX.commands[cmd].push(item) - 1 + item.step = steps.push(item) - 1 + item.args = params self._view.journal.appendChild(yo` -
- ${block} -
+
${el}
`) self.scroll2bottom() - }) - }) - } - scroll2bottom () { - var self = this - setTimeout(function () { - self._view.term.scrollTop = self._view.term.scrollHeight - }, 0) + } + var scopedCommands = self._scopeCommands(append) + command(args, scopedCommands, el => append(null, args, el)) + } + var help = typeof command.help === 'string' ? command.help : [ + `// no help available for:`, + `terminal.commands.${name}(...)` + ].join('\n') + self.commands[name].toString = _ => { return help } + self.commands[name].help = help + return self.commands[name] } _shell (script, done) { // default shell var self = this @@ -552,7 +568,9 @@ function domTerminalFeatures (self) { return { web3: executionContext.getProvider() !== 'vm' ? new Web3(executionContext.web3().currentProvider) : null, console: { - log: function () { self._output.apply(self, arguments) } + log: function () { self.commands.log.apply(null, arguments) }, + info: function () { self.commands.info.apply(null, arguments) }, + error: function () { self.commands.error.apply(null, arguments) } } } }