Unverified Commit f43f4815 authored by yann300's avatar yann300 Committed by GitHub

Merge pull request #1318 from ethereum/refactor_compile

refactor compile tab
parents 3adf2ec3 ed61791b
/* global */ const yo = require('yo-yo')
var $ = require('jquery') const csjs = require('csjs-inject')
var yo = require('yo-yo')
var parseContracts = require('../contract/contractParser') const TreeView = require('../ui/TreeView')
var publishOnSwarm = require('../contract/publishOnSwarm') const modalDialog = require('../ui/modaldialog')
var modalDialog = require('../ui/modaldialog') const copyToClipboard = require('../ui/copy-to-clipboard')
var modalDialogCustom = require('../ui/modal-dialog-custom') const modalDialogCustom = require('../ui/modal-dialog-custom')
var TreeView = require('../ui/TreeView') const styleGuide = require('../ui/styles-guide/theme-chooser')
var copyToClipboard = require('../ui/copy-to-clipboard') const parseContracts = require('../contract/contractParser')
const publishOnSwarm = require('../contract/publishOnSwarm')
var css = require('./styles/compile-tab-styles') const styles = styleGuide.chooser()
var styleGuide = require('../ui/styles-guide/theme-chooser')
var styles = styleGuide.chooser()
function compileTab (appAPI = {}, appEvents = {}, opts = {}) { module.exports = class CompileTab {
// Containers constructor (api = {}, events = {}, opts = {}) {
var warnCompilationSlow = yo`<i title="Copy Address" style="display:none" class="${css.warnCompilationSlow} fa fa-exclamation-triangle" aria-hidden="true"></i>` const self = this
var compileIcon = yo`<i class="fa fa-refresh ${css.icon}" aria-hidden="true"></i>` self._opts = opts
var compileContainer = yo` self._api = api
<div class="${css.compileContainer}"> self._events = events
<div class="${css.compileButtons}"> self._view = {
<div class="${css.compileButton} "id="compile" title="Compile source code">${compileIcon} Start to compile</div> el: null,
<div class="${css.autocompileContainer}"> autoCompile: null,
<input class="${css.autocompile}" id="autoCompile" type="checkbox" title="Auto compile"> compileButton: null,
<span class="${css.autocompileText}">Auto compile</span> warnCompilationSlow: null,
</div> compileIcon: null,
${warnCompilationSlow} compileContainer: null,
</div> errorContainer: null,
</div> contractNames: null,
` contractEl: null
compileContainer.querySelector('#compile').addEventListener('click', () => {
appAPI.runCompiler()
})
var compileTimeout = null
function scheduleCompilation () {
if (!opts.config.get('autoCompile')) {
return
} }
self.data = {
if (compileTimeout) { autoCompile: self._opts.config.get('autoCompile'),
window.clearTimeout(compileTimeout) compileTimeout: null,
contractsDetails: {},
maxTime: 1000,
timeout: 300
} }
compileTimeout = window.setTimeout(() => { self._events.editor.register('contentChanged', scheduleCompilation)
appAPI.runCompiler() self._events.editor.register('sessionSwitched', scheduleCompilation)
}, 300) function scheduleCompilation () {
} if (!self._opts.config.get('autoCompile')) return
if (self.data.compileTimeout) window.clearTimeout(self.data.compileTimeout)
appEvents.editor.register('contentChanged', () => { self.data.compileTimeout = window.setTimeout(() => self._api.runCompiler(), self.data.timeout)
scheduleCompilation()
})
appEvents.editor.register('sessionSwitched', () => {
scheduleCompilation()
})
// ----------------- autoCompile -----------------
var autoCompileInput = compileContainer.querySelector('#autoCompile')
var autoCompile = false
if (opts.config.exists('autoCompile')) {
autoCompile = opts.config.get('autoCompile')
}
opts.config.set('autoCompile', autoCompile)
if (autoCompile) {
autoCompileInput.setAttribute('checked', autoCompile)
}
autoCompileInput.addEventListener('change', function () {
opts.config.set('autoCompile', autoCompileInput.checked)
})
// REGISTER EVENTS
// compilationDuration
appEvents.compiler.register('compilationDuration', function tabHighlighting (speed) {
if (speed > 1000) {
warnCompilationSlow.setAttribute('title', `Last compilation took ${speed}ms. We suggest to turn off autocompilation.`)
warnCompilationSlow.style.display = 'inline-block'
} else {
warnCompilationSlow.style.display = 'none'
} }
}) self._events.compiler.register('compilationDuration', function tabHighlighting (speed) {
// loadingCompiler if (!self._view.warnCompilationSlow) return
appEvents.editor.register('contentChanged', function changedFile () { if (speed > self.data.maxTime) {
var compileTab = document.querySelector('.compileView') const msg = `Last compilation took ${speed}ms. We suggest to turn off autocompilation.`
compileTab.style.color = styles.colors.red self._view.warnCompilationSlow.setAttribute('title', msg)
compileIcon.classList.add(`${css.bouncingIcon}`) self._view.warnCompilationSlow.style.display = 'inline-block'
}) } else {
appEvents.compiler.register('loadingCompiler', function start () { self._view.warnCompilationSlow.style.display = 'none'
compileIcon.classList.add(`${css.spinningIcon}`) }
warnCompilationSlow.style.display = 'none'
compileIcon.setAttribute('title', 'compiler is loading, please wait a few moments.')
})
appEvents.compiler.register('compilationFinished', function finish () {
var compileTab = document.querySelector('.compileView')
compileTab.style.color = styles.colors.black
compileIcon.style.color = styles.colors.black
compileIcon.classList.remove(`${css.spinningIcon}`)
compileIcon.classList.remove(`${css.bouncingIcon}`)
compileIcon.setAttribute('title', 'idle')
})
appEvents.compiler.register('compilationStarted', function start () {
compileIcon.classList.remove(`${css.bouncingIcon}`)
compileIcon.classList.add(`${css.spinningIcon}`)
compileIcon.setAttribute('title', 'compiling...')
})
appEvents.compiler.register('compilerLoaded', function loaded () {
compileIcon.classList.remove(`${css.spinningIcon}`)
compileIcon.setAttribute('title', '')
})
var errorContainer = yo`<div class='error'></div>`
var el = yo`
<div class="${css.compileTabView}" id="compileTabView">
${compileContainer}
${contractNames(appAPI, appEvents, opts)}
${errorContainer}
</div>
`
/* ------------------------------------------------
section CONTRACT DROPDOWN, DETAILS AND PUBLISH
------------------------------------------------ */
function contractNames (appAPI, appEvents, opts) {
var contractsDetails = {}
appEvents.compiler.register('compilationStarted', () => {
errorContainer.innerHTML = ''
}) })
self._events.editor.register('contentChanged', function changedFile () {
appEvents.compiler.register('compilationFinished', function (success, data, source) { 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 () {
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 () {
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 () {
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) {
if (self._view.compileIcon) {
const compileTab = document.querySelector('.compileView')
compileTab.style.color = styles.colors.black
self._view.compileIcon.style.color = styles.colors.black
self._view.compileIcon.classList.remove(`${css.spinningIcon}`)
self._view.compileIcon.classList.remove(`${css.bouncingIcon}`)
self._view.compileIcon.setAttribute('title', 'idle')
}
// reset the contractMetadata list (used by the publish action) // reset the contractMetadata list (used by the publish action)
contractsDetails = {} self.data.contractsDetails = {}
// refill the dropdown list // refill the dropdown list
getContractNames(success, data) self._view.contractNames.innerHTML = ''
// hightlight the tab if error
if (success) { if (success) {
document.querySelector('.compileView').style.color = '' 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))
var contractName = yo`<option>${contract.name}</option>`
self._view.contractNames.appendChild(contractName)
})
self._api.resetDapp(self.data.contractsDetails)
} else { } else {
document.querySelector('.compileView').style.color = styles.colors.red self._view.contractNames.setAttribute('disabled', true)
self._api.resetDapp({})
} }
// hightlight the tab if error
if (success) document.querySelector('.compileView').style.color = '' // @TODO: compileView tab
else document.querySelector('.compileView').style.color = styles.colors.red // @TODO: compileView tab
// display warning error if any // display warning error if any
var error = false var error = false
if (data['error']) { if (data['error']) {
error = true error = true
opts.renderer.error(data['error'].formattedMessage, $(errorContainer), {type: data['error'].severity}) self._opts.renderer.error(data['error'].formattedMessage, self._view.errorContainer, {type: data['error'].severity})
} }
if (data['errors']) { if (data.errors && data.errors.length) {
if (data['errors'].length) error = true error = true
data['errors'].forEach(function (err) { data.errors.forEach(function (err) {
opts.renderer.error(err.formattedMessage, $(errorContainer), {type: err.severity}) self._opts.renderer.error(err.formattedMessage, self._view.errorContainer, {type: err.severity})
}) })
} }
if (!error) { if (!error && data.contracts) {
if (data.contracts) { self._opts.compiler.visitContracts((contract) => {
opts.compiler.visitContracts((contract) => { self._opts.renderer.error(contract.name, self._view.errorContainer, {type: 'success'})
opts.renderer.error(contract.name, $(errorContainer), {type: 'success'}) })
})
}
} }
}) })
self._events.staticAnalysis.register('staticAnaysisWarning', (count) => {
appEvents.staticAnalysis.register('staticAnaysisWarning', (count) => {
if (count) { if (count) {
opts.renderer.error(`Static Analysis raised ${count} warning(s) that requires your attention.`, $(errorContainer), { const msg = `Static Analysis raised ${count} warning(s) that requires your attention.`
type: 'warning', const settings = { type: 'warning', click: () => self._api.switchTab('staticanalysisView') }
click: () => appAPI.switchTab('staticanalysisView') self._opts.renderer.error(msg, self._view.errorContainer, settings)
})
} }
}) })
}
var el = yo` render () {
const self = this
if (self._view.el) return self._view.el
self._view.warnCompilationSlow = yo`<i title="Copy Address" style="display:none" class="${css.warnCompilationSlow} fa fa-exclamation-triangle" aria-hidden="true"></i>`
self._view.compileIcon = yo`<i class="fa fa-refresh ${css.icon}" aria-hidden="true"></i>`
self._view.compileButton = yo`<div class="${css.compileButton}" onclick=${compile} id="compile" title="Compile source code">${self._view.compileIcon} Start to compile</div>`
self._view.autoCompile = yo`<input class="${css.autocompile}" onchange=${updateAutoCompile} id="autoCompile" type="checkbox" title="Auto compile">`
if (self.data.autoCompile) self._view.autoCompile.setAttribute('checked', '')
self._view.compileContainer = yo`
<div class="${css.compileContainer}">
<div class="${css.compileButtons}">
${self._view.compileButton}
<div class="${css.autocompileContainer}">
${self._view.autoCompile}
<span class="${css.autocompileText}">Auto compile</span>
</div>
${self._view.warnCompilationSlow}
</div>
</div>`
self._view.errorContainer = yo`<div class='error'></div>`
self._view.contractNames = yo`<select class="${css.contractNames}" disabled></select>`
self._view.contractEl = yo`
<div class="${css.container}"> <div class="${css.container}">
<select class="${css.contractNames}" disabled></select> ${self._view.contractNames}
<div class="${css.contractButtons}"> <div class="${css.contractButtons}">
<div title="Display Contract Details" class="${css.details}" onclick=${() => { details() }}>Details</div> <div title="Display Contract Details" class="${css.details}" onclick=${details}>Details</div>
<div title="Publish on Swarm" class="${css.publish}" onclick=${() => { publish(appAPI) }}>Publish on Swarm</div> <div title="Publish on Swarm" class="${css.publish}" onclick=${publish}>Publish on Swarm</div>
</div> </div>
</div> </div>`
` self._view.el = yo`
<div class="${css.compileTabView}" id="compileTabView">
// HELPERS ${self._view.compileContainer}
${self._view.contractEl}
// GET NAMES OF ALL THE CONTRACTS ${self._view.errorContainer}
function getContractNames (success, data) { </div>`
var contractNames = document.querySelector(`.${css.contractNames.classNames[0]}`) const help = {
contractNames.innerHTML = '' 'Assembly': 'Assembly opcodes describing the contract including corresponding solidity source code',
if (success) { 'Opcodes': 'Assembly opcodes describing the contract',
contractNames.removeAttribute('disabled') 'Runtime Bytecode': 'Bytecode storing the state and being executed during normal contract call',
opts.compiler.visitContracts((contract) => { 'bytecode': 'Bytecode being executed during contract creation',
contractsDetails[contract.name] = parseContracts(contract.name, contract.object, opts.compiler.getSource(contract.file)) 'functionHashes': 'List of declared function and their corresponding hash',
var contractName = yo` 'gasEstimates': 'Gas estimation for each function call',
<option> 'metadata': 'Contains all informations related to the compilation',
${contract.name} 'metadataHash': 'Hash representing all metadata information',
</option>` 'abi': 'ABI: describing all the functions (input/output params, scope, ...)',
contractNames.appendChild(contractName) 'name': 'Name of the compiled contract',
}) 'swarmLocation': 'Swarm url where all metadata information can be found (contract needs to be published first)',
appAPI.resetDapp(contractsDetails) 'web3Deploy': 'Copy/paste this code to any JavaScript/Web3 console to deploy this contract'
} else {
contractNames.setAttribute('disabled', true)
appAPI.resetDapp({})
}
} }
function updateAutoCompile (event) { self._opts.config.set('autoCompile', self._view.autoCompile.checked) }
function compile (event) { self._api.runCompiler() }
function details () { function details () {
var select = el.querySelector('select') const select = self._view.contractNames
if (select.children.length > 0 && select.selectedIndex >= 0) { if (select.children.length > 0 && select.selectedIndex >= 0) {
var contractName = select.children[select.selectedIndex].innerHTML const contractName = select.children[select.selectedIndex].innerHTML
var contractProperties = contractsDetails[contractName] const contractProperties = self.data.contractsDetails[contractName]
var log = yo`<div class="${css.detailsJSON}"></div>` const log = yo`<div class="${css.detailsJSON}"></div>`
Object.keys(contractProperties).map(propertyName => { Object.keys(contractProperties).map(propertyName => {
var copyDetails = yo`<span class="${css.copyDetails}"> const copyDetails = yo`<span class="${css.copyDetails}">${copyToClipboard(() => contractProperties[propertyName])}</span>`
${copyToClipboard(() => contractProperties[propertyName])} const questionMark = yo`<span class="${css.questionMark}"><i title="${help[propertyName]}" class="fa fa-question-circle" aria-hidden="true"></i></span>`
</span>` log.appendChild(yo`<div class=${css.log}>
var questionMark = yo`<span class="${css.questionMark}"><i title="${detailsHelpSection()[propertyName]}" class="fa fa-question-circle" aria-hidden="true"></i></span>` <div class="${css.key}">${propertyName} ${copyDetails} ${questionMark}</div>
log.appendChild(yo` ${insertValue(contractProperties, propertyName)}
<div class=${css.log}> </div>`)
<div class="${css.key}">${propertyName} ${copyDetails} ${questionMark}</div>
${insertValue(contractProperties, propertyName)}
</div>
`)
}) })
modalDialog(contractName, log, {label: ''}, {label: 'Close'}) modalDialog(contractName, log, { label: '' }, { label: 'Close' })
} }
} }
function insertValue (details, propertyName) { function insertValue (details, propertyName) {
var value = yo`<pre class="${css.value}"></pre>`
var node var node
if (propertyName === 'web3Deploy' || propertyName === 'name' || propertyName === 'Assembly') { if (propertyName === 'web3Deploy' || propertyName === 'name' || propertyName === 'Assembly') {
node = yo`<pre>${details[propertyName]}</pre>` node = yo`<pre>${details[propertyName]}</pre>`
} else if (propertyName === 'abi' || propertyName === 'metadata') { } else if (propertyName === 'abi' || propertyName === 'metadata') {
var treeView = new TreeView({ const treeView = new TreeView({
extractData: function (item, parent, key) { extractData: function (item, parent, key) {
var ret = {} var ret = {}
if (item instanceof Array) { if (item instanceof Array) {
ret.children = item.map((item, index) => { ret.children = item.map((item, index) => ({ key: index, value: item }))
return {key: index, value: item}
})
ret.self = '' ret.self = ''
} else if (item instanceof Object) { } else if (item instanceof Object) {
ret.children = Object.keys(item).map((key) => { ret.children = Object.keys(item).map((key) => ({key: key, value: item[key]}))
return {key: key, value: item[key]}
})
ret.self = '' ret.self = ''
} else { } else {
ret.self = item ret.self = item
...@@ -266,18 +231,16 @@ function compileTab (appAPI = {}, appEvents = {}, opts = {}) { ...@@ -266,18 +231,16 @@ function compileTab (appAPI = {}, appEvents = {}, opts = {}) {
} else { } else {
node = yo`<div>${JSON.stringify(details[propertyName], null, 4)}</div>` node = yo`<div>${JSON.stringify(details[propertyName], null, 4)}</div>`
} }
if (node) value.appendChild(node) return yo`<pre class="${css.value}">${node || ''}</pre>`
return value
} }
function publish () {
function publish (appAPI) { const selectContractNames = self._view.contractNames
var selectContractNames = document.querySelector(`.${css.contractNames.classNames[0]}`)
if (selectContractNames.children.length > 0 && selectContractNames.selectedIndex >= 0) { if (selectContractNames.children.length > 0 && selectContractNames.selectedIndex >= 0) {
var contract = contractsDetails[selectContractNames.children[selectContractNames.selectedIndex].innerHTML] var contract = self.data.contractsDetails[selectContractNames.children[selectContractNames.selectedIndex].innerHTML]
if (contract.metadata === undefined || contract.metadata.length === 0) { if (contract.metadata === undefined || contract.metadata.length === 0) {
modalDialogCustom.alert('This contract does not implement all functions and thus cannot be published.') modalDialogCustom.alert('This contract does not implement all functions and thus cannot be published.')
} else { } else {
publishOnSwarm(contract, appAPI, function (err) { publishOnSwarm(contract, self._api, function (err) {
if (err) { if (err) {
try { try {
err = JSON.stringify(err) err = JSON.stringify(err)
...@@ -287,33 +250,150 @@ function compileTab (appAPI = {}, appEvents = {}, opts = {}) { ...@@ -287,33 +250,150 @@ function compileTab (appAPI = {}, appEvents = {}, opts = {}) {
} else { } else {
modalDialogCustom.alert(yo`<span>Metadata published successfully.<br />The Swarm address of the metadata file is available in the contract details.</span>`) modalDialogCustom.alert(yo`<span>Metadata published successfully.<br />The Swarm address of the metadata file is available in the contract details.</span>`)
} }
}, function (item) { }, function (item) { // triggered each time there's a new verified publish (means hash correspond)
// triggered each time there's a new verified publish (means hash correspond) self._api.fileProvider('swarm').addReadOnly(item.hash, item.content)
appAPI.fileProvider('swarm').addReadOnly(item.hash, item.content)
}) })
} }
} }
} }
return el return self._view.el
} }
return { render () { return el } }
} }
function detailsHelpSection () { const css = csjs`
return { .compileTabView {
'Assembly': 'Assembly opcodes describing the contract including corresponding solidity source code', padding: 2%;
'Opcodes': 'Assembly opcodes describing the contract',
'Runtime Bytecode': 'Bytecode storing the state and being executed during normal contract call',
'bytecode': 'Bytecode being executed during contract creation',
'functionHashes': 'List of declared function and their corresponding hash',
'gasEstimates': 'Gas estimation for each function call',
'metadata': 'Contains all informations related to the compilation',
'metadataHash': 'Hash representing all metadata information',
'abi': 'ABI: describing all the functions (input/output params, scope, ...)',
'name': 'Name of the compiled contract',
'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'
} }
} .contract {
display: block;
module.exports = compileTab margin: 3% 0;
}
.compileContainer {
${styles.rightPanel.compileTab.box_CompileContainer};
margin-bottom: 2%;
}
.autocompileContainer {
width: 90px;
display: flex;
align-items: center;
}
.autocompile {}
.autocompileTitle {
font-weight: bold;
margin: 1% 0;
}
.autocompileText {
margin: 1% 0;
font-size: 12px;
overflow: hidden;
word-break: normal;
line-height: initial;
}
.warnCompilationSlow {
color: ${styles.rightPanel.compileTab.icon_WarnCompilation_Color};
margin-left: 1%;
}
.compileButtons {
display: flex;
align-items: center;
flex-wrap: wrap;
}
.name {
display: flex;
}
.size {
display: flex;
}
.compileButton {
${styles.rightPanel.compileTab.button_Compile};
width: 120px;
min-width: 110px;
margin-right: 1%;
font-size: 12px;
}
.container {
${styles.rightPanel.compileTab.box_CompileContainer};
margin: 0;
display: flex;
align-items: center;
}
.contractNames {
${styles.rightPanel.compileTab.dropdown_CompileContract};
margin-right: 5%;
}
.contractButtons {
display: flex;
cursor: pointer;
justify-content: center;
text-align: center;
}
.details {
${styles.rightPanel.compileTab.button_Details};
}
.publish {
${styles.rightPanel.compileTab.button_Publish};
margin-left: 2%;
width: 120px;
}
.log {
${styles.rightPanel.compileTab.box_CompileContainer};
display: flex;
flex-direction: column;
margin-bottom: 5%;
overflow: visible;
}
.key {
margin-right: 5px;
color: ${styles.rightPanel.text_Primary};
text-transform: uppercase;
width: 100%;
}
.value {
display: flex;
width: 100%;
margin-top: 1.5%;
}
.questionMark {
margin-left: 2%;
cursor: pointer;
color: ${styles.rightPanel.icon_Color_TogglePanel};
}
.questionMark:hover {
color: ${styles.rightPanel.icon_HoverColor_TogglePanel};
}
.detailsJSON {
padding: 8px 0;
background-color: ${styles.rightPanel.modalDialog_BackgroundColor_Primary};
border: none;
color: ${styles.rightPanel.modalDialog_text_Secondary};
}
.icon {
margin-right: 3%;
}
.spinningIcon {
margin-right: .3em;
animation: spin 2s linear infinite;
}
.bouncingIcon {
margin-right: .3em;
animation: bounce 2s infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
@-webkit-keyframes bounce {
0% {
margin-bottom: 0;
color: ${styles.colors.transparent};
}
70% {
margin-bottom: 0;
color: ${styles.rightPanel.text_Secondary};
}
100% {
margin-bottom: 0;
color: ${styles.colors.transparent};
}
}
`
var csjs = require('csjs-inject')
var styleGuide = require('../../ui/styles-guide/theme-chooser')
var styles = styleGuide.chooser()
var css = csjs`
.compileTabView {
padding: 2%;
}
.contract {
display: block;
margin: 3% 0;
}
.compileContainer {
${styles.rightPanel.compileTab.box_CompileContainer};
margin-bottom: 2%;
}
.autocompileContainer {
width: 90px;
display: flex;
align-items: center;
}
.autocompile {}
.autocompileTitle {
font-weight: bold;
margin: 1% 0;
}
.autocompileText {
margin: 1% 0;
font-size: 12px;
overflow: hidden;
word-break: normal;
line-height: initial;
}
.warnCompilationSlow {
color: ${styles.rightPanel.compileTab.icon_WarnCompilation_Color};
margin-left: 1%;
}
.compileButtons {
display: flex;
align-items: center;
flex-wrap: wrap;
}
.name {
display: flex;
}
.size {
display: flex;
}
.compileButton {
${styles.rightPanel.compileTab.button_Compile};
width: 120px;
min-width: 110px;
margin-right: 1%;
font-size: 12px;
}
.container {
${styles.rightPanel.compileTab.box_CompileContainer};
margin: 0;
display: flex;
align-items: center;
}
.contractNames {
${styles.rightPanel.compileTab.dropdown_CompileContract};
margin-right: 5%;
}
.contractButtons {
display: flex;
cursor: pointer;
justify-content: center;
text-align: center;
}
.details {
${styles.rightPanel.compileTab.button_Details};
}
.publish {
${styles.rightPanel.compileTab.button_Publish};
margin-left: 2%;
width: 120px;
}
.log {
${styles.rightPanel.compileTab.box_CompileContainer};
display: flex;
flex-direction: column;
margin-bottom: 5%;
overflow: visible;
}
.key {
margin-right: 5px;
color: ${styles.rightPanel.text_Primary};
text-transform: uppercase;
width: 100%;
}
.value {
display: flex;
width: 100%;
margin-top: 1.5%;
}
.questionMark {
margin-left: 2%;
cursor: pointer;
color: ${styles.rightPanel.icon_Color_TogglePanel};
}
.questionMark:hover {
color: ${styles.rightPanel.icon_HoverColor_TogglePanel};
}
.detailsJSON {
padding: 8px 0;
background-color: ${styles.rightPanel.modalDialog_BackgroundColor_Primary};
border: none;
color: ${styles.rightPanel.modalDialog_text_Secondary};
}
.icon {
margin-right: 3%;
}
.spinningIcon {
margin-right: .3em;
animation: spin 2s linear infinite;
}
.bouncingIcon {
margin-right: .3em;
animation: bounce 2s infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
@-webkit-keyframes bounce {
0% {
margin-bottom: 0;
color: ${styles.colors.transparent};
}
70% {
margin-bottom: 0;
color: ${styles.rightPanel.text_Secondary};
}
100% {
margin-bottom: 0;
color: ${styles.colors.transparent};
}
}
`
module.exports = css
...@@ -56,7 +56,7 @@ Renderer.prototype.error = function (message, container, opt) { ...@@ -56,7 +56,7 @@ Renderer.prototype.error = function (message, container, opt) {
var $pre = $(opt.useSpan ? yo`<span />` : yo`<pre />`).html(message) var $pre = $(opt.useSpan ? yo`<span />` : yo`<pre />`).html(message)
var $error = $(yo`<div class="sol ${opt.type}"><div class="close"><i class="fa fa-close"></i></div></div>`).prepend($pre) var $error = $(yo`<div class="sol ${opt.type}"><div class="close"><i class="fa fa-close"></i></div></div>`).prepend($pre)
container.append($error) $(container).append($error)
$error.click((ev) => { $error.click((ev) => {
if (opt.errFile && opt.errLine) { if (opt.errFile && opt.errLine) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment