diff --git a/src/app/tabs/compile-tab.js b/src/app/tabs/compile-tab.js index 09ada87dde..abb7ef9963 100644 --- a/src/app/tabs/compile-tab.js +++ b/src/app/tabs/compile-tab.js @@ -20,9 +20,8 @@ const CompilerContainer = require('./compileTab/compilerContainer.js') class CompileTab { constructor (registry) { - const self = this - self.event = new EventEmitter() - self._view = { + this.event = new EventEmitter() + this._view = { el: null, warnCompilationSlow: null, errorContainer: null, @@ -30,10 +29,10 @@ class CompileTab { contractNames: null, contractEl: null } - self.queryParams = new QueryParams() + this.queryParams = new QueryParams() // dependencies - self._deps = { + this._deps = { editor: registry.get('editor').api, config: registry.get('config').api, renderer: registry.get('renderer').api, @@ -42,52 +41,62 @@ class CompileTab { fileProviders: registry.get('fileproviders').api, pluginManager: registry.get('pluginmanager').api } - self.data = { + this.data = { contractsDetails: {} } - this.compileTabLogic = new CompileTabLogic(self.queryParams, self._deps.fileManager, self._deps.editor, self._deps.config, self._deps.fileProviders) + this.compileTabLogic = new CompileTabLogic(this.queryParams, this._deps.fileManager, this._deps.editor, this._deps.config, this._deps.fileProviders) this.compiler = this.compileTabLogic.compiler this.compileTabLogic.init() - this.compilerContainer = new CompilerContainer(self.compileTabLogic, self._deps.editor, self._deps.config, self.queryParams) + this.compilerContainer = new CompilerContainer( + this.compileTabLogic, + this._deps.editor, + this._deps.config, + this.queryParams + ) this.listenToEvents() } - listenToEvents () { - const self = this + /************ + * EVENTS + */ - self.compiler.event.register('compilationStarted', () => { - if (self._view.errorContainer) { - self._view.errorContainer.innerHTML = '' - self._view.errorContainerHead.innerHTML = '' + listenToEvents () { + this.compiler.event.register('compilationStarted', () => { + if (this._view.errorContainer) { + this._view.errorContainer.innerHTML = '' + this._view.errorContainerHead.innerHTML = '' } }) - self.compiler.event.register('compilationFinished', (success, data, source) => { + + this._deps.fileManager.event.register('currentFileChanged', (name) => { + this.compilerContainer.currentFile = name + }) + this.compiler.event.register('compilationFinished', (success, data, source) => { if (success) { // forwarding the event to the appManager infra - self.event.emit('compilationFinished', source.target, source, self.data.selectedVersion, data) - } - // reset the contractMetadata list (used by the publish action) - self.data.contractsDetails = {} - // refill the dropdown list - self._view.contractNames.innerHTML = '' - if (success) { - // TODO consider using compile tab as a proper module instead of just forwarding event - self._view.contractNames.removeAttribute('disabled') - self.compiler.visitContracts(contract => { - self.data.contractsDetails[contract.name] = parseContracts(contract.name, contract.object, self.compiler.getSource(contract.file)) - var contractName = yo`` - self._view.contractNames.appendChild(contractName) + this.event.emit('compilationFinished', source.target, source, this.data.selectedVersion, data) + // Store the contracts + this.data.contractsDetails = {} + this.compiler.visitContracts((contract) => { + this.data.contractsDetails[contract.name] = parseContracts( + contract.name, + contract.object, + this.compiler.getSource(contract.file) + ) }) - } else { - self._view.contractNames.setAttribute('disabled', true) } - var error = false + // Update contract Selection + const contractMap = this.compiler.getContracts() + const contractSelection = this.contractSelection(Object.keys(contractMap) || []) + yo.update(this._view.contractSelection, contractSelection) + + let error = false if (data['error']) { error = true - self._deps.renderer.error(data['error'].formattedMessage, self._view.errorContainer, {type: data['error'].severity || 'error'}) + this._deps.renderer.error(data['error'].formattedMessage, this._view.errorContainer, {type: data['error'].severity || 'error'}) if (data['error'].mode === 'panic') { return modalDialogCustom.alert(yo`
${value.output.url}
${result}`) + } + }, (item) => { // triggered each time there's a new verified publish (means hash correspond) + this._deps.swarmfileProvider.addReadOnly(item.hash, item.content) + }) + } + } + } + + details() { const help = { 'Assembly': 'Assembly opcodes describing the contract including corresponding solidity source code', 'Opcodes': 'Assembly opcodes describing the contract', @@ -182,115 +249,104 @@ 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 getContractProperty (property) { - const select = self._view.contractNames - if (select.children.length > 0 && select.selectedIndex >= 0) { - const contractName = select.children[select.selectedIndex].innerHTML - const contractProperties = self.data.contractsDetails[contractName] - return contractProperties[property] || null - } - } - function copyContractProperty (property) { - let content = getContractProperty(property) - if (!content) { - addTooltip('No content available for ' + property) - return - } - - try { - if (typeof content !== 'string') { - content = JSON.stringify(content, null, '\t') - } - } catch (e) {} + if (!this.selectedContract) throw new Error('No contract compiled yet') + const contractProperties = this.data.contractsDetails[this.selectedContract] + const log = yo`` + Object.keys(contractProperties).map(propertyName => { + const copyDetails = yo`${copyToClipboard(() => contractProperties[propertyName])}` + const questionMark = yo`` + log.appendChild(yo`
${details[propertyName]}` - } else if (propertyName === 'abi' || propertyName === 'metadata') { - const treeView = new TreeView({ - extractData: function (item, parent, key) { - var ret = {} - if (item instanceof Array) { - ret.children = item.map((item, index) => ({ key: index, value: item })) - ret.self = '' - } else if (item instanceof Object) { - ret.children = Object.keys(item).map((key) => ({key: key, value: item[key]})) - ret.self = '' - } else { - ret.self = item - ret.children = [] - } - return ret - } - }) - if (details[propertyName] !== '') { - try { - node = yo`
${details[propertyName]}` + } else if (propertyName === 'abi' || propertyName === 'metadata') { + const treeView = new TreeView({ + extractData: function (item, parent, key) { + var ret = {} + if (item instanceof Array) { + ret.children = item.map((item, index) => ({ key: index, value: item })) + ret.self = '' + } else if (item instanceof Object) { + ret.children = Object.keys(item).map((key) => ({key: key, value: item[key]})) + ret.self = '' + } else { + ret.self = item + ret.children = [] } - } else { - node = yo`
${node || ''}` + } else { + node = yo`
${value.output.url}
${result}`) - } - }, function (item) { // triggered each time there's a new verified publish (means hash correspond) - self._deps.swarmfileProvider.addReadOnly(item.hash, item.content) - }) - } - } + return yo`
${node || ''}` + } + + getContractProperty (property) { + if (!this.selectedContract) throw new Error('No contract compiled yet') + const contractProperties = this.data.contractsDetails[this.selectedContract] + return contractProperties[property] || null + } + + copyContractProperty (property) { + let content = getContractProperty(property) + if (!content) { + addTooltip('No content available for ' + property) + return } - return self._view.el + + try { + if (typeof content !== 'string') { + content = JSON.stringify(content, null, '\t') + } + } catch (e) {} + + copy(content) + addTooltip('Copied value to clipboard') + } + + copyABI () { + this.copyContractProperty('abi') + } + + copyBytecode () { + this.copyContractProperty('bytecode') + } + + render () { + if (this._view.el) return this._view.el + + this._view.errorContainer = yo`` + this._view.errorContainerHead = yo`` + this._view.contractSelection = this.contractSelection() + this._view.compilerContainer = this.compilerContainer.render() + this.compilerContainer.currentFile = this._deps.fileManager.currentFile() + + this._view.el = yo` +