diff --git a/src/app.js b/src/app.js index 35d531f99a..5bad821530 100644 --- a/src/app.js +++ b/src/app.js @@ -46,7 +46,6 @@ var BasicReadOnlyExplorer = require('./app/files/basicReadOnlyExplorer') var NotPersistedExplorer = require('./app/files/NotPersistedExplorer') var toolTip = require('./app/ui/tooltip') var CommandInterpreter = require('./lib/cmdInterpreter') -var PluginAPI = require('./app/plugin/pluginAPI') var styleGuide = require('./app/ui/styles-guide/theme-chooser') var styles = styleGuide.chooser() @@ -117,16 +116,26 @@ class App { constructor (api = {}, events = {}, opts = {}) { var self = this self._api = {} + registry.put({api: self, name: 'app'}) var fileStorage = new Storage('sol:') + registry.put({api: fileStorage, name: 'fileStorage'}) + var configStorage = new Storage('config:') + registry.put({api: configStorage, name: 'configStorage'}) + self._api.config = new Config(fileStorage) + registry.put({api: self._api.config, name: 'config'}) + executionContext.init(self._api.config) executionContext.listenOnLastBlock() self._api.filesProviders = {} self._api.filesProviders['browser'] = new Browserfiles(fileStorage) self._api.filesProviders['config'] = new BrowserfilesTree('config', configStorage) self._api.filesProviders['config'].init() + registry.put({api: self._api.filesProviders['browser'], name: 'fileProviders/browser'}) + registry.put({api: self._api.filesProviders['config'], name: 'fileProviders/config'}) var remixd = new Remixd() + registry.put({api: remixd, name: 'remixd/config'}) remixd.event.register('system', (message) => { if (message.error) toolTip(message.error) }) @@ -135,9 +144,15 @@ class App { self._api.filesProviders['github'] = new BasicReadOnlyExplorer('github') self._api.filesProviders['gist'] = new NotPersistedExplorer('gist') self._api.filesProviders['ipfs'] = new BasicReadOnlyExplorer('ipfs') + registry.put({api: self._api.filesProviders['localhost'], name: 'fileProviders/localhost'}) + registry.put({api: self._api.filesProviders['swarm'], name: 'fileProviders/swarm'}) + registry.put({api: self._api.filesProviders['github'], name: 'fileProviders/github'}) + registry.put({api: self._api.filesProviders['gist'], name: 'fileProviders/gist'}) + registry.put({api: self._api.filesProviders['ipfs'], name: 'fileProviders/ipfs'}) self._view = {} self._components = {} self._components.compilerImport = new CompilerImport() + registry.put({api: self._components.compilerImport, name: 'compilerImport'}) self.data = { _layout: { right: { @@ -207,6 +222,34 @@ class App { self._adjustLayout('right', self.data._layout.right.offset) return self._view.el } + runCompiler () { + const self = this + if (self._view.transactionDebugger.isActive) return + + self._components.fileManager.saveCurrentFile() + self._components.editor.clearAnnotations() + var currentFile = self._api.config.get('currentFile') + if (currentFile) { + if (/.(.sol)$/.exec(currentFile)) { + // only compile *.sol file. + var target = currentFile + var sources = {} + var provider = self._components.fileManager.fileProviderOf(currentFile) + if (provider) { + provider.get(target, (error, content) => { + if (error) { + console.log(error) + } else { + sources[target] = { content } + self._components.compiler.compile(sources, target) + } + }) + } else { + console.log('cannot compile ' + currentFile + '. Does not belong to any explorer') + } + } + } + } } module.exports = App @@ -242,7 +285,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org // ctrl+s or command+s if ((e.metaKey || e.ctrlKey) && e.keyCode === 83) { e.preventDefault() - runCompiler() + self.runCompiler() } }) @@ -293,7 +336,8 @@ Please make a backup of your contracts and start using http://remix.ethereum.org } // ----------------- Compiler ----------------- - var compiler = new Compiler(importFileCb) + self._components.compiler = new Compiler(importFileCb) + var compiler = self._components.compiler registry.put({api: compiler, name: 'compiler'}) var offsetToLineColumnConverter = new OffsetToLineColumnConverter(compiler.event) @@ -327,6 +371,8 @@ Please make a backup of your contracts and start using http://remix.ethereum.org cb(null, $('#gasLimit').val()) } } + // @TODO should put this in runtab + registry.put({api: transactionContextAPI, name: 'transactionContextAPI'}) var udapp = new UniversalDApp({ api: { @@ -346,10 +392,12 @@ Please make a backup of your contracts and start using http://remix.ethereum.org }, opt: { removable: false, removable_instances: true } }) + registry.put({api: udapp, name: 'udapp'}) var udappUI = new UniversalDAppUI(udapp) + registry.put({api: udappUI, name: 'udappUI'}) - udapp.reset({}, transactionContextAPI) + udapp.reset({}) udappUI.reset() udapp.event.register('debugRequested', this, function (txResult) { startdebugging(txResult.transactionHash) @@ -389,6 +437,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org event: { udapp: udapp.event }}) + registry.put({api: txlistener, name: 'txlistener'}) var eventsDecoder = new EventsDecoder({ api: { @@ -397,6 +446,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org } } }) + registry.put({api: eventsDecoder, name: 'eventsDecoder'}) txlistener.startListening() @@ -467,6 +517,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org // ----------------- 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({ @@ -557,6 +608,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org udapp: () => { return udapp } } }) + registry.put({ api: this._components.editorpanel, name: 'editorpanel' }) this._components.editorpanel.event.register('resize', direction => self._adjustLayout(direction)) this._view.centerpanel.appendChild(this._components.editorpanel.render()) @@ -580,12 +632,14 @@ Please make a backup of your contracts and start using http://remix.ethereum.org var config = self._api.config var filesProviders = self._api.filesProviders - var fileManager = new FileManager({ + 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) { @@ -715,6 +769,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org } } var renderer = new Renderer(rendererAPI) + registry.put({api: renderer, name: 'renderer'}) // ----------------- StaticAnalysis ----------------- @@ -727,84 +782,10 @@ Please make a backup of your contracts and start using http://remix.ethereum.org } } var staticanalysis = new StaticAnalysis(staticAnalysisAPI, compiler.event) + registry.put({api: staticanalysis, name: 'staticanalysis'}) // ---------------- Righthand-panel -------------------- - - var rhpAPI = { - importFileCb: importFileCb, - filesFromPath: (path, cb) => { - fileManager.filesFromPath(path, cb) - }, - newAccount: (pass, cb) => { - udapp.newAccount(pass, cb) - }, - setEditorSize (delta) { - $('#righthand-panel').css('width', delta) - self._view.centerpanel.style.right = delta + 'px' - document.querySelector(`.${css.dragbar2}`).style.right = delta + 'px' - onResize() - }, - switchFile: function (path) { - fileManager.switchFile(path) - }, - filesProviders: filesProviders, - fileProviderOf: (path) => { - return fileManager.fileProviderOf(path) - }, - fileProvider: (name) => { - return self._api.filesProviders[name] - }, - currentPath: function () { - return fileManager.currentPath() - }, - getBalance: (address, callback) => { - udapp.getBalance(address, (error, balance) => { - if (error) { - callback(error) - } else { - callback(null, executionContext.web3().fromWei(balance, 'ether')) - } - }) - }, - currentCompiledSourceCode: () => { - if (compiler.lastCompilationResult.source) { - return compiler.lastCompilationResult.source.sources[compiler.lastCompilationResult.source.target] - } - return '' - }, - resetDapp: (contracts) => { - udapp.reset(contracts, transactionContextAPI) - udappUI.reset() - }, - setOptimize: (optimize, runCompilation) => { - compiler.setOptimize(optimize) - if (runCompilation) runCompiler() - }, - runCompiler: () => { - runCompiler() - }, - logMessage: (msg) => { - self._components.editorpanel.log({type: 'log', value: msg}) - } - } - var rhpEvents = { - compiler: compiler.event, - app: self.event, - udapp: udapp.event, - editor: editor.event, - staticAnalysis: staticanalysis.event - } - var rhpOpts = { - pluginAPI: new PluginAPI(self, compiler), - udapp: udapp, - udappUI: udappUI, - compiler: compiler, - renderer: renderer, - editor: editor, - config: config - } - - self._components.righthandpanel = new RighthandPanel(rhpAPI, rhpEvents, rhpOpts) + self._components.righthandpanel = new RighthandPanel() self._view.rightpanel.appendChild(self._components.righthandpanel.render()) self._components.righthandpanel.init() self._components.righthandpanel.event.register('resize', delta => self._adjustLayout('right', delta)) @@ -861,11 +842,11 @@ Please make a backup of your contracts and start using http://remix.ethereum.org return offsetToLineColumnConverter.offsetToLineColumn(location, file, compiler.lastCompilationResult) } } - var transactionDebugger = new Debugger('#debugger', debugAPI, editor.event) - transactionDebugger.addProvider('vm', executionContext.vm()) - transactionDebugger.addProvider('injected', executionContext.internalWeb3()) - transactionDebugger.addProvider('web3', executionContext.internalWeb3()) - transactionDebugger.switchProvider(executionContext.getProvider()) + self._view.transactionDebugger = new Debugger('#debugger', debugAPI, editor.event) + self._view.transactionDebugger.addProvider('vm', executionContext.vm()) + self._view.transactionDebugger.addProvider('injected', executionContext.internalWeb3()) + self._view.transactionDebugger.addProvider('web3', executionContext.internalWeb3()) + self._view.transactionDebugger.switchProvider(executionContext.getProvider()) var txLogger = new TxLogger({ api: { @@ -889,34 +870,6 @@ Please make a backup of your contracts and start using http://remix.ethereum.org startdebugging(hash) }) - function runCompiler () { - if (transactionDebugger.isActive) return - - fileManager.saveCurrentFile() - editor.clearAnnotations() - var currentFile = config.get('currentFile') - if (currentFile) { - if (/.(.sol)$/.exec(currentFile)) { - // only compile *.sol file. - var target = currentFile - var sources = {} - var provider = fileManager.fileProviderOf(currentFile) - if (provider) { - provider.get(target, (error, content) => { - if (error) { - console.log(error) - } else { - sources[target] = { content } - compiler.compile(sources, target) - } - }) - } else { - console.log('cannot compile ' + currentFile + '. Does not belong to any explorer') - } - } - } - } - var previousInput = '' var saveTimeout = null @@ -950,16 +903,16 @@ Please make a backup of your contracts and start using http://remix.ethereum.org editor.event.register('sessionSwitched', editorOnChange) executionContext.event.register('contextChanged', this, function (context) { - runCompiler() + self.runCompiler() }) executionContext.event.register('web3EndpointChanged', this, function (context) { - runCompiler() + self.runCompiler() }) compiler.event.register('compilerLoaded', this, function (version) { previousInput = '' - runCompiler() + self.runCompiler() if (queryParams.get().context) { let context = queryParams.get().context @@ -987,6 +940,6 @@ Please make a backup of your contracts and start using http://remix.ethereum.org function startdebugging (txHash) { self.event.trigger('debuggingRequested', []) - transactionDebugger.debug(txHash) + self._view.transactionDebugger.debug(txHash) } } diff --git a/src/app/editor/editor.js b/src/app/editor/editor.js index 008a1aa6b1..a67e5dd4de 100644 --- a/src/app/editor/editor.js +++ b/src/app/editor/editor.js @@ -65,7 +65,6 @@ document.head.appendChild(yo` function Editor (opts = {}) { var self = this - var el = yo`
` var editor = ace.edit(el) if (styles.appProperties.aceTheme) { @@ -104,14 +103,14 @@ function Editor (opts = {}) { var breakpoints = e.editor.session.getBreakpoints() for (var k in breakpoints) { if (k === row.toString()) { - self.event.trigger('breakpointCleared', [currentSession, row]) + event.trigger('breakpointCleared', [currentSession, row]) e.editor.session.clearBreakpoint(row) e.stop() return } } self.setBreakpoint(row) - self.event.trigger('breakpointAdded', [currentSession, row]) + event.trigger('breakpointAdded', [currentSession, row]) e.stop() }) @@ -278,10 +277,10 @@ function Editor (opts = {}) { // Do setup on initialisation here editor.on('changeSession', function () { - self.event.trigger('sessionSwitched', []) + event.trigger('sessionSwitched', []) editor.getSession().on('change', function () { - self.event.trigger('contentChanged', []) + event.trigger('contentChanged', []) }) }) diff --git a/src/app/panels/editor-panel.js b/src/app/panels/editor-panel.js index 4762ffa41c..6ecd460c70 100644 --- a/src/app/panels/editor-panel.js +++ b/src/app/panels/editor-panel.js @@ -96,6 +96,10 @@ class EditorPanel { var command = self._components.terminal.commands[data.type] if (typeof command === 'function') command(data.value) } + logMessage (msg) { + var self = this + self.log({type: 'log', value: msg}) + } render () { var self = this if (self._view.el) return self._view.el diff --git a/src/app/panels/righthand-panel.js b/src/app/panels/righthand-panel.js index ae6fc8189e..dbdd6baa71 100644 --- a/src/app/panels/righthand-panel.js +++ b/src/app/panels/righthand-panel.js @@ -2,6 +2,8 @@ const yo = require('yo-yo') const csjs = require('csjs-inject') const remixLib = require('remix-lib') +var globalRegistry = require('../../global/registry') + const styleguide = require('../ui/styles-guide/theme-chooser') const PluginManager = require('../plugin/pluginManager') const TabbedMenu = require('../tabs/tabbed-menu') @@ -18,32 +20,28 @@ const EventManager = remixLib.EventManager const styles = styleguide.chooser() module.exports = class RighthandPanel { - constructor (api = {}, events = {}, opts = {}) { + constructor (localRegistry) { const self = this + self._components = {} + self._components.registry = localRegistry || globalRegistry self.event = new EventManager() - self._api = api - self._api.switchTab = x => { // @TODO: refactor - if (self._components.tabbedMenu) self._components.tabbedMenu.selectTabByClassName(x) - } - self._events = events - self._events.rhp = self.event // @TODO: refactor - self._opts = opts self._view = { element: null, tabbedMenu: null, tabbedMenuViewport: null, dragbar: null } + self._components = { - pluginManager: new PluginManager(self._opts.pluginAPI, self._events), - tabbedMenu: new TabbedMenu(self._api, self._events), - compile: new CompileTab(self._api, self._events, self._opts), - run: new RunTab(self._api, self._events, self._opts), - settings: new SettingsTab(self._api, self._events, self._opts), - analysis: new AnalysisTab(self._api, self._events, self._opts), - debug: new DebuggerTab(self._api, self._events, self._opts), - support: new SupportTab(self._api, self._events, self._opts), - test: new TestTab(self._api, self._events, self._opts) + pluginManager: new PluginManager(), + tabbedMenu: new TabbedMenu(), + compile: new CompileTab(), + run: new RunTab(), + settings: new SettingsTab(), + analysis: new AnalysisTab(), + debug: new DebuggerTab(), + support: new SupportTab(), + test: new TestTab() } self.event.register('plugin-loadRequest', json => { diff --git a/src/app/plugin/pluginAPI.js b/src/app/plugin/pluginAPI.js index eb1f72322f..82119414c4 100644 --- a/src/app/plugin/pluginAPI.js +++ b/src/app/plugin/pluginAPI.js @@ -2,24 +2,24 @@ /* Defines available API. `key` / `type` */ -module.exports = (app, compiler) => { +module.exports = (registry) => { return { config: { setConfig: (mod, path, content, cb) => { - app._api.filesProviders['config'].set(mod + '/' + path, content) + registry.get('fileProviders/config').api.set(mod + '/' + path, content) cb() }, getConfig: (mod, path, cb) => { - cb(null, app._api.filesProviders['config'].get(mod + '/' + path)) + cb(null, registry.get('fileProviders/config').get(mod + '/' + path)) }, removeConfig: (mod, path, cb) => { - cb(null, app._api.filesProviders['config'].remove(mod + '/' + path)) + cb(null, registry.get('fileProviders/config').api.remove(mod + '/' + path)) if (cb) cb() } }, compiler: { getCompilationResult: () => { - return compiler.lastCompilationResult + return registry.get('compiler').api.lastCompilationResult } } } diff --git a/src/app/plugin/pluginManager.js b/src/app/plugin/pluginManager.js index 0c1c5ba955..462b457ea1 100644 --- a/src/app/plugin/pluginManager.js +++ b/src/app/plugin/pluginManager.js @@ -1,4 +1,7 @@ 'use strict' + +var globalRegistry = require('../../global/registry') +var PluginAPI = require('./pluginAPI') /** * Register and Manage plugin: * @@ -76,15 +79,19 @@ * */ module.exports = class PluginManager { - constructor (api = {}, events = {}, opts = {}) { + constructor (localRegistry) { const self = this - self._opts = opts - self._api = api - self._events = events self.plugins = {} + self._components = {} + self._components.registry = localRegistry || globalRegistry + self._components.pluginAPI = new PluginAPI(self._components.registry) + self._deps = { + compiler: self._components.registry.get('compiler').api, + app: self._components.registry.get('app').api + } self.inFocus self.allowedapi = {'setConfig': 1, 'getConfig': 1, 'removeConfig': 1} - self._events.compiler.register('compilationFinished', (success, data, source) => { + self._deps.compiler.event.register('compilationFinished', (success, data, source) => { if (self.inFocus) { // trigger to the current focus self.post(self.inFocus, JSON.stringify({ @@ -96,7 +103,7 @@ module.exports = class PluginManager { } }) - self._events.app.register('tabChanged', (tabName) => { + self._deps.app.event.register('tabChanged', (tabName) => { if (self.inFocus && self.inFocus !== tabName) { // trigger unfocus self.post(self.inFocus, JSON.stringify({ @@ -119,7 +126,7 @@ module.exports = class PluginManager { action: 'notification', key: 'compiler', type: 'compilationData', - value: [api.compiler.getCompilationResult()] + value: [self._deps.compiler.getCompilationResult()] })) } }) @@ -142,7 +149,7 @@ module.exports = class PluginManager { data.value.push((error, result) => { response(data.key, data.type, data.id, error, result) }) - api[data.key][data.type].apply({}, data.value) + self._components.pluginAPI[data.key][data.type].apply({}, data.value) } } }, false) diff --git a/src/app/tabs/analysis-tab.js b/src/app/tabs/analysis-tab.js index f2bda461ca..16a7c06c04 100644 --- a/src/app/tabs/analysis-tab.js +++ b/src/app/tabs/analysis-tab.js @@ -2,17 +2,17 @@ var yo = require('yo-yo') var csjs = require('csjs-inject') var remixLib = require('remix-lib') +var globalRegistry = require('../../global/registry') var EventManager = remixLib.EventManager module.exports = class AnalysisTab { - constructor (opts = { api: {}, events: {} }) { + constructor (localRegistry) { const self = this self.event = new EventManager() - self._api = opts.api - self._events = opts.events self._view = { el: null } self.data = {} self._components = {} + self._components.registry = localRegistry || globalRegistry } render () { const self = this diff --git a/src/app/tabs/compile-tab.js b/src/app/tabs/compile-tab.js index d425a9bfdd..e8d228d781 100644 --- a/src/app/tabs/compile-tab.js +++ b/src/app/tabs/compile-tab.js @@ -2,6 +2,7 @@ const yo = require('yo-yo') const csjs = require('csjs-inject') const copy = require('clipboard-copy') +var globalRegistry = require('../../global/registry') const TreeView = require('../ui/TreeView') const modalDialog = require('../ui/modaldialog') const copyToClipboard = require('../ui/copy-to-clipboard') @@ -14,11 +15,8 @@ const addTooltip = require('../ui/tooltip') const styles = styleGuide.chooser() module.exports = class CompileTab { - constructor (api = {}, events = {}, opts = {}) { + constructor (localRegistry) { const self = this - self._opts = opts - self._api = api - self._events = events self._view = { el: null, autoCompile: null, @@ -30,22 +28,36 @@ module.exports = class CompileTab { contractNames: null, contractEl: null } + self._components = {} + self._components.registry = localRegistry || globalRegistry + // dependencies + self._deps = { + app: self._components.registry.get('app').api, + udapp: self._components.registry.get('udapp').api, + udappUI: self._components.registry.get('udappUI').api, + editor: self._components.registry.get('editor').api, + config: self._components.registry.get('config').api, + compiler: self._components.registry.get('compiler').api, + staticAnalysis: self._components.registry.get('staticanalysis').api, + renderer: self._components.registry.get('renderer').api, + transactionContextAPI: self._components.registry.get('transactionContextAPI').api + } self.data = { - hideWarnings: self._opts.config.get('hideWarnings') || false, - autoCompile: self._opts.config.get('autoCompile'), + hideWarnings: self._deps.config.get('hideWarnings') || false, + autoCompile: self._deps.config.get('autoCompile'), compileTimeout: null, contractsDetails: {}, maxTime: 1000, timeout: 300 } - self._events.editor.register('contentChanged', scheduleCompilation) - self._events.editor.register('sessionSwitched', scheduleCompilation) + self._deps.editor.event.register('contentChanged', scheduleCompilation) + self._deps.editor.event.register('sessionSwitched', scheduleCompilation) function scheduleCompilation () { - if (!self._opts.config.get('autoCompile')) return + if (!self._deps.config.get('autoCompile')) return if (self.data.compileTimeout) window.clearTimeout(self.data.compileTimeout) - self.data.compileTimeout = window.setTimeout(() => self._api.runCompiler(), self.data.timeout) + self.data.compileTimeout = window.setTimeout(() => self._deps.app.runCompiler(), self.data.timeout) } - self._events.compiler.register('compilationDuration', function tabHighlighting (speed) { + self._deps.compiler.event.register('compilationDuration', function tabHighlighting (speed) { if (!self._view.warnCompilationSlow) return if (speed > self.data.maxTime) { const msg = `Last compilation took ${speed}ms. We suggest to turn off autocompilation.` @@ -55,31 +67,31 @@ module.exports = class CompileTab { self._view.warnCompilationSlow.style.display = 'none' } }) - self._events.editor.register('contentChanged', function changedFile () { + self._deps.editor.event.register('contentChanged', function changedFile () { if (!self._view.compileIcon) return const compileTab = document.querySelector('.compileView') // @TODO: compileView tab compileTab.style.color = styles.colors.red // @TODO: compileView tab self._view.compileIcon.classList.add(`${css.bouncingIcon}`) // @TODO: compileView tab }) - self._events.compiler.register('loadingCompiler', function start () { + self._deps.compiler.event.register('loadingCompiler', function start () { if (!self._view.compileIcon) return self._view.compileIcon.classList.add(`${css.spinningIcon}`) self._view.warnCompilationSlow.style.display = 'none' self._view.compileIcon.setAttribute('title', 'compiler is loading, please wait a few moments.') }) - self._events.compiler.register('compilationStarted', function start () { + self._deps.compiler.event.register('compilationStarted', function start () { if (!self._view.compileIcon) return self._view.errorContainer.innerHTML = '' self._view.compileIcon.classList.remove(`${css.bouncingIcon}`) self._view.compileIcon.classList.add(`${css.spinningIcon}`) self._view.compileIcon.setAttribute('title', 'compiling...') }) - self._events.compiler.register('compilerLoaded', function loaded () { + self._deps.compiler.event.register('compilerLoaded', function loaded () { if (!self._view.compileIcon) return self._view.compileIcon.classList.remove(`${css.spinningIcon}`) self._view.compileIcon.setAttribute('title', '') }) - self._events.compiler.register('compilationFinished', function finish (success, data, source) { + self._deps.compiler.event.register('compilationFinished', function finish (success, data, source) { if (self._view.compileIcon) { const compileTab = document.querySelector('.compileView') compileTab.style.color = styles.colors.black @@ -94,15 +106,17 @@ module.exports = class CompileTab { self._view.contractNames.innerHTML = '' if (success) { self._view.contractNames.removeAttribute('disabled') - self._opts.compiler.visitContracts(contract => { - self.data.contractsDetails[contract.name] = parseContracts(contract.name, contract.object, self._opts.compiler.getSource(contract.file)) + self._deps.compiler.visitContracts(contract => { + self.data.contractsDetails[contract.name] = parseContracts(contract.name, contract.object, self._deps.compiler.getSource(contract.file)) var contractName = yo`` self._view.contractNames.appendChild(contractName) }) - self._api.resetDapp(self.data.contractsDetails) + self._deps.udapp.reset(self.data.contractsDetails, self._deps.transactionContextAPI) + self._deps.udappUI.reset() } else { self._view.contractNames.setAttribute('disabled', true) - self._api.resetDapp({}) + self._deps.udapp.reset({}, self._deps.transactionContextAPI) + self._deps.udappUI.reset() } // hightlight the tab if error if (success) document.querySelector('.compileView').style.color = '' // @TODO: compileView tab @@ -111,31 +125,31 @@ module.exports = class CompileTab { var error = false if (data['error']) { error = true - self._opts.renderer.error(data['error'].formattedMessage, self._view.errorContainer, {type: data['error'].severity}) + self._deps.renderer.error(data['error'].formattedMessage, self._view.errorContainer, {type: data['error'].severity}) } if (data.errors && data.errors.length) { error = true data.errors.forEach(function (err) { - if (self._opts.config.get('hideWarnings')) { + if (self._deps.config.get('hideWarnings')) { if (err.severity !== 'warning') { - self._opts.renderer.error(err.formattedMessage, self._view.errorContainer, {type: err.severity}) + self._deps.renderer.error(err.formattedMessage, self._view.errorContainer, {type: err.severity}) } } else { - self._opts.renderer.error(err.formattedMessage, self._view.errorContainer, {type: err.severity}) + self._deps.renderer.error(err.formattedMessage, self._view.errorContainer, {type: err.severity}) } }) } if (!error && data.contracts) { - self._opts.compiler.visitContracts((contract) => { - self._opts.renderer.error(contract.name, self._view.errorContainer, {type: 'success'}) + self._deps.compiler.visitContracts((contract) => { + self._deps.renderer.error(contract.name, self._view.errorContainer, {type: 'success'}) }) } }) - self._events.staticAnalysis.register('staticAnaysisWarning', (count) => { + self._deps.staticAnalysis.event.register('staticAnaysisWarning', (count) => { if (count) { const msg = `Static Analysis raised ${count} warning(s) that requires your attention. Click here to show the warning(s).` const settings = { type: 'staticAnalysisWarning', click: () => self._api.switchTab('staticanalysisView'), useSpan: true } - self._opts.renderer.error(msg, self._view.errorContainer, settings) + self._deps.renderer.error(msg, self._view.errorContainer, settings) } }) } @@ -202,8 +216,8 @@ module.exports = class CompileTab { 'swarmLocation': 'Swarm url where all metadata information can be found (contract needs to be published first)', 'web3Deploy': 'Copy/paste this code to any JavaScript/Web3 console to deploy this contract' } - function updateAutoCompile (event) { self._opts.config.set('autoCompile', self._view.autoCompile.checked) } - function compile (event) { self._api.runCompiler() } + function updateAutoCompile (event) { self._deps.config.set('autoCompile', self._view.autoCompile.checked) } + function compile (event) { self._deps.app.runCompiler() } function hideWarnings (event) { self._opts.config.set('hideWarnings', self._view.hideWarningsBox.checked) self._api.runCompiler() diff --git a/src/app/tabs/debugger-tab.js b/src/app/tabs/debugger-tab.js index a9fed861c5..ccf7abb35b 100644 --- a/src/app/tabs/debugger-tab.js +++ b/src/app/tabs/debugger-tab.js @@ -2,18 +2,18 @@ var yo = require('yo-yo') var csjs = require('csjs-inject') var remixLib = require('remix-lib') +var globalRegistry = require('../../global/registry') var EventManager = remixLib.EventManager var styles = require('../ui/styles-guide/theme-chooser').chooser() module.exports = class DebuggerTab { - constructor (opts = { api: {}, events: {} }) { + constructor (localRegistry) { const self = this self.event = new EventManager() - self._api = opts.api - self._events = opts.events self._view = { el: null } self.data = {} self._components = {} + self._components.registry = localRegistry || globalRegistry } render () { const self = this diff --git a/src/app/tabs/plugin-tab.js b/src/app/tabs/plugin-tab.js index 9b92233c0c..d4ad06924c 100644 --- a/src/app/tabs/plugin-tab.js +++ b/src/app/tabs/plugin-tab.js @@ -2,17 +2,16 @@ var yo = require('yo-yo') var csjs = require('csjs-inject') var remixLib = require('remix-lib') +var globalRegistry = require('../../global/registry') var EventManager = remixLib.EventManager module.exports = class plugintab { - constructor (api = {}, events = {}, opts = {}) { + constructor (localRegistry) { const self = this self.event = new EventManager() - self._opts = opts - self._api = api - self._events = events self._view = { el: null } self._components = {} + self._components.registry = localRegistry || globalRegistry } render () { const self = this diff --git a/src/app/tabs/run-tab.js b/src/app/tabs/run-tab.js index 416fa6a4ff..7904e30e83 100644 --- a/src/app/tabs/run-tab.js +++ b/src/app/tabs/run-tab.js @@ -8,6 +8,7 @@ var txExecution = remixLib.execution.txExecution var txFormat = remixLib.execution.txFormat var txHelper = remixLib.execution.txHelper var EventManager = remixLib.EventManager +var globlalRegistry = require('../../global/registry') var helper = require('../../lib/helper.js') var executionContext = require('../../execution-context') var modalDialogCustom = require('../ui/modal-dialog-custom') @@ -18,13 +19,12 @@ var addTooltip = require('../ui/tooltip') var css = require('./styles/run-tab-styles') var MultiParamManager = require('../../multiParamManager') -function runTab (appAPI = {}, appEvents = {}, opts = {}) { +function runTab (localRegistry) { /* ------------------------- VARIABLES --------------------------- */ var self = this var event = new EventManager() - appEvents.eventManager = event self._view = {} self.data = { count: 0, @@ -33,7 +33,18 @@ function runTab (appAPI = {}, appEvents = {}, opts = {}) { another environment. e.g Transactions created in Javascript VM can be replayed in the Injected Web3.` } - + self._components = {} + self._components.registry = localRegistry || globlalRegistry + // dependencies + self._deps = { + compiler: self._components.registry.get('compiler').api, + udapp: self._components.registry.get('udapp').api, + udappUI: self._components.registry.get('udappUI').api, + config: self._components.registry.get('config').api, + fileManager: self._components.registry.get('filemanager').api, + editorPanel: self._components.registry.get('editorpanel').api, + editor: self._components.registry.get('editor').api + } self._view.recorderCount = yo`0` self._view.instanceContainer = yo`
` self._view.clearInstanceElement = yo` @@ -52,7 +63,7 @@ function runTab (appAPI = {}, appEvents = {}, opts = {}) { ` var container = yo`
` - var recorderInterface = makeRecorder(appAPI, appEvents, opts, self) + var recorderInterface = makeRecorder(localRegistry, event, self) self._view.collapsedView = yo`
@@ -92,8 +103,8 @@ function runTab (appAPI = {}, appEvents = {}, opts = {}) { --------------------------- */ var el = yo`
- ${settings(container, appAPI, appEvents, opts)} - ${contractDropdown(event, appAPI, appEvents, opts, self)} + ${settings(container, self)} + ${contractDropdown(event, self)} ${recorderCard.render()} ${self._view.instanceContainer}
@@ -114,7 +125,7 @@ function runTab (appAPI = {}, appEvents = {}, opts = {}) { function setFinalContext () { // set the final context. Cause it is possible that this is not the one we've originaly selected selectExEnv.value = executionContext.getProvider() - fillAccountsList(appAPI, opts, el) + fillAccountsList(el, self) event.trigger('clearInstance', []) } @@ -141,9 +152,9 @@ function runTab (appAPI = {}, appEvents = {}, opts = {}) { setFinalContext() }) - fillAccountsList(appAPI, opts, el) + fillAccountsList(el, self) setInterval(() => { - updateAccountBalances(container, appAPI) + updateAccountBalances(container, self) }, 10000) event.register('clearInstance', () => { @@ -156,10 +167,10 @@ function runTab (appAPI = {}, appEvents = {}, opts = {}) { return { render () { return container } } } -function fillAccountsList (appAPI, opts, container) { +function fillAccountsList (container, self) { var $txOrigin = $(container.querySelector('#txorigin')) $txOrigin.empty() - opts.udapp.getAccounts((err, accounts) => { + self._deps.udapp.getAccounts((err, accounts) => { if (err) { addTooltip(`Cannot get account list: ${err}`) } if (accounts && accounts[0]) { for (var a in accounts) { $txOrigin.append($('
@@ -327,7 +341,7 @@ function contractDropdown (events, appAPI, appEvents, opts, self) { function setInputParamsPlaceHolder () { createPanel.innerHTML = '' - if (opts.compiler.getContract && selectContractNames.selectedIndex >= 0 && selectContractNames.children.length > 0) { + if (self._deps.compiler.getContract && selectContractNames.selectedIndex >= 0 && selectContractNames.children.length > 0) { var ctrabi = txHelper.getConstructorInterface(getSelectedContract().contract.object.abi) var ctrEVMbc = getSelectedContract().contract.object.evm.bytecode.object var createConstructorInstance = new MultiParamManager(0, ctrabi, (valArray, inputsValues) => { @@ -352,44 +366,44 @@ function contractDropdown (events, appAPI, appEvents, opts, self) { } var constructor = txHelper.getConstructorInterface(selectedContract.contract.object.abi) - txFormat.buildData(selectedContract.name, selectedContract.contract.object, opts.compiler.getContracts(), true, constructor, args, (error, data) => { + txFormat.buildData(selectedContract.name, selectedContract.contract.object, self._deps.compiler.getContracts(), true, constructor, args, (error, data) => { if (!error) { - appAPI.logMessage(`creation of ${selectedContract.name} pending...`) - opts.udapp.createContract(data, (error, txResult) => { + self._deps.editorPanel.logMessage(`creation of ${selectedContract.name} pending...`) + self._deps.udapp.createContract(data, (error, txResult) => { if (error) { - appAPI.logMessage(`creation of ${selectedContract.name} errored: ` + error) + self._deps.editorPanel.logMessage(`creation of ${selectedContract.name} errored: ` + error) } else { var isVM = executionContext.isVM() if (isVM) { var vmError = txExecution.checkVMError(txResult) if (vmError.error) { - appAPI.logMessage(vmError.message) + self._deps.editorPanel.logMessage(vmError.message) return } } if (txResult.result.status && txResult.result.status === '0x0') { - appAPI.logMessage(`creation of ${selectedContract.name} errored: transaction execution failed`) + self._deps.editorPanel.logMessage(`creation of ${selectedContract.name} errored: transaction execution failed`) return } var noInstancesText = self._view.noInstancesText if (noInstancesText.parentNode) { noInstancesText.parentNode.removeChild(noInstancesText) } var address = isVM ? txResult.result.createdAddress : txResult.result.contractAddress - instanceContainer.appendChild(opts.udappUI.renderInstance(selectedContract.contract.object, address, selectContractNames.value)) + instanceContainer.appendChild(self._deps.udappUI.renderInstance(selectedContract.contract.object, address, selectContractNames.value)) } }) } else { - appAPI.logMessage(`creation of ${selectedContract.name} errored: ` + error) + self._deps.editorPanel.logMessage(`creation of ${selectedContract.name} errored: ` + error) } }, (msg) => { - appAPI.logMessage(msg) + self._deps.editorPanel.logMessage(msg) }, (data, runTxCallback) => { // called for libraries deployment - opts.udapp.runTx(data, runTxCallback) + self._deps.udapp.runTx(data, runTxCallback) }) } // ACCESS DEPLOYED INSTANCE - function loadFromAddress (editor, config) { + function loadFromAddress () { var noInstancesText = self._view.noInstancesText if (noInstancesText.parentNode) { noInstancesText.parentNode.removeChild(noInstancesText) } var contractNames = document.querySelector(`.${css.contractNames.classNames[0]}`) @@ -400,19 +414,19 @@ function contractDropdown (events, appAPI, appEvents, opts, self) { if (/[a-f]/.test(address) && /[A-F]/.test(address) && !ethJSUtil.isValidChecksumAddress(address)) { return modalDialogCustom.alert('Invalid checksum address.') } - if (/.(.abi)$/.exec(config.get('currentFile'))) { + if (/.(.abi)$/.exec(self._deps.config.get('currentFile'))) { modalDialogCustom.confirm(null, 'Do you really want to interact with ' + address + ' using the current ABI definition ?', () => { var abi try { - abi = JSON.parse(editor.currentContent()) + abi = JSON.parse(self._deps.editor.currentContent()) } catch (e) { return modalDialogCustom.alert('Failed to parse the current file as JSON ABI.') } - instanceContainer.appendChild(opts.udappUI.renderInstanceFromABI(abi, address, address)) + instanceContainer.appendChild(self._deps.udappUI.renderInstanceFromABI(abi, address, address)) }) } else { - var contract = opts.compiler.getContract(contractNames.children[contractNames.selectedIndex].innerHTML) - instanceContainer.appendChild(opts.udappUI.renderInstance(contract.object, address, selectContractNames.value)) + var contract = self._deps.compiler.getContract(contractNames.children[contractNames.selectedIndex].innerHTML) + instanceContainer.appendChild(self._deps.udappUI.renderInstance(contract.object, address, selectContractNames.value)) } } @@ -422,7 +436,7 @@ function contractDropdown (events, appAPI, appEvents, opts, self) { contractNames.innerHTML = '' if (success) { selectContractNames.removeAttribute('disabled') - opts.compiler.visitContracts((contract) => { + self._deps.compiler.visitContracts((contract) => { contractNames.appendChild(yo``) }) } else { @@ -436,7 +450,7 @@ function contractDropdown (events, appAPI, appEvents, opts, self) { /* ------------------------------------------------ section SETTINGS: Environment, Account, Gas, Value ------------------------------------------------ */ -function settings (container, appAPI, appEvents, opts) { +function settings (container, self) { // VARIABLES var net = yo`` const updateNetwork = () => { @@ -511,15 +525,15 @@ function settings (container, appAPI, appEvents, opts) { ` // HELPER FUNCTIONS AND EVENTS - appEvents.udapp.register('transactionExecuted', (error, from, to, data, lookupOnly, txResult) => { + self._deps.udapp.event.register('transactionExecuted', (error, from, to, data, lookupOnly, txResult) => { if (error) return if (!lookupOnly) el.querySelector('#value').value = '0' - updateAccountBalances(container, appAPI) + updateAccountBalances(container, self) }) setInterval(updateNetwork, 5000) function newAccount () { - appAPI.newAccount('', (error, address) => { + self._deps.udapp.newAccount('', (error, address) => { if (!error) { container.querySelector('#txorigin').appendChild(yo``) addTooltip(`account ${address} created`) diff --git a/src/app/tabs/settings-tab.js b/src/app/tabs/settings-tab.js index 1007a4d08a..8721e78063 100644 --- a/src/app/tabs/settings-tab.js +++ b/src/app/tabs/settings-tab.js @@ -3,6 +3,8 @@ var yo = require('yo-yo') var csjs = require('csjs-inject') var minixhr = require('minixhr') var remixLib = require('remix-lib') + +var globalRegistry = require('../../global/registry') var QueryParams = require('../../lib/query-params') var helper = require('../../lib/helper') var modal = require('../ui/modal-dialog-custom') @@ -15,12 +17,20 @@ var Storage = remixLib.Storage var EventManager = remixLib.EventManager module.exports = class SettingsTab { - constructor (api = {}, events = {}, opts = {}) { + constructor (localRegistry) { const self = this - self._opts = opts - self._api = api - self._events = events self._components = {} + self._components.registry = localRegistry || globalRegistry + // dependencies + self._deps = { + compiler: self._components.registry.get('compiler').api, + udapp: self._components.registry.get('udapp').api, + udappUI: self._components.registry.get('udappUI').api, + config: self._components.registry.get('config').api, + fileManager: self._components.registry.get('filemanager').api, + editorPanel: self._components.registry.get('editorpanel').api, + editor: self._components.registry.get('editor').api + } self._view = { /* eslint-disable */ el: null, optionVM: null, personal: null, optimize: null, warnPersonalMode: null, @@ -41,9 +51,10 @@ module.exports = class SettingsTab { self._components.themeStorage = new Storage('style:') self.data.optimize = !!self._components.queryParams.get().optimize self._components.queryParams.update({ optimize: self.data.optimize }) - self._api.setOptimize(self.data.optimize, false) + self._deps.compiler.setOptimize(self.data.optimize) self.data.currentTheme = self._components.themeStorage.get('theme') || 'light' - self._events.compiler.register('compilerLoaded', (version) => self.setVersionText(version)) + + self._deps.compiler.event.register('compilerLoaded', (version) => self.setVersionText(version)) self.fetchAllVersion((allversions, selectedVersion) => { self.data.allversions = allversions self.data.selectedVersion = selectedVersion @@ -56,16 +67,16 @@ module.exports = class SettingsTab { // Gist settings var gistAccessToken = yo`` - var token = self._opts.config.get('settings/gist-access-token') + var token = self._deps.config.get('settings/gist-access-token') if (token) gistAccessToken.value = token - var gistAddToken = yo` { self._opts.config.set('settings/gist-access-token', gistAccessToken.value); tooltip('Access token saved') }} value="Save" type="button">` - var gistRemoveToken = yo` { gistAccessToken.value = ''; self._opts.config.set('settings/gist-access-token', ''); tooltip('Access token removed') }} value="Remove" type="button">` - self._view.gistToken = yo`
${gistAccessToken}${copyToClipboard(() => self._opts.config.get('settings/gist-access-token'))}${gistAddToken}${gistRemoveToken}
` + var gistAddToken = yo` { self._deps.config.set('settings/gist-access-token', gistAccessToken.value); tooltip('Access token saved') }} value="Save" type="button">` + var gistRemoveToken = yo` { gistAccessToken.value = ''; self._deps.config.set('settings/gist-access-token', ''); tooltip('Access token removed') }} value="Remove" type="button">` + self._view.gistToken = yo`
${gistAccessToken}${copyToClipboard(() => self._deps.config.get('settings/gist-access-token'))}${gistAddToken}${gistRemoveToken}
` // self._view.optionVM = yo`` - if (self._opts.config.get('settings/always-use-vm')) self._view.optionVM.setAttribute('checked', '') + if (self._deps.config.get('settings/always-use-vm')) self._view.optionVM.setAttribute('checked', '') self._view.personal = yo`` - if (self._opts.config.get('settings/personal-mode')) self._view.personal.setAttribute('checked', '') + if (self._deps.config.get('settings/personal-mode')) self._view.personal.setAttribute('checked', '') self._view.optimize = yo`` if (self.data.optimize) self._view.optimize.setAttribute('checked', '') var warnText = `Transaction sent over Web3 will use the web3.personal API - be sure the endpoint is opened before enabling it. @@ -187,7 +198,7 @@ module.exports = class SettingsTab { ${self._view.config.localremixd} ` function onchangeOption (event) { - self._opts.config.set('settings/always-use-vm', !self._opts.config.get('settings/always-use-vm')) + self._deps.config.set('settings/always-use-vm', !self._deps.config.get('settings/always-use-vm')) } function onloadPlugin (event) { try { @@ -209,14 +220,15 @@ module.exports = class SettingsTab { function onchangeOptimize (event) { self.data.optimize = !!self._view.optimize.checked self._components.queryParams.update({ optimize: self.data.optimize }) - self._api.setOptimize(self.data.optimize, true) + self._deps.compiler.setOptimize(self.data.optimize) + self._deps.app.runCompiler() } function onchangeLoadVersion (event) { self.data.selectedVersion = self._view.versionSelector.value self._updateVersionSelector() } function onchangePersonal (event) { - self._opts.config.set('settings/personal-mode', !self._opts.config.get('settings/personal-mode')) + self._deps.config.set('settings/personal-mode', !self._deps.config.get('settings/personal-mode')) } return self._view.el } @@ -250,10 +262,10 @@ module.exports = class SettingsTab { // Workers cannot load js on "file:"-URLs and we get a // "Uncaught RangeError: Maximum call stack size exceeded" error on Chromium, // resort to non-worker version in that case. - self._opts.compiler.loadVersion(true, url) + self._deps.compiler.loadVersion(true, url) self.setVersionText('(loading using worker)') } else { - self._opts.compiler.loadVersion(false, url) + self._deps.compiler.loadVersion(false, url) self.setVersionText('(loading)') } } diff --git a/src/app/tabs/support-tab.js b/src/app/tabs/support-tab.js index 2f2b651740..042f94f29c 100644 --- a/src/app/tabs/support-tab.js +++ b/src/app/tabs/support-tab.js @@ -2,21 +2,25 @@ const yo = require('yo-yo') const csjs = require('csjs-inject') const remixLib = require('remix-lib') +var globalRegistry = require('../../global/registry') const styles = require('../ui/styles-guide/theme-chooser').chooser() const EventManager = remixLib.EventManager module.exports = class SupportTab { - constructor (api = {}, events = {}, opts = {}) { + constructor (localRegistry) { const self = this self.event = new EventManager() - self._api = api - self._events = events - self._opts = opts self._view = { el: null, gitterIframe: '' } self.data = { gitterIsLoaded: false } self._components = {} - self._events.app.register('tabChanged', (tabName) => { + self._components.registry = localRegistry || globalRegistry + + self._deps = { + app: self._components.registry.get('app').api + } + + self._deps.app.event.register('tabChanged', (tabName) => { if (tabName !== 'Support' || self.data.gitterIsLoaded) return const iframe = yo`