Merge pull request #1387 from ethereum/refactor1

refactor RightHandPanel
pull/3094/head
yann300 6 years ago committed by GitHub
commit 6e02f17e5f
  1. 189
      src/app.js
  2. 9
      src/app/editor/editor.js
  3. 4
      src/app/panels/editor-panel.js
  4. 32
      src/app/panels/righthand-panel.js
  5. 10
      src/app/plugin/pluginAPI.js
  6. 23
      src/app/plugin/pluginManager.js
  7. 6
      src/app/tabs/analysis-tab.js
  8. 74
      src/app/tabs/compile-tab.js
  9. 6
      src/app/tabs/debugger-tab.js
  10. 7
      src/app/tabs/plugin-tab.js
  11. 120
      src/app/tabs/run-tab.js
  12. 46
      src/app/tabs/settings-tab.js
  13. 14
      src/app/tabs/support-tab.js
  14. 15
      src/app/tabs/tabbed-menu.js
  15. 25
      src/app/tabs/test-tab.js
  16. 12
      src/recorder.js
  17. 11
      src/universal-dapp.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)
}
}

@ -65,7 +65,6 @@ document.head.appendChild(yo`
function Editor (opts = {}) {
var self = this
var el = yo`<div id="input"></div>`
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', [])
})
})

@ -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

@ -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 => {

@ -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
}
}
}

@ -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)

@ -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

@ -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`<option>${contract.name}</option>`
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()

@ -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

@ -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

@ -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`<span>0</span>`
self._view.instanceContainer = yo`<div class="${css.instanceContainer}"></div>`
self._view.clearInstanceElement = yo`
@ -52,7 +63,7 @@ function runTab (appAPI = {}, appEvents = {}, opts = {}) {
</div>`
var container = yo`<div class="${css.runTabView}" id="runTabView" ></div>`
var recorderInterface = makeRecorder(appAPI, appEvents, opts, self)
var recorderInterface = makeRecorder(localRegistry, event, self)
self._view.collapsedView = yo`
<div class=${css.recorderCollapsedView}>
@ -92,8 +103,8 @@ function runTab (appAPI = {}, appEvents = {}, opts = {}) {
--------------------------- */
var el = yo`
<div>
${settings(container, appAPI, appEvents, opts)}
${contractDropdown(event, appAPI, appEvents, opts, self)}
${settings(container, self)}
${contractDropdown(event, self)}
${recorderCard.render()}
${self._view.instanceContainer}
</div>
@ -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($('<option />').val(accounts[a]).text(accounts[a])) }
@ -170,11 +181,11 @@ function fillAccountsList (appAPI, opts, container) {
})
}
function updateAccountBalances (container, appAPI) {
function updateAccountBalances (container, self) {
var accounts = $(container.querySelector('#txorigin')).children('option')
accounts.each(function (index, value) {
(function (acc) {
appAPI.getBalance(accounts[acc].value, function (err, res) {
self._deps.udapp.getBalanceInEther(accounts[acc].value, function (err, res) {
if (!err) {
accounts[acc].innerText = helper.shortenAddress(accounts[acc].value, res)
}
@ -186,15 +197,18 @@ function updateAccountBalances (container, appAPI) {
/* ------------------------------------------------
RECORDER
------------------------------------------------ */
function makeRecorder (appAPI, appEvents, opts, self) {
var recorder = new Recorder(opts.compiler, opts.udapp, {
function makeRecorder (registry, runTabEvent, self) {
var recorder = new Recorder(self._deps.compiler, self._deps.udapp,
(msg) => {
self._deps.editorPanel.logMessage(msg)
}, {
events: {
udapp: appEvents.udapp,
udapp: self._deps.udapp.event,
executioncontext: executionContext.event,
runtab: appEvents.eventManager
},
api: appAPI
runtab: runTabEvent
}
})
recorder.event.register('newTxRecorded', (count) => {
self.data.count = count
self._view.recorderCount.innerText = count
@ -217,9 +231,10 @@ function makeRecorder (appAPI, appEvents, opts, self) {
function triggerRecordButton () {
var txJSON = JSON.stringify(recorder.getAll(), null, 2)
var path = appAPI.currentPath()
var fileManager = self._deps.fileManager
var path = fileManager.currentPath()
modalDialogCustom.prompt(null, 'Transactions will be saved in a file under ' + path, 'scenario.json', input => {
var fileProvider = appAPI.fileProviderOf(path)
var fileProvider = fileManager.fileProviderOf(path)
if (fileProvider) {
var newFile = path + input
helper.createNonClashingName(newFile, fileProvider, (error, newFile) => {
@ -227,7 +242,7 @@ function makeRecorder (appAPI, appEvents, opts, self) {
if (!fileProvider.set(newFile, txJSON)) {
modalDialogCustom.alert('Failed to create file ' + newFile)
} else {
appAPI.switchFile(newFile)
fileManager.switchFile(newFile)
}
})
}
@ -240,8 +255,8 @@ function makeRecorder (appAPI, appEvents, opts, self) {
update account address in scenario.json
popup if scenario.json not open - "Open a file with transactions you want to replay and click play again"
*/
var currentFile = opts.config.get('currentFile')
appAPI.fileProviderOf(currentFile).get(currentFile, (error, json) => {
var currentFile = self._deps.config.get('currentFile')
self._deps.fileManager.fileProviderOf(currentFile).get(currentFile, (error, json) => {
if (error) {
modalDialogCustom.alert('Invalid Scenario File ' + error)
} else {
@ -259,8 +274,8 @@ function makeRecorder (appAPI, appEvents, opts, self) {
if (txArray.length) {
var noInstancesText = self._view.noInstancesText
if (noInstancesText.parentNode) { noInstancesText.parentNode.removeChild(noInstancesText) }
recorder.run(txArray, accounts, options, abis, linkReferences, opts.udapp, (abi, address, contractName) => {
self._view.instanceContainer.appendChild(opts.udappUI.renderInstanceFromABI(abi, address, contractName))
recorder.run(txArray, accounts, options, abis, linkReferences, self._deps.udapp, (abi, address, contractName) => {
self._view.instanceContainer.appendChild(self._deps.udappUI.renderInstanceFromABI(abi, address, contractName))
})
}
} else {
@ -276,13 +291,13 @@ function makeRecorder (appAPI, appEvents, opts, self) {
CONTRACT (deploy or access deployed)
------------------------------------------------ */
function contractDropdown (events, appAPI, appEvents, opts, self) {
function contractDropdown (events, self) {
var instanceContainer = self._view.instanceContainer
var instanceContainerTitle = self._view.instanceContainerTitle
instanceContainer.appendChild(instanceContainerTitle)
instanceContainer.appendChild(self._view.noInstancesText)
var compFails = yo`<i title="Contract compilation failed. Please check the compile tab for more information." class="fa fa-times-circle ${css.errorIcon}" ></i>`
appEvents.compiler.register('compilationFinished', function (success, data, source) {
self._deps.compiler.event.register('compilationFinished', function (success, data, source) {
getContractNames(success, data)
if (success) {
compFails.style.display = 'none'
@ -301,12 +316,11 @@ function contractDropdown (events, appAPI, appEvents, opts, self) {
if (contractName) {
return {
name: contractName,
contract: opts.compiler.getContract(contractName)
contract: self._deps.compiler.getContract(contractName)
}
}
return null
}
appAPI.getSelectedContract = getSelectedContract
var createPanel = yo`<div class="${css.button}"></div>`
@ -319,7 +333,7 @@ function contractDropdown (events, appAPI, appEvents, opts, self) {
${createPanel}
<div class="${css.button}">
${atAddressButtonInput}
<div class="${css.atAddress}" onclick=${function () { loadFromAddress(opts.editor, opts.config) }}>At Address</div>
<div class="${css.atAddress}" onclick=${function () { loadFromAddress() }}>At Address</div>
</div>
</div>
</div>
@ -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`<option>${contract.name}</option>`)
})
} 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`<span class=${css.network}></span>`
const updateNetwork = () => {
@ -511,15 +525,15 @@ function settings (container, appAPI, appEvents, opts) {
</div>
`
// 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`<option value=${address}>${address}</option>`)
addTooltip(`account ${address} created`)

@ -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`<input id="gistaccesstoken" type="password">`
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`<input class="${css.savegisttoken}" id="savegisttoken" onclick=${() => { self._opts.config.set('settings/gist-access-token', gistAccessToken.value); tooltip('Access token saved') }} value="Save" type="button">`
var gistRemoveToken = yo`<input id="removegisttoken" onclick=${() => { gistAccessToken.value = ''; self._opts.config.set('settings/gist-access-token', ''); tooltip('Access token removed') }} value="Remove" type="button">`
self._view.gistToken = yo`<div class="${css.checkboxText}">${gistAccessToken}${copyToClipboard(() => self._opts.config.get('settings/gist-access-token'))}${gistAddToken}${gistRemoveToken}</div>`
var gistAddToken = yo`<input class="${css.savegisttoken}" id="savegisttoken" onclick=${() => { self._deps.config.set('settings/gist-access-token', gistAccessToken.value); tooltip('Access token saved') }} value="Save" type="button">`
var gistRemoveToken = yo`<input id="removegisttoken" onclick=${() => { gistAccessToken.value = ''; self._deps.config.set('settings/gist-access-token', ''); tooltip('Access token removed') }} value="Remove" type="button">`
self._view.gistToken = yo`<div class="${css.checkboxText}">${gistAccessToken}${copyToClipboard(() => self._deps.config.get('settings/gist-access-token'))}${gistAddToken}${gistRemoveToken}</div>`
//
self._view.optionVM = yo`<input onchange=${onchangeOption} id="alwaysUseVM" type="checkbox">`
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`<input onchange=${onchangePersonal} id="personal" type="checkbox">`
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`<input onchange=${onchangeOptimize} id="optimize" type="checkbox">`
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}
</div>`
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)')
}
}

@ -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`<iframe class="${css.chatIframe}" src='https://gitter.im/ethereum/remix/~embed'>`
self._view.gitterIframe.parentNode.replaceChild(iframe, self._view.gitterIframe)

@ -2,20 +2,23 @@ var yo = require('yo-yo')
var csjs = require('csjs-inject')
var remixLib = require('remix-lib')
var globalRegistry = require('../../global/registry')
var helper = require('../../lib/helper')
var styles = require('../ui/styles-guide/theme-chooser').chooser()
var EventManager = remixLib.EventManager
module.exports = class TabbedMenu {
constructor (api = {}, events = {}, opts = {}) {
constructor (localRegistry) {
const self = this
self.event = new EventManager()
self._opts = opts
self._api = api
self._events = events
self._components = {}
self._components.registry = localRegistry || globalRegistry
self._deps = {
app: self._components.registry.get('app').api
}
self._view = { el: null, viewport: null, tabs: {}, contents: {} }
events.app.register('debuggingRequested', () => {
self._deps.app.event.register('debuggingRequested', () => {
self.selectTabByTitle('Debugger')
})
}
@ -63,7 +66,7 @@ module.exports = class TabbedMenu {
var title = el.getAttribute('title')
self._view.contents[el.getAttribute('title')].style.display = 'block'
el.classList.add(css.active)
self._events.app.trigger('tabChanged', [title])
self._deps.app.event.trigger('tabChanged', [title])
}
}

@ -1,21 +1,24 @@
var yo = require('yo-yo')
var async = require('async')
var globalRegistry = require('../../global/registry')
var css = require('./styles/test-tab-styles')
var remixTests = require('remix-tests')
module.exports = class TestTab {
constructor (api = {}, events = {}, opts = {}) {
constructor (localRegistry) {
const self = this
self._opts = opts
self._api = api
self._events = events
self._view = { el: null }
self._components = {}
self._components.registry = localRegistry || globalRegistry
// dependencies
self._deps = {
fileManager: self._components.registry.get('filemanager').api,
app: self._components.registry.get('app').api
}
self.data = {}
self._view.el = self.render()
events.app.register('tabChanged', tabName => {
self._deps.app.event.register('tabChanged', tabName => {
if (tabName !== 'test') return
yo.update(self._view.el, self.render())
self._view.el.style.display = 'block'
@ -24,8 +27,6 @@ module.exports = class TestTab {
return { render () { return self._view.el } }
}
render () {
const self = this
const api = self._api
var container = yo`<div class="tests" id="tests"></div>`
function append (container, txt) {
@ -67,7 +68,7 @@ module.exports = class TestTab {
}
function runTest (testFilePath, callback) {
var provider = api.fileProviderOf(testFilePath)
var provider = this._deps.fileManager.fileProviderOf(testFilePath)
provider.get(testFilePath, (error, content) => {
if (!error) {
var runningTest = {}
@ -75,16 +76,16 @@ module.exports = class TestTab {
remixTests.runTestSources(runningTest, testCallback, resultsCallback, (error, result) => {
updateFinalResult(error, result)
callback(error)
}, api.importFileCb)
}, this._deps.fileManager.importFileCb)
}
})
}
let runTests = function () {
container.innerHTML = ''
var path = api.currentPath()
var path = this._deps.fileManager.currentPath()
var tests = []
api.filesFromPath(path, (error, files) => {
this._deps.fileManager.filesFromPath(path, (error, files) => {
if (!error) {
for (var file in files) {
if (/.(_test.sol)$/.exec(file)) tests.push(path + file)

@ -13,9 +13,9 @@ var modal = require('./app/ui/modal-dialog-custom')
*
*/
class Recorder {
constructor (compiler, udapp, opts = {}) {
constructor (compiler, udapp, logMessageCallback, opts = {}) {
var self = this
self._api = opts.api
self.logMessageCallback = logMessageCallback
self.event = new EventManager()
self.data = { _listen: true, _replay: false, journal: [], _createdContracts: {}, _createdContractsReverse: {}, _usedAccounts: {}, _abis: {}, _contractABIReferences: {}, _linkReferences: {} }
opts.events.executioncontext.register('contextChanged', () => {
@ -184,7 +184,7 @@ class Recorder {
run (records, accounts, options, abis, linkReferences, udapp, newContractFn) {
var self = this
self.setListen(false)
self._api.logMessage(`Running ${records.length} transaction(s) ...`)
self.logMessageCallback(`Running ${records.length} transaction(s) ...`)
async.eachOfSeries(records, function (tx, index, cb) {
var record = self.resolveAddress(tx.record, accounts, options)
var abi = abis[tx.record.abi]
@ -241,14 +241,14 @@ class Recorder {
cb(data.error)
return
} else {
self._api.logMessage(`(${index}) ${JSON.stringify(record, null, '\t')}`)
self._api.logMessage(`(${index}) data: ${data.data}`)
self.logMessageCallback(`(${index}) ${JSON.stringify(record, null, '\t')}`)
self.logMessageCallback(`(${index}) data: ${data.data}`)
record.data = { dataHex: data.data, funArgs: tx.record.parameters, funAbi: fnABI, contractBytecode: tx.record.bytecode, contractName: tx.record.contractName }
}
udapp.runTx(record, function (err, txResult) {
if (err) {
console.error(err)
self._api.logMessage(err + '. Execution failed at ' + index)
self.logMessageCallback(err + '. Execution failed at ' + index)
} else {
var address = executionContext.isVM() ? txResult.result.createdAddress : txResult.result.contractAddress
if (address) {

@ -148,6 +148,17 @@ UniversalDApp.prototype.getBalance = function (address, cb) {
}
}
UniversalDApp.prototype.getBalanceInEther = function (address, callback) {
var self = this
self.getBalance(address, (error, balance) => {
if (error) {
callback(error)
} else {
callback(null, executionContext.web3().fromWei(balance, 'ether'))
}
})
}
UniversalDApp.prototype.pendingTransactions = function () {
return this.txRunner.pendingTxs
}

Loading…
Cancel
Save