diff --git a/src/app/tabs/run-tab.js b/src/app/tabs/run-tab.js
index 48999f914e..d3b90c34db 100644
--- a/src/app/tabs/run-tab.js
+++ b/src/app/tabs/run-tab.js
@@ -9,6 +9,7 @@ var css = require('./styles/run-tab-styles')
var Settings = require('./runTab/model/settings.js')
var SettingsUI = require('./runTab/settings.js')
+var DropdownLogic = require('./runTab/model/dropdownLogic.js')
var ContractDropdownUI = require('./runTab/contractDropdown.js')
var Recorder = require('./runTab/model/recorder.js')
@@ -133,17 +134,31 @@ function runTab (opts, localRegistry) {
var settingsUI = new SettingsUI(settings)
self.event.register('clearInstance', () => {
- var instanceContainer = self._view.instanceContainer
- var instanceContainerTitle = self._view.instanceContainerTitle
- instanceContainer.innerHTML = '' // clear the instances list
- instanceContainer.appendChild(instanceContainerTitle)
- instanceContainer.appendChild(self._view.noInstancesText)
+ this._view.instanceContainer.innerHTML = '' // clear the instances list
+ this._view.instanceContainer.appendChild(self._view.instanceContainerTitle)
+ this._view.instanceContainer.appendChild(self._view.noInstancesText)
})
settingsUI.event.register('clearInstance', () => {
this.event.trigger('clearInstance', [])
})
- var contractDropdownUI = new ContractDropdownUI(self)
+ var dropdownLogic = new DropdownLogic(self)
+ var contractDropdownUI = new ContractDropdownUI(dropdownLogic, self)
+
+ contractDropdownUI.event.register('clearInstance', () => {
+ var noInstancesText = this._view.noInstancesText
+ if (noInstancesText.parentNode) { noInstancesText.parentNode.removeChild(noInstancesText) }
+ })
+ contractDropdownUI.event.register('newContractABIAdded', (abi, address) => {
+ this._view.instanceContainer.appendChild(this._deps.udappUI.renderInstanceFromABI(abi, address, address))
+ })
+ contractDropdownUI.event.register('newContractInstanceAdded', (contractObject, address, value) => {
+ this._view.instanceContainer.appendChild(this._deps.udappUI.renderInstance(contractObject, address, value))
+ })
+
+ this._view.instanceContainer.appendChild(this._view.instanceContainerTitle)
+ this._view.instanceContainer.appendChild(this._view.noInstancesText)
+
var el = yo`
${settingsUI.render()}
diff --git a/src/app/tabs/runTab/contractDropdown.js b/src/app/tabs/runTab/contractDropdown.js
index 6e9fd461a4..f1157aaa04 100644
--- a/src/app/tabs/runTab/contractDropdown.js
+++ b/src/app/tabs/runTab/contractDropdown.js
@@ -1,93 +1,71 @@
var yo = require('yo-yo')
-var ethJSUtil = require('ethereumjs-util')
var css = require('../styles/run-tab-styles')
var executionContext = require('../../../execution-context')
var modalDialogCustom = require('../../ui/modal-dialog-custom')
-var modalCustom = require('../../ui/modal-dialog-custom')
-var CompilerAbstract = require('../../compiler/compiler-abstract')
var remixLib = require('remix-lib')
var txExecution = remixLib.execution.txExecution
var txFormat = remixLib.execution.txFormat
var txHelper = remixLib.execution.txHelper
+var EventManager = remixLib.EventManager
var typeConversion = remixLib.execution.typeConversion
var confirmDialog = require('../../execution/confirmDialog')
var modalDialog = require('../../ui/modaldialog')
var MultiParamManager = require('../../../multiParamManager')
class ContractDropdownUI {
- constructor (parentSelf) {
+ constructor (dropdownLogic, parentSelf) {
this.parentSelf = parentSelf
+ this.dropdownLogic = dropdownLogic
+ this.event = new EventManager()
+
+ this.listenToEvents()
}
- render () {
- this.instanceContainer = this.parentSelf._view.instanceContainer
- var instanceContainerTitle = this.parentSelf._view.instanceContainerTitle
- this.instanceContainer.appendChild(instanceContainerTitle)
- this.instanceContainer.appendChild(this.parentSelf._view.noInstancesText)
- var compFails = yo`
`
- var info = yo`
`
+ listenToEvents () {
+ this.dropdownLogic.event.register('newlyCompiled', (success, data, source, compiler, compilerFullName) => {
+ var contractNames = document.querySelector(`.${css.contractNames.classNames[0]}`)
+ contractNames.innerHTML = ''
+ if (success) {
+ this.selectContractNames.removeAttribute('disabled')
+ this.dropdownLogic.getCompiledContracts(compiler, compilerFullName).forEach((contract) => {
+ contractNames.appendChild(yo`
`)
+ })
+ } else {
+ this.selectContractNames.setAttribute('disabled', true)
+ }
+ this.setInputParamsPlaceHolder()
- var newlyCompiled = (success, data, source, compiler, compilerFullName) => {
- this.getContractNames(success, data, compiler, compilerFullName)
if (success) {
- compFails.style.display = 'none'
+ this.compFails.style.display = 'none'
document.querySelector(`.${css.contractNames}`).classList.remove(css.contractNamesError)
} else {
- compFails.style.display = 'block'
+ this.compFails.style.display = 'block'
document.querySelector(`.${css.contractNames}`).classList.add(css.contractNamesError)
}
- }
-
- this.parentSelf._deps.pluginManager.event.register('sendCompilationResult', (file, source, languageVersion, data) => {
- // TODO check whether the tab is configured
- let compiler = new CompilerAbstract(languageVersion, data)
- this.parentSelf._deps.compilersArtefacts[languageVersion] = compiler
- this.parentSelf._deps.compilersArtefacts['__last'] = compiler
- newlyCompiled(true, data, source, compiler, languageVersion)
})
- this.parentSelf._deps.compiler.event.register('compilationFinished', (success, data, source) => {
- var name = 'solidity'
- let compiler = new CompilerAbstract(name, data)
- this.parentSelf._deps.compilersArtefacts[name] = compiler
- this.parentSelf._deps.compilersArtefacts['__last'] = compiler
- newlyCompiled(success, data, source, this.parentSelf._deps.compiler, name)
- })
-
- var deployAction = (value) => {
- this.parentSelf._view.createPanel.style.display = value
- this.parentSelf._view.orLabel.style.display = value
- }
+ this.dropdownLogic.event.register('currentFileChanged', this.changeCurrentFile.bind(this))
+ }
- this.parentSelf._deps.fileManager.event.register('currentFileChanged', (currentFile) => {
- document.querySelector(`.${css.contractNames}`).classList.remove(css.contractNamesError)
- var contractNames = document.querySelector(`.${css.contractNames.classNames[0]}`)
- contractNames.innerHTML = ''
- if (/.(.abi)$/.exec(currentFile)) {
- deployAction('none')
- compFails.style.display = 'none'
- contractNames.appendChild(yo`
`)
- this.selectContractNames.setAttribute('disabled', true)
- } else if (/.(.sol)$/.exec(currentFile)) {
- deployAction('block')
- }
- })
+ render () {
+ this.compFails = yo`
`
+ var info = yo`
`
this.atAddressButtonInput = yo`
`
this.selectContractNames = yo`
`
- this.parentSelf._view.createPanel = yo`
`
- this.parentSelf._view.orLabel = yo`
or
`
+ this.createPanel = yo`
`
+ this.orLabel = yo`
or
`
var el = yo`
- ${this.selectContractNames} ${compFails} ${info}
+ ${this.selectContractNames} ${this.compFails} ${info}
- ${this.parentSelf._view.createPanel}
- ${this.parentSelf._view.orLabel}
+ ${this.createPanel}
+ ${this.orLabel}
@@ -98,36 +76,50 @@ class ContractDropdownUI {
return el
}
+ changeCurrentFile (currentFile) {
+ document.querySelector(`.${css.contractNames}`).classList.remove(css.contractNamesError)
+ var contractNames = document.querySelector(`.${css.contractNames.classNames[0]}`)
+ contractNames.innerHTML = ''
+ if (/.(.abi)$/.exec(currentFile)) {
+ this.createPanel.style.display = 'none'
+ this.orLabel.style.display = 'none'
+ this.compFails.style.display = 'none'
+ contractNames.appendChild(yo`
`)
+ this.selectContractNames.setAttribute('disabled', true)
+ } else if (/.(.sol)$/.exec(currentFile)) {
+ this.createPanel.style.display = 'block'
+ this.orLabel.style.display = 'block'
+ }
+ }
+
setInputParamsPlaceHolder () {
- this.parentSelf._view.createPanel.innerHTML = ''
- if (this.selectContractNames.selectedIndex >= 0 && this.selectContractNames.children.length > 0) {
- var selectedContract = this.getSelectedContract()
- var ctrabi = txHelper.getConstructorInterface(selectedContract.contract.object.abi)
- var ctrEVMbc = selectedContract.contract.object.evm.bytecode.object
- var createConstructorInstance = new MultiParamManager(0, ctrabi, (valArray, inputsValues) => {
- this.createInstance(inputsValues, selectedContract.compiler)
- }, txHelper.inputParametersDeclarationToString(ctrabi.inputs), 'Deploy', ctrEVMbc)
- this.parentSelf._view.createPanel.appendChild(createConstructorInstance.render())
+ this.createPanel.innerHTML = ''
+ if (this.selectContractNames.selectedIndex < 0 || this.selectContractNames.children.length <= 0) {
+ this.createPanel.innerHTML = 'No compiled contracts'
return
- } else {
- this.parentSelf._view.createPanel.innerHTML = 'No compiled contracts'
}
+
+ var selectedContract = this.getSelectedContract()
+ var ctrabi = txHelper.getConstructorInterface(selectedContract.contract.object.abi)
+ var ctrEVMbc = selectedContract.contract.object.evm.bytecode.object
+ var createConstructorInstance = new MultiParamManager(0, ctrabi, (valArray, inputsValues) => {
+ this.createInstance(inputsValues, selectedContract.compiler)
+ }, txHelper.inputParametersDeclarationToString(ctrabi.inputs), 'Deploy', ctrEVMbc)
+ this.createPanel.appendChild(createConstructorInstance.render())
}
getSelectedContract () {
var contract = this.selectContractNames.children[this.selectContractNames.selectedIndex]
var contractName = contract.innerHTML
- var compiler = this.parentSelf._deps.compilersArtefacts[contract.getAttribute('compiler')]
+ var compiler = this.dropdownLogic.getContractCompiler(contract.getAttribute('compiler'))
if (!compiler) return null
- if (contractName) {
- return {
- name: contractName,
- contract: compiler.getContract(contractName),
- compiler
- }
+ if (!contractName) return null
+ return {
+ name: contractName,
+ contract: compiler.getContract(contractName),
+ compiler
}
- return null
}
createInstanceCallback (selectedContract, data) {
@@ -214,29 +206,27 @@ class ContractDropdownUI {
}
},
function (okCb, cancelCb) {
- modalCustom.promptPassphrase(null, 'Personal mode is enabled. Please provide passphrase of account', '', okCb, cancelCb)
+ modalDialogCustom.promptPassphrase(null, 'Personal mode is enabled. Please provide passphrase of account', '', okCb, cancelCb)
},
(error, txResult) => {
- if (!error) {
- var isVM = executionContext.isVM()
- if (isVM) {
- var vmError = txExecution.checkVMError(txResult)
- if (vmError.error) {
- this.parentSelf._deps.logCallback(vmError.message)
- return
- }
- }
- if (txResult.result.status && txResult.result.status === '0x0') {
- this.parentSelf._deps.logCallback(`creation of ${selectedContract.name} errored: transaction execution failed`)
+ if (error) {
+ return this.parentSelf._deps.logCallback(`creation of ${selectedContract.name} errored: ${error}`)
+ }
+ var isVM = executionContext.isVM()
+ if (isVM) {
+ var vmError = txExecution.checkVMError(txResult)
+ if (vmError.error) {
+ this.parentSelf._deps.logCallback(vmError.message)
return
}
- var noInstancesText = this.parentSelf._view.noInstancesText
- if (noInstancesText.parentNode) { noInstancesText.parentNode.removeChild(noInstancesText) }
- var address = isVM ? txResult.result.createdAddress : txResult.result.contractAddress
- this.instanceContainer.appendChild(this.parentSelf._deps.udappUI.renderInstance(selectedContract.contract.object, address, this.selectContractNames.value))
- } else {
- this.parentSelf._deps.logCallback(`creation of ${selectedContract.name} errored: ${error}`)
}
+ if (txResult.result.status && txResult.result.status === '0x0') {
+ this.parentSelf._deps.logCallback(`creation of ${selectedContract.name} errored: transaction execution failed`)
+ return
+ }
+ this.event.trigger('clearInstance')
+ var address = isVM ? txResult.result.createdAddress : txResult.result.contractAddress
+ this.event.trigger('newContractInstanceAdded', [selectedContract.contract.object, address, this.selectContractNames.value])
}
)
}
@@ -317,7 +307,7 @@ class ContractDropdownUI {
})
},
function (okCb, cancelCb) {
- modalCustom.promptPassphrase(null, 'Personal mode is enabled. Please provide passphrase of account', '', okCb, cancelCb)
+ modalDialogCustom.promptPassphrase(null, 'Personal mode is enabled. Please provide passphrase of account', '', okCb, cancelCb)
},
runTxCallback)
})
@@ -350,46 +340,25 @@ class ContractDropdownUI {
}
}
- // ACCESS DEPLOYED INSTANCE
loadFromAddress () {
- var noInstancesText = this.parentSelf._view.noInstancesText
- if (noInstancesText.parentNode) { noInstancesText.parentNode.removeChild(noInstancesText) }
+ this.event.trigger('clearInstance')
+
var address = this.atAddressButtonInput.value
- if (!ethJSUtil.isValidAddress(address)) {
- return modalDialogCustom.alert('Invalid address.')
- }
- if (/[a-f]/.test(address) && /[A-F]/.test(address) && !ethJSUtil.isValidChecksumAddress(address)) {
- return modalDialogCustom.alert('Invalid checksum address.')
- }
- if (/.(.abi)$/.exec(this.parentSelf._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(this.parentSelf._deps.editor.currentContent())
- } catch (e) {
- return modalDialogCustom.alert('Failed to parse the current file as JSON ABI.')
+ this.dropdownLogic.loadContractFromAddress(address,
+ (cb) => {
+ modalDialogCustom.confirm(null, 'Do you really want to interact with ' + address + ' using the current ABI definition ?', cb)
+ },
+ (error, loadType, abi) => {
+ if (error) {
+ return modalDialogCustom.alert(error)
}
- this.instanceContainer.appendChild(this.parentSelf._deps.udappUI.renderInstanceFromABI(abi, address, address))
- })
- } else {
- var selectedContract = this.getSelectedContract()
- this.instanceContainer.appendChild(this.parentSelf._deps.udappUI.renderInstance(selectedContract.contract.object, address, this.selectContractNames.value))
- }
- }
-
- // GET NAMES OF ALL THE CONTRACTS
- getContractNames (success, data, compiler, compilerFullName) {
- var contractNames = document.querySelector(`.${css.contractNames.classNames[0]}`)
- contractNames.innerHTML = ''
- if (success) {
- this.selectContractNames.removeAttribute('disabled')
- compiler.visitContracts((contract) => {
- contractNames.appendChild(yo`
`)
- })
- } else {
- this.selectContractNames.setAttribute('disabled', true)
- }
- this.setInputParamsPlaceHolder()
+ if (loadType === 'abi') {
+ return this.event.trigger('newContractABIAdded', [abi, address])
+ }
+ var selectedContract = this.getSelectedContract()
+ this.event.trigger('newContractInstanceAdded', [selectedContract.contract.object, address, this.selectContractNames.value])
+ }
+ )
}
}
diff --git a/src/app/tabs/runTab/model/dropdownlogic.js b/src/app/tabs/runTab/model/dropdownlogic.js
new file mode 100644
index 0000000000..fce17512d7
--- /dev/null
+++ b/src/app/tabs/runTab/model/dropdownlogic.js
@@ -0,0 +1,70 @@
+var ethJSUtil = require('ethereumjs-util')
+var remixLib = require('remix-lib')
+var CompilerAbstract = require('../../../compiler/compiler-abstract')
+var EventManager = remixLib.EventManager
+
+class DropdownLogic {
+ constructor (parentSelf) {
+ this.parentSelf = parentSelf
+ this.event = new EventManager()
+
+ this.listenToCompilationEvents()
+
+ this.parentSelf._deps.fileManager.event.register('currentFileChanged', (currentFile) => {
+ this.event.trigger('currentFileChanged', [currentFile])
+ })
+ }
+
+ listenToCompilationEvents () {
+ this.parentSelf._deps.pluginManager.event.register('sendCompilationResult', (file, source, languageVersion, data) => {
+ // TODO check whether the tab is configured
+ let compiler = new CompilerAbstract(languageVersion, data)
+ this.parentSelf._deps.compilersArtefacts[languageVersion] = compiler
+ this.parentSelf._deps.compilersArtefacts['__last'] = compiler
+ this.event.trigger('newlyCompiled', [true, data, source, compiler, languageVersion])
+ })
+
+ this.parentSelf._deps.compiler.event.register('compilationFinished', (success, data, source) => {
+ var name = 'solidity'
+ let compiler = new CompilerAbstract(name, data)
+ this.parentSelf._deps.compilersArtefacts[name] = compiler
+ this.parentSelf._deps.compilersArtefacts['__last'] = compiler
+ this.event.trigger('newlyCompiled', [success, data, source, this.parentSelf._deps.compiler, name])
+ })
+ }
+
+ loadContractFromAddress (address, confirmCb, cb) {
+ if (!ethJSUtil.isValidAddress(address)) {
+ return cb('Invalid address.')
+ }
+ if (/[a-f]/.test(address) && /[A-F]/.test(address) && !ethJSUtil.isValidChecksumAddress(address)) {
+ return cb('Invalid checksum address.')
+ }
+ if (/.(.abi)$/.exec(this.parentSelf._deps.config.get('currentFile'))) {
+ confirmCb(() => {
+ var abi
+ try {
+ abi = JSON.parse(this.parentSelf._deps.editor.currentContent())
+ } catch (e) {
+ return cb('Failed to parse the current file as JSON ABI.')
+ }
+ cb(null, 'abi', abi)
+ })
+ }
+ cb(null, 'instance')
+ }
+
+ getCompiledContracts (compiler, compilerFullName) {
+ var contracts = []
+ compiler.visitContracts((contract) => {
+ contracts.push(contract)
+ })
+ return contracts
+ }
+
+ getContractCompiler (name) {
+ return this.parentSelf._deps.compilersArtefacts[name]
+ }
+}
+
+module.exports = DropdownLogic