diff --git a/src/app.js b/src/app.js index 66144b68c2..bfef9b84b4 100644 --- a/src/app.js +++ b/src/app.js @@ -46,6 +46,7 @@ var BasicReadOnlyExplorer = require('./app/files/basicReadOnlyExplorer') var NotPersistedExplorer = require('./app/files/NotPersistedExplorer') var toolTip = require('./app/ui/tooltip') var CommandInterpreter = require('./lib/cmdInterpreter') +var TransactionReceiptResolver = require('./transactionReceiptResolver') var styleGuide = require('./app/ui/styles-guide/theme-chooser') var styles = styleGuide.chooser() @@ -339,8 +340,9 @@ Please make a backup of your contracts and start using http://remix.ethereum.org self._components.compiler = new Compiler(importFileCb) var compiler = self._components.compiler registry.put({api: compiler, name: 'compiler'}) - var offsetToLineColumnConverter = new OffsetToLineColumnConverter(compiler.event) + var offsetToLineColumnConverter = new OffsetToLineColumnConverter(compiler.event) + registry.put({api: offsetToLineColumnConverter, name: 'offsetToLineColumnConverter'}) // ----------------- UniversalDApp ----------------- var transactionContextAPI = { getAddress: (cb) => { @@ -387,22 +389,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org }) // ----------------- Tx listener ----------------- - var transactionReceiptResolver = { - _transactionReceipts: {}, - resolve: function (tx, cb) { - if (this._transactionReceipts[tx.hash]) { - return cb(null, this._transactionReceipts[tx.hash]) - } - executionContext.web3().eth.getTransactionReceipt(tx.hash, (error, receipt) => { - if (!error) { - this._transactionReceipts[tx.hash] = receipt - cb(null, receipt) - } else { - cb(error) - } - }) - } - } + var transactionReceiptResolver = new TransactionReceiptResolver() var compiledContracts = function () { if (compiler.lastCompilationResult && compiler.lastCompilationResult.data) { @@ -497,100 +484,37 @@ Please make a backup of your contracts and start using http://remix.ethereum.org }) }) + registry.put({api: cmdInterpreter, name: 'cmdinterpreter'}) + // ----------------- editor ---------------------------- this._components.editor = new Editor({}) // @TODO: put into editorpanel var editor = self._components.editor // shortcut for the editor registry.put({api: editor, name: 'editor'}) - // ---------------- ContextualListener ----------------------- - this._components.contextualListener = new ContextualListener({ - getCursorPosition: () => { - return this._components.editor.getCursorPosition() - }, - getCompilationResult: () => { - return compiler.lastCompilationResult - }, - getCurrentFile: () => { - return config.get('currentFile') - }, - getSourceName: (index) => { - return compiler.getSourceName(index) - }, - highlight: (position, node) => { - if (compiler.lastCompilationResult && compiler.lastCompilationResult.data) { - var lineColumn = offsetToLineColumnConverter.offsetToLineColumn(position, position.file, compiler.lastCompilationResult) - var css = 'highlightreference' - if (node.children && node.children.length) { - // If node has children, highlight the entire line. if not, just highlight the current source position of the node. - css = 'highlightreference' - lineColumn = { - start: { - line: lineColumn.start.line, - column: 0 - }, - end: { - line: lineColumn.start.line + 1, - column: 0 - } - } - } - var fileName = compiler.getSourceName(position.file) - if (fileName) { - return editor.addMarker(lineColumn, fileName, css) - } - } - return null - }, - stopHighlighting: (event) => { - editor.removeMarker(event.eventId, event.fileTarget) - } - }, { - compiler: compiler.event, - editor: editor.event + var config = self._api.config + var filesProviders = self._api.filesProviders + + // ----------------- file manager ---------------------------- + + self._components.fileManager = new FileManager({ + config: config, + editor: editor, + filesProviders: filesProviders, + compilerImport: self._components.compilerImport }) + var fileManager = self._components.fileManager + registry.put({api: fileManager, name: 'filemanager'}) + + // ---------------- ContextualListener ----------------------- + this._components.contextualListener = new ContextualListener() + registry.put({api: this._components.contextualListener, name: 'contextualListener'}) // ---------------- ContextView ----------------------- - this._components.contextView = new ContextView({ - contextualListener: this._components.contextualListener, - jumpTo: (position) => { - function jumpToLine (lineColumn) { - if (lineColumn.start && lineColumn.start.line && lineColumn.start.column) { - editor.gotoLine(lineColumn.start.line, lineColumn.end.column + 1) - } - } - if (compiler.lastCompilationResult && compiler.lastCompilationResult.data) { - var lineColumn = offsetToLineColumnConverter.offsetToLineColumn(position, position.file, compiler.lastCompilationResult) - var filename = compiler.getSourceName(position.file) - // TODO: refactor with rendererAPI.errorClick - if (filename !== config.get('currentFile')) { - var provider = fileManager.fileProviderOf(filename) - if (provider) { - provider.exists(filename, (error, exist) => { - if (error) return console.log(error) - fileManager.switchFile(filename) - jumpToLine(lineColumn) - }) - } - } else { - jumpToLine(lineColumn) - } - } - } - }, { - contextualListener: this._components.contextualListener.event - }) + this._components.contextView = new ContextView() + registry.put({api: this._components.contextView, name: 'contextview'}) // ----------------- editor panel ---------------------- - this._components.editorpanel = new EditorPanel({ - api: { - cmdInterpreter: cmdInterpreter, - editor: self._components.editor, - config: self._api.config, - txListener: txlistener, - contextview: self._components.contextView, - udapp: () => { return udapp } - } - }) + this._components.editorpanel = new EditorPanel() registry.put({ api: this._components.editorpanel, name: 'editorpanel' }) this._components.editorpanel.event.register('resize', direction => self._adjustLayout(direction)) @@ -612,18 +536,6 @@ Please make a backup of your contracts and start using http://remix.ethereum.org this.event = new EventManager() - var config = self._api.config - var filesProviders = self._api.filesProviders - - self._components.fileManager = new FileManager({ - config: config, - editor: editor, - filesProviders: filesProviders, - compilerImport: self._components.compilerImport - }) - var fileManager = self._components.fileManager - registry.put({api: fileManager, name: 'filemanager'}) - // Add files received from remote instance (i.e. another remix-ide) function loadFiles (filesSet, fileProvider, callback) { if (!fileProvider) fileProvider = 'browser' diff --git a/src/app/editor/contextView.js b/src/app/editor/contextView.js index 1913ebdacf..014ed1efd7 100644 --- a/src/app/editor/contextView.js +++ b/src/app/editor/contextView.js @@ -2,6 +2,7 @@ var yo = require('yo-yo') var remixLib = require('remix-lib') var SourceMappingDecoder = remixLib.SourceMappingDecoder +var globalRegistry = require('../../global/registry') var css = require('./styles/contextView-styles') @@ -13,15 +14,24 @@ var css = require('./styles/contextView-styles') - rename declaration/references */ class ContextView { - constructor (api, event) { - this._api = api - this._event = event + constructor (localRegistry) { + const self = this + self._components = {} + self._components.registry = localRegistry || globalRegistry + self._deps = { + contextualListener: self._components.registry.get('contextualListener').api, + editor: self._components.registry.get('editor').api, + compiler: self._components.registry.get('compiler').api, + offsetToLineColumnConverter: self._components.registry.get('offsetToLineColumnConverter').api, + config: self._components.registry.get('config').api, + fileManager: self._components.registry.get('filemanager').api + } this._view this._nodes this._current this.sourceMappingDecoder = new SourceMappingDecoder() this.previousElement = null - event.contextualListener.register('contextChanged', nodes => { + self._deps.contextualListener.event.register('contextChanged', nodes => { this._nodes = nodes this.update() }) @@ -66,7 +76,7 @@ class ContextView { if (isDefinition(last)) { this._current = last } else { - var target = this._api.contextualListener.declarationOf(last) + var target = this._deps.contextualListener.declarationOf(last) if (target) { this._current = target } else { @@ -80,15 +90,41 @@ class ContextView { return this.previousElement } + _jumpToInternal (position) { + var self = this + function jumpToLine (lineColumn) { + if (lineColumn.start && lineColumn.start.line && lineColumn.start.column) { + self._deps.editor.gotoLine(lineColumn.start.line, lineColumn.end.column + 1) + } + } + if (self._deps.compiler.lastCompilationResult && self._deps.compiler.lastCompilationResult.data) { + var lineColumn = self._deps.offsetToLineColumnConverter.offsetToLineColumn(position, position.file, self._deps.compiler.lastCompilationResult) + var filename = self._deps.compiler.getSourceName(position.file) + // TODO: refactor with rendererAPI.errorClick + if (filename !== self._deps.config.get('currentFile')) { + var provider = self._deps.fileManager.fileProviderOf(filename) + if (provider) { + provider.exists(filename, (error, exist) => { + if (error) return console.log(error) + self._deps.fileManager.switchFile(filename) + jumpToLine(lineColumn) + }) + } + } else { + jumpToLine(lineColumn) + } + } + } + _render (node, nodeAtCursorPosition) { if (!node) return yo`
` var self = this - var references = this._api.contextualListener.referencesOf(node) + var references = self._deps.contextualListener.referencesOf(node) var type = (node.attributes && node.attributes.type) ? node.attributes.type : node.name references = `${references ? references.length : '0'} reference(s)` var ref = 0 - var nodes = self._api.contextualListener.getActiveHighlights() + var nodes = self._deps.contextualListener.getActiveHighlights() for (var k in nodes) { if (nodeAtCursorPosition.id === nodes[k].nodeId) { ref = k @@ -101,14 +137,14 @@ class ContextView { e.target.dataset.action === 'next' ? ref++ : ref-- if (ref < 0) ref = nodes.length - 1 if (ref >= nodes.length) ref = 0 - self._api.jumpTo(nodes[ref].position) + self._jumpToInternal(nodes[ref].position) } function jumpTo () { if (node && node.src) { var position = self.sourceMappingDecoder.decode(node.src) if (position) { - self._api.jumpTo(position) + self._jumpToInternal(position) } } } @@ -125,7 +161,7 @@ class ContextView { function showGasEstimation () { if (node.name === 'FunctionDefinition') { - var result = self._api.contextualListener.gasEstimation(node) + var result = self._deps.contextualListener.gasEstimation(node) var executionCost = 'Execution cost: ' + result.executionCost + ' gas' var codeDepositCost = 'Code deposit cost: ' + result.codeDepositCost + ' gas' var estimatedGas = result.codeDepositCost ? `${codeDepositCost}, ${executionCost}` : `${executionCost}` diff --git a/src/app/editor/contextualListener.js b/src/app/editor/contextualListener.js index 4f2ea3865d..903aa91d3f 100644 --- a/src/app/editor/contextualListener.js +++ b/src/app/editor/contextualListener.js @@ -3,21 +3,30 @@ var remixLib = require('remix-lib') var SourceMappingDecoder = remixLib.SourceMappingDecoder var AstWalker = remixLib.AstWalker var EventManager = remixLib.EventManager +var globalRegistry = require('../../global/registry') /* trigger contextChanged(nodes) */ class ContextualListener { - constructor (api, events) { + constructor (localRegistry) { + var self = this this.event = new EventManager() - this._api = api + self._components = {} + self._components.registry = localRegistry || globalRegistry + self._deps = { + compiler: self._components.registry.get('compiler').api, + editor: self._components.registry.get('editor').api, + config: self._components.registry.get('config').api, + offsetToLineColumnConverter: self._components.registry.get('offsetToLineColumnConverter').api + } this._index = { Declarations: {}, FlatReferences: {} } this._activeHighlights = [] - events.compiler.register('compilationFinished', (success, data, source) => { + self._deps.compiler.event.register('compilationFinished', (success, data, source) => { this._stopHighlighting() this._index = { Declarations: {}, @@ -28,12 +37,12 @@ class ContextualListener { } }) - events.editor.register('contentChanged', () => { this._stopHighlighting() }) + self._deps.editor.event.register('contentChanged', () => { this._stopHighlighting() }) this.sourceMappingDecoder = new SourceMappingDecoder() this.astWalker = new AstWalker() setInterval(() => { - this._highlightItems(api.getCursorPosition(), api.getCompilationResult(), api.getCurrentFile()) + this._highlightItems(self._deps.editor.getCursorPosition(), self._deps.compiler.lastCompilationResult, self._deps.config.get('currentFile')) }, 1000) } @@ -94,13 +103,41 @@ class ContextualListener { _highlight (node, compilationResult) { if (!node) return + var self = this var position = this.sourceMappingDecoder.decode(node.src) - var eventId = this._api.highlight(position, node) + var eventId = this._highlightInternal(position, node) if (eventId) { - this._activeHighlights.push({ eventId, position, fileTarget: this._api.getSourceName(position.file), nodeId: node.id }) + this._activeHighlights.push({ eventId, position, fileTarget: self._deps.compiler.getSourceName(position.file), nodeId: node.id }) } } + _highlightInternal (position, node) { + var self = this + if (self._deps.compiler.lastCompilationResult && self._deps.compiler.lastCompilationResult.data) { + var lineColumn = self._deps.offsetToLineColumnConverter.offsetToLineColumn(position, position.file, self._deps.compiler.lastCompilationResult) + var css = 'highlightreference' + if (node.children && node.children.length) { + // If node has children, highlight the entire line. if not, just highlight the current source position of the node. + css = 'highlightreference' + lineColumn = { + start: { + line: lineColumn.start.line, + column: 0 + }, + end: { + line: lineColumn.start.line + 1, + column: 0 + } + } + } + var fileName = self._deps.compiler.getSourceName(position.file) + if (fileName) { + return self._deps.editor.addMarker(lineColumn, fileName, css) + } + } + return null + } + _highlightExpressions (node, compilationResult) { var self = this function highlights (id) { @@ -124,8 +161,10 @@ class ContextualListener { } _stopHighlighting () { - for (var event in this._activeHighlights) { - this._api.stopHighlighting(this._activeHighlights[event]) + var self = this + for (var eventKey in this._activeHighlights) { + var event = this._activeHighlights[eventKey] + self._deps.editor.removeMarker(event.eventId, event.fileTarget) } this._activeHighlights = [] } diff --git a/src/app/panels/editor-panel.js b/src/app/panels/editor-panel.js index 370a14683a..2c00a74ac8 100644 --- a/src/app/panels/editor-panel.js +++ b/src/app/panels/editor-panel.js @@ -3,32 +3,42 @@ var remixLib = require('remix-lib') var EventManager = remixLib.EventManager var Terminal = require('./terminal') +var globalRegistry = require('../../global/registry') var styles = require('./styles/editor-panel-styles') var cssTabs = styles.cssTabs var css = styles.css class EditorPanel { - constructor (opts = {}) { + constructor (localRegistry) { var self = this - self._api = opts.api + self._components = {} + self._components.registry = localRegistry || globalRegistry + self._deps = { + config: self._components.registry.get('config').api, + editor: self._components.registry.get('editor').api, + txlistener: self._components.registry.get('txlistener').api, + contextView: self._components.registry.get('contextview').api, + udapp: self._components.registry.get('udapp').api, + cmdInterpreter: self._components.registry.get('cmdinterpreter').api + } self.event = new EventManager() self.data = { _FILE_SCROLL_DELTA: 200, _layout: { top: { - offset: self._api.config.get('terminal-top-offset') || 500, + offset: self._deps.config.get('terminal-top-offset') || 500, show: true } } } self._view = {} self._components = { - editor: opts.api.editor, // @TODO: instantiate in eventpanel instead of passing via `opts` + editor: self._deps.editor, // @TODO: instantiate in eventpanel instead of passing via `opts` terminal: new Terminal({ api: { - cmdInterpreter: self._api.cmdInterpreter, - udapp: self._api.udapp, + cmdInterpreter: self._deps.cmdInterpreter, + udapp: self._deps.udapp, getPosition (event) { var limitUp = 36 var limitDown = 20 @@ -36,12 +46,6 @@ class EditorPanel { var newpos = (event.pageY < limitUp) ? limitUp : event.pageY newpos = (newpos < height - limitDown) ? newpos : height - limitDown return newpos - }, - web3 () { - return self._api.web3() - }, - context () { - return self._api.context() } } }) @@ -50,9 +54,9 @@ class EditorPanel { this.event.trigger('terminalFilterChanged', [type, value]) }) self._components.terminal.event.register('resize', delta => self._adjustLayout('top', delta)) - if (self._api.txListener) { + if (self._deps.txListener) { self._components.terminal.event.register('listenOnNetWork', (listenOnNetWork) => { - self._api.txListener.setListenOnNetwork(listenOnNetWork) + self._deps.txListener.setListenOnNetwork(listenOnNetWork) }) } if (document && document.head) { @@ -72,7 +76,7 @@ class EditorPanel { else delta = containerHeight } else { layout.show = true - self._api.config.set(`terminal-${direction}-offset`, delta) + self._deps.config.set(`terminal-${direction}-offset`, delta) layout.offset = delta } } @@ -113,7 +117,7 @@ class EditorPanel {
${self._renderTabsbar()}
- ${self._api.contextview.render()} + ${self._deps.contextView.render()}
${self._view.editor} ${self._view.terminal} diff --git a/src/app/panels/terminal.js b/src/app/panels/terminal.js index 4dce6b3c58..7d79fa2d85 100644 --- a/src/app/panels/terminal.js +++ b/src/app/panels/terminal.js @@ -580,7 +580,7 @@ function domTerminalFeatures (self, scopedCommands) { function blockify (el) { return yo`
${el}
` } // PENDING TX function updatePendingTxs (api, el) { - var count = Object.keys(api.udapp().pendingTransactions()).length + var count = Object.keys(api.udapp.pendingTransactions()).length el.innerText = count } diff --git a/src/transactionReceiptResolver.js b/src/transactionReceiptResolver.js new file mode 100644 index 0000000000..b94e871973 --- /dev/null +++ b/src/transactionReceiptResolver.js @@ -0,0 +1,23 @@ +'use strict' +var executionContext = require('./execution-context') + +module.exports = class TransactionReceiptResolver { + constructor () { + this._transactionReceipts = {} + } + + resolve (tx, cb) { + if (this._transactionReceipts[tx.hash]) { + return cb(null, this._transactionReceipts[tx.hash]) + } + executionContext.web3().eth.getTransactionReceipt(tx.hash, (error, receipt) => { + if (!error) { + this._transactionReceipts[tx.hash] = receipt + cb(null, receipt) + } else { + cb(error) + } + }) + } +} +