@ -14,293 +14,291 @@ var publishOnSwarm = require('../contract/publishOnSwarm')
var styles = styleGuide . chooser ( )
var x = {
compileTab : compileTab
}
function compileTab ( appAPI = { } , appEvents = { } , opts = { } ) {
// Containers
var warnCompilationSlow = yo ` <i title="Copy Address" style="display:none" class=" ${ css . warnCompilationSlow } fa fa-exclamation-triangle" aria-hidden="true"></i> `
var compileIcon = yo ` <i class="fa fa-refresh ${ css . icon } " aria-hidden="true"></i> `
var compileContainer = yo `
< div class = "${css.compileContainer}" >
< div class = "${css.compileButtons}" >
< div class = "${css.compileButton} " id = "compile" title = "Compile source code" > $ { compileIcon } Start to compile < / d i v >
< div class = "${css.autocompileContainer}" >
< input class = "${css.autocompile}" id = "autoCompile" type = "checkbox" title = "Auto compile" >
< span class = "${css.autocompileText}" > Auto compile < / s p a n >
compileTab : function compileTab ( appAPI = { } , appEvents = { } , opts = { } ) {
// Containers
var warnCompilationSlow = yo ` <i title="Copy Address" style="display:none" class=" ${ css . warnCompilationSlow } fa fa-exclamation-triangle" aria-hidden="true"></i> `
var compileIcon = yo ` <i class="fa fa-refresh ${ css . icon } " aria-hidden="true"></i> `
var compileContainer = yo `
< div class = "${css.compileContainer}" >
< div class = "${css.compileButtons}" >
< div class = "${css.compileButton} " id = "compile" title = "Compile source code" > $ { compileIcon } Start to compile < / d i v >
< div class = "${css.autocompileContainer}" >
< input class = "${css.autocompile}" id = "autoCompile" type = "checkbox" title = "Auto compile" >
< span class = "${css.autocompileText}" > Auto compile < / s p a n >
< / d i v >
$ { warnCompilationSlow }
< / d i v >
$ { warnCompilationSlow }
< / d i v >
< / d i v >
`
`
compileContainer . querySelector ( '#compile' ) . addEventListener ( 'click' , ( ) => {
appAPI . runCompiler ( )
} )
compileContainer . querySelector ( '#compile' ) . addEventListener ( 'click' , ( ) => {
appAPI . runCompiler ( )
} )
var compileTimeout = null
function scheduleCompilation ( ) {
if ( ! opts . config . get ( 'autoCompile' ) ) {
return
}
var compileTimeout = null
function scheduleCompilation ( ) {
if ( ! opts . config . get ( 'autoCompile' ) ) {
return
}
if ( compileTimeout ) {
window . clearTimeout ( compileTimeout )
if ( compileTimeout ) {
window . clearTimeout ( compileTimeout )
}
compileTimeout = window . setTimeout ( ( ) => {
appAPI . runCompiler ( )
} , 300 )
}
compileTimeout = window . setTimeout ( ( ) => {
appAPI . runCompiler ( )
} , 300 )
}
appEvents . editor . register ( 'contentChanged' , ( ) => {
scheduleCompilation ( )
} )
appEvents . editor . register ( 'contentChanged' , ( ) => {
scheduleCompilation ( )
} )
appEvents . editor . register ( 'sessionSwitched' , ( ) => {
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 )
}
// ----------------- 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 )
} )
autoCompileInput . addEventListener ( 'change' , function ( ) {
opts . config . set ( 'autoCompile' , autoCompileInput . checked )
} )
// REGISTER EVENTS
// 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 {
// 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'
}
} )
// loadingCompiler
appEvents . editor . register ( 'contentChanged' , function changedFile ( ) {
var compileTab = document . querySelector ( '.compileView' )
compileTab . style . color = styles . colors . red
compileIcon . classList . add ( ` ${ css . bouncingIcon } ` )
} )
appEvents . compiler . register ( 'loadingCompiler' , function start ( ) {
compileIcon . classList . add ( ` ${ css . spinningIcon } ` )
warnCompilationSlow . style . display = 'none'
}
} )
// loadingCompiler
appEvents . editor . register ( 'contentChanged' , function changedFile ( ) {
var compileTab = document . querySelector ( '.compileView' )
compileTab . style . color = styles . colors . red
compileIcon . classList . add ( ` ${ css . bouncingIcon } ` )
} )
appEvents . compiler . register ( 'loadingCompiler' , function start ( ) {
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' , '' )
} )
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 }
< / d i v >
`
var errorContainer = yo ` <div class='error'></div> `
var el = yo `
< div class = "${css.compileTabView}" id = "compileTabView" >
$ { compileContainer }
$ { contractNames ( appAPI , appEvents , opts ) }
$ { errorContainer }
< / d i v >
`
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
section CONTRACT DROPDOWN , DETAILS AND PUBLISH
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- * /
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
section CONTRACT DROPDOWN , DETAILS AND PUBLISH
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- * /
function contractNames ( appAPI , appEvents , opts ) {
var contractsDetails = { }
function contractNames ( appAPI , appEvents , opts ) {
var contractsDetails = { }
appEvents . compiler . register ( 'compilationStarted' , ( ) => {
errorContainer . innerHTML = ''
} )
appEvents . compiler . register ( 'compilationStarted' , ( ) => {
errorContainer . innerHTML = ''
} )
appEvents . compiler . register ( 'compilationFinished' , function ( success , data , source ) {
// reset the contractMetadata list (used by the publish action)
contractsDetails = { }
// refill the dropdown list
getContractNames ( success , data )
// hightlight the tab if error
if ( success ) {
document . querySelector ( '.compileView' ) . style . color = ''
} else {
document . querySelector ( '.compileView' ) . style . color = styles . colors . red
}
// display warning error if any
var error = false
if ( data [ 'error' ] ) {
error = true
opts . renderer . error ( data [ 'error' ] . formattedMessage , $ ( errorContainer ) , { type : data [ 'error' ] . severity } )
}
if ( data [ 'errors' ] ) {
if ( data [ 'errors' ] . length ) error = true
data [ 'errors' ] . forEach ( function ( err ) {
opts . renderer . error ( err . formattedMessage , $ ( errorContainer ) , { type : err . severity } )
} )
}
if ( ! error ) {
if ( data . contracts ) {
opts . compiler . visitContracts ( ( contract ) => {
opts . renderer . error ( contract . name , $ ( errorContainer ) , { type : 'success' } )
appEvents . compiler . register ( 'compilationFinished' , function ( success , data , source ) {
// reset the contractMetadata list (used by the publish action)
contractsDetails = { }
// refill the dropdown list
getContractNames ( success , data )
// hightlight the tab if error
if ( success ) {
document . querySelector ( '.compileView' ) . style . color = ''
} else {
document . querySelector ( '.compileView' ) . style . color = styles . colors . red
}
// display warning error if any
var error = false
if ( data [ 'error' ] ) {
error = true
opts . renderer . error ( data [ 'error' ] . formattedMessage , $ ( errorContainer ) , { type : data [ 'error' ] . severity } )
}
if ( data [ 'errors' ] ) {
if ( data [ 'errors' ] . length ) error = true
data [ 'errors' ] . forEach ( function ( err ) {
opts . renderer . error ( err . formattedMessage , $ ( errorContainer ) , { type : err . severity } )
} )
}
}
} )
if ( ! error ) {
if ( data . contracts ) {
opts . compiler . visitContracts ( ( contract ) => {
opts . renderer . error ( contract . name , $ ( errorContainer ) , { type : 'success' } )
} )
}
}
} )
appEvents . staticAnalysis . register ( 'staticAnaysisWarning' , ( count ) => {
if ( count ) {
opts . renderer . error ( ` Static Analysis raised ${ count } warning(s) that requires your attention. ` , $ ( errorContainer ) , {
type : 'warning' ,
click : ( ) => appAPI . switchTab ( 'staticanalysisView' )
} )
}
} )
appEvents . staticAnalysis . register ( 'staticAnaysisWarning' , ( count ) => {
if ( count ) {
opts . renderer . error ( ` Static Analysis raised ${ count } warning(s) that requires your attention. ` , $ ( errorContainer ) , {
type : 'warning' ,
click : ( ) => appAPI . switchTab ( 'staticanalysisView' )
} )
}
} )
var el = yo `
< div class = "${css.container}" >
< select class = "${css.contractNames}" disabled > < / s e l e c t >
< div class = "${css.contractButtons}" >
< div title = "Display Contract Details" class = "${css.details}" onclick = $ { ( ) => { details ( ) } } > Details < / d i v >
< div title = "Publish on Swarm" class = "${css.publish}" onclick = $ { ( ) => { publish ( appAPI ) } } > Publish on Swarm < / d i v >
var el = yo `
< div class = "${css.container}" >
< select class = "${css.contractNames}" disabled > < / s e l e c t >
< div class = "${css.contractButtons}" >
< div title = "Display Contract Details" class = "${css.details}" onclick = $ { ( ) => { details ( ) } } > Details < / d i v >
< div title = "Publish on Swarm" class = "${css.publish}" onclick = $ { ( ) => { publish ( appAPI ) } } > Publish on Swarm < / d i v >
< / d i v >
< / d i v >
< / d i v >
`
`
// HELPERS
// HELPERS
// GET NAMES OF ALL THE CONTRACTS
function getContractNames ( success , data ) {
var contractNames = document . querySelector ( ` . ${ css . contractNames . classNames [ 0 ] } ` )
contractNames . innerHTML = ''
if ( success ) {
contractNames . removeAttribute ( 'disabled' )
opts . compiler . visitContracts ( ( contract ) => {
contractsDetails [ contract . name ] = parseContracts ( contract . name , contract . object , opts . compiler . getSource ( contract . file ) )
var contractName = yo `
< option >
$ { contract . name }
< / o p t i o n > `
contractNames . appendChild ( contractName )
} )
appAPI . resetDapp ( contractsDetails )
} else {
contractNames . setAttribute ( 'disabled' , true )
appAPI . resetDapp ( { } )
// GET NAMES OF ALL THE CONTRACTS
function getContractNames ( success , data ) {
var contractNames = document . querySelector ( ` . ${ css . contractNames . classNames [ 0 ] } ` )
contractNames . innerHTML = ''
if ( success ) {
contractNames . removeAttribute ( 'disabled' )
opts . compiler . visitContracts ( ( contract ) => {
contractsDetails [ contract . name ] = parseContracts ( contract . name , contract . object , opts . compiler . getSource ( contract . file ) )
var contractName = yo `
< option >
$ { contract . name }
< / o p t i o n > `
contractNames . appendChild ( contractName )
} )
appAPI . resetDapp ( contractsDetails )
} else {
contractNames . setAttribute ( 'disabled' , true )
appAPI . resetDapp ( { } )
}
}
}
function details ( ) {
var select = el . querySelector ( 'select' )
function details ( ) {
var select = el . querySelector ( 'select' )
if ( select . children . length > 0 && select . selectedIndex >= 0 ) {
var contractName = select . children [ select . selectedIndex ] . innerHTML
var contractProperties = contractsDetails [ contractName ]
var log = yo ` <div class=" ${ css . detailsJSON } "></div> `
Object . keys ( contractProperties ) . map ( propertyName => {
var copyDetails = yo ` <span class=" ${ css . copyDetails } ">
$ { copyToClipboard ( ( ) => contractProperties [ propertyName ] ) }
< / s p a n > `
var questionMark = yo ` <span class=" ${ css . questionMark } "><i title=" ${ detailsHelpSection ( ) [ propertyName ] } " class="fa fa-question-circle" aria-hidden="true"></i></span> `
log . appendChild ( yo `
< div class = $ { css . log } >
< div class = "${css.key}" > $ { propertyName } $ { copyDetails } $ { questionMark } < / d i v >
$ { insertValue ( contractProperties , propertyName ) }
< / d i v >
` )
} )
modalDialog ( contractName , log , { label : '' } , { label : 'Close' } )
if ( select . children . length > 0 && select . selectedIndex >= 0 ) {
var contractName = select . children [ select . selectedIndex ] . innerHTML
var contractProperties = contractsDetails [ contractName ]
var log = yo ` <div class=" ${ css . detailsJSON } "></div> `
Object . keys ( contractProperties ) . map ( propertyName => {
var copyDetails = yo ` <span class=" ${ css . copyDetails } ">
$ { copyToClipboard ( ( ) => contractProperties [ propertyName ] ) }
< / s p a n > `
var questionMark = yo ` <span class=" ${ css . questionMark } "><i title=" ${ detailsHelpSection ( ) [ propertyName ] } " class="fa fa-question-circle" aria-hidden="true"></i></span> `
log . appendChild ( yo `
< div class = $ { css . log } >
< div class = "${css.key}" > $ { propertyName } $ { copyDetails } $ { questionMark } < / d i v >
$ { insertValue ( contractProperties , propertyName ) }
< / d i v >
` )
} )
modalDialog ( contractName , log , { label : '' } , { label : 'Close' } )
}
}
}
function insertValue ( details , propertyName ) {
var value = yo ` <pre class=" ${ css . value } "></pre> `
var node
if ( propertyName === 'web3Deploy' || propertyName === 'name' || propertyName === 'Assembly' ) {
node = yo ` <pre> ${ details [ propertyName ] } </pre> `
} else if ( propertyName === 'abi' || propertyName === 'metadata' ) {
var treeView = new TreeView ( {
extractData : function ( item , parent , key ) {
var ret = { }
if ( item instanceof Array ) {
ret . children = item . map ( ( item , index ) => {
return { key : index , value : item }
} )
ret . self = ''
} else if ( item instanceof Object ) {
ret . children = Object . keys ( item ) . map ( ( key ) => {
return { key : key , value : item [ key ] }
} )
ret . self = ''
} else {
ret . self = item
ret . children = [ ]
function insertValue ( details , propertyName ) {
var value = yo ` <pre class=" ${ css . value } "></pre> `
var node
if ( propertyName === 'web3Deploy' || propertyName === 'name' || propertyName === 'Assembly' ) {
node = yo ` <pre> ${ details [ propertyName ] } </pre> `
} else if ( propertyName === 'abi' || propertyName === 'metadata' ) {
var treeView = new TreeView ( {
extractData : function ( item , parent , key ) {
var ret = { }
if ( item instanceof Array ) {
ret . children = item . map ( ( item , index ) => {
return { key : index , value : item }
} )
ret . self = ''
} else if ( item instanceof Object ) {
ret . children = Object . keys ( item ) . map ( ( key ) => {
return { key : key , value : item [ key ] }
} )
ret . self = ''
} else {
ret . self = item
ret . children = [ ]
}
return ret
}
return ret
}
} )
if ( details [ propertyName ] !== '' ) {
try {
node = yo ` <div> ${ treeView . render ( typeof details [ propertyName ] === 'object' ? details [ propertyName ] : JSON . parse ( details [ propertyName ] ) ) } </div> ` // catch in case the parsing fails.
} catch ( e ) {
node = yo ` <div>Unable to display " ${ propertyName } ": ${ e . message } </div> `
} )
if ( details [ propertyName ] !== '' ) {
try {
node = yo ` <div> ${ treeView . render ( typeof details [ propertyName ] === 'object' ? details [ propertyName ] : JSON . parse ( details [ propertyName ] ) ) } </div> ` // catch in case the parsing fails.
} catch ( e ) {
node = yo ` <div>Unable to display " ${ propertyName } ": ${ e . message } </div> `
}
} else {
node = yo ` <div> - </div> `
}
} else {
node = yo ` <div> - </div> `
node = yo ` <div> ${ JSON . stringify ( details [ propertyName ] , null , 4 ) } </div> `
}
} else {
node = yo ` <div> ${ JSON . stringify ( details [ propertyName ] , null , 4 ) } </div> `
if ( node ) value . appendChild ( node )
return value
}
if ( node ) value . appendChild ( node )
return value
}
function publish ( appAPI ) {
var selectContractNames = document . querySelector ( ` . ${ css . contractNames . classNames [ 0 ] } ` )
if ( selectContractNames . children . length > 0 && selectContractNames . selectedIndex >= 0 ) {
var contract = contractsDetails [ selectContractNames . children [ selectContractNames . selectedIndex ] . innerHTML ]
if ( contract . metadata === undefined || contract . metadata . length === 0 ) {
modalDialogCustom . alert ( 'This contract does not implement all functions and thus cannot be published.' )
} else {
publishOnSwarm ( contract , appAPI , function ( err ) {
if ( err ) {
try {
err = JSON . stringify ( err )
} catch ( e ) { }
modalDialogCustom . alert ( yo ` <span>Failed to publish metadata file to swarm, please check the Swarm gateways is available ( swarm-gateways.net ).<br />
$ { err } < / s p a n > ` )
} else {
modalDialogCustom . alert ( yo ` <span>Metadata published successfully.<br />The Swarm address of the metadata file is available in the contract details.</span> ` )
}
} , function ( item ) {
// triggered each time there's a new verified publish (means hash correspond)
appAPI . fileProvider ( 'swarm' ) . addReadOnly ( item . hash , item . content )
} )
function publish ( appAPI ) {
var selectContractNames = document . querySelector ( ` . ${ css . contractNames . classNames [ 0 ] } ` )
if ( selectContractNames . children . length > 0 && selectContractNames . selectedIndex >= 0 ) {
var contract = contractsDetails [ selectContractNames . children [ selectContractNames . selectedIndex ] . innerHTML ]
if ( contract . metadata === undefined || contract . metadata . length === 0 ) {
modalDialogCustom . alert ( 'This contract does not implement all functions and thus cannot be published.' )
} else {
publishOnSwarm ( contract , appAPI , function ( err ) {
if ( err ) {
try {
err = JSON . stringify ( err )
} catch ( e ) { }
modalDialogCustom . alert ( yo ` <span>Failed to publish metadata file to swarm, please check the Swarm gateways is available ( swarm-gateways.net ).<br />
$ { err } < / s p a n > ` )
} else {
modalDialogCustom . alert ( yo ` <span>Metadata published successfully.<br />The Swarm address of the metadata file is available in the contract details.</span> ` )
}
} , function ( item ) {
// triggered each time there's a new verified publish (means hash correspond)
appAPI . fileProvider ( 'swarm' ) . addReadOnly ( item . hash , item . content )
} )
}
}
}
return el
}
return el
return { render ( ) { return el } }
}
return { render ( ) { return el } }
}
function detailsHelpSection ( ) {