@ -40,16 +40,19 @@ module.exports = class Filepanel extends ApiFactory {
config : self . _components . registry . get ( 'config' ) . api ,
pluginManager : self . _components . registry . get ( 'pluginmanager' ) . api
}
var fileExplorer = new FileExplorer ( self . _components . registry , self . _deps . fileProviders [ 'browser' ] )
var fileExplorer = new FileExplorer ( self . _components . registry , self . _deps . fileProviders [ 'browser' ] ,
[ 'createNewFile' , 'publishToGist' , 'copyFiles' , canUpload ? 'uploadFile' : '' ]
)
var fileSystemExplorer = new FileExplorer ( self . _components . registry , self . _deps . fileProviders [ 'localhost' ] )
var swarmExplorer = new FileExplorer ( self . _components . registry , self . _deps . fileProviders [ 'swarm' ] )
var githubExplorer = new FileExplorer ( self . _components . registry , self . _deps . fileProviders [ 'github' ] )
var gistExplorer = new FileExplorer ( self . _components . registry , self . _deps . fileProviders [ 'gist' ] )
var gistExplorer = new FileExplorer ( self . _components . registry , self . _deps . fileProviders [ 'gist' ] , [ 'updateGist' ] )
var configExplorer = new FileExplorer ( self . _components . registry , self . _deps . fileProviders [ 'config' ] )
var httpExplorer = new FileExplorer ( self . _components . registry , self . _deps . fileProviders [ 'http' ] )
var httpsExplorer = new FileExplorer ( self . _components . registry , self . _deps . fileProviders [ 'https' ] )
self . remixdHandle = new RemixdHandle ( fileSystemExplorer , self . _deps . fileProviders [ 'localhost' ] )
self . remixdHandle = new RemixdHandle ( fileSystemExplorer , self . _deps . fileProviders [ 'localhost' ] ,
self . _deps . fileProviders [ 'localhost' ] . isReadOnly ? [ 'createNewFile' ] : [ ] )
// ----------------- editor panel ----------------------
self . _compilerMetadata = new CompilerMetadata (
@ -66,28 +69,7 @@ module.exports = class Filepanel extends ApiFactory {
function template ( ) {
return yo `
< div class = $ { css . container } >
< div class = "${css.fileexplorer}" >
< div class = $ { css . menu } >
< span onclick = $ { createNewFile } class = "newFile ${css.newFile}" title = "Create New File in the Browser Storage Explorer" >
< i class = "fa fa-plus-circle" > < / i >
< / s p a n >
$ { canUpload ? yo `
< span class = $ { css . uploadFile } title = "Add Local file to the Browser Storage Explorer" >
< label class = "fa fa-folder-open" >
< input type = "file" onchange = $ { uploadFile } multiple / >
< / l a b e l >
< / s p a n >
` : ''}
< span class = "${css.gist}" title = "Publish all [browser] explorer files to a github gist" onclick = $ { ( ) => publishToGist ( 'browser' ) } >
< i class = "fa fa-github" > < / i >
< / s p a n >
< span class = "${css.gist}" title = "Update the current [gist] explorer" onclick = $ { ( ) => updateGist ( ) } >
< i class = "fa fa-github" > < / i >
< / s p a n >
< span class = "${css.copyFiles}" title = "Copy all files to another instance of Remix IDE" onclick = $ { copyFiles } >
< i class = "fa fa-files-o" aria - hidden = "true" > < / i >
< / s p a n >
< / d i v >
< div class = "${css.fileexplorer}" >
< div >
< div class = $ { css . treeview } > $ { fileExplorer . init ( ) } < / d i v >
< div class = "configexplorer ${css.treeview}" > $ { configExplorer . init ( ) } < / d i v >
@ -156,149 +138,6 @@ module.exports = class Filepanel extends ApiFactory {
} )
self . render = function render ( ) { return element }
function uploadFile ( event ) {
// TODO The file explorer is merely a view on the current state of
// the files module. Please ask the user here if they want to overwrite
// a file and then just use `files.add`. The file explorer will
// pick that up via the 'fileAdded' event from the files module.
; [ ... this . files ] . forEach ( ( file ) => {
var files = fileExplorer . files
function loadFile ( ) {
var fileReader = new FileReader ( )
fileReader . onload = function ( event ) {
if ( helper . checkSpecialChars ( file . name ) ) {
modalDialogCustom . alert ( 'Special characters are not allowed' )
return
}
var success = files . set ( name , event . target . result )
if ( ! success ) modalDialogCustom . alert ( 'Failed to create file ' + name )
else self . event . trigger ( 'focus' , [ name ] )
}
fileReader . readAsText ( file )
}
var name = files . type + '/' + file . name
files . exists ( name , ( error , exist ) => {
if ( error ) console . log ( error )
if ( ! exist ) {
loadFile ( )
} else {
modalDialogCustom . confirm ( null , ` The file ${ name } already exists! Would you like to overwrite it? ` , ( ) => { loadFile ( ) } )
}
} )
} )
}
function createNewFile ( ) {
modalDialogCustom . prompt ( null , 'File Name' , 'Untitled.sol' , ( input ) => {
helper . createNonClashingName ( input , self . _deps . fileProviders [ 'browser' ] , ( error , newName ) => {
if ( error ) return modalDialogCustom . alert ( 'Failed to create file ' + newName + ' ' + error )
if ( ! self . _deps . fileProviders [ 'browser' ] . set ( newName , '' ) ) {
modalDialogCustom . alert ( 'Failed to create file ' + newName )
} else {
var file = self . _deps . fileProviders [ 'browser' ] . type + '/' + newName
self . _deps . fileManager . switchFile ( file )
if ( file . includes ( '_test.sol' ) ) {
self . event . trigger ( 'newTestFileCreated' , [ file ] )
}
}
} )
} , null , true )
}
// ------------------ gist publish --------------
function updateGist ( ) {
var gistId = self . _deps . fileProviders [ 'gist' ] . id
if ( ! gistId ) {
tooltip ( 'no gist content is currently loaded.' )
} else {
toGist ( 'gist' , gistId )
}
}
function publishToGist ( fileProviderName ) {
modalDialogCustom . confirm ( null , 'Are you very sure you want to publish all your files anonymously as a public gist on github.com?' , ( ) => {
toGist ( fileProviderName )
} )
}
function toGist ( fileProviderName , id ) {
packageFiles ( self . _deps . fileProviders [ fileProviderName ] , ( error , packaged ) => {
if ( error ) {
console . log ( error )
modalDialogCustom . alert ( 'Failed to create gist: ' + error )
} else {
var tokenAccess = self . _deps . config . get ( 'settings/gist-access-token' )
if ( ! tokenAccess ) {
modalDialogCustom . alert ( 'Remix requires an access token (which includes gists creation permission). Please go to the settings tab for more information.' )
} else {
var description = 'Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. \n Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=' + queryParams . get ( ) . version + '&optimize=' + queryParams . get ( ) . optimize + '&gist='
var gists = new Gists ( {
token : tokenAccess
} )
if ( id ) {
tooltip ( 'Saving gist (' + id + ') ...' )
gists . edit ( {
description : description ,
public : true ,
files : packaged ,
id : id
} , ( error , result ) => {
cb ( error , result )
} )
} else {
tooltip ( 'Creating a new gist ...' )
gists . create ( {
description : description ,
public : true ,
files : packaged
} , ( error , result ) => {
cb ( error , result )
} )
}
}
}
} )
}
function cb ( error , data ) {
if ( error ) {
modalDialogCustom . alert ( 'Failed to manage gist: ' + error )
} else {
if ( data . html _url ) {
modalDialogCustom . confirm ( null , ` The gist is at ${ data . html _url } . Would you like to open it in a new window? ` , ( ) => {
window . open ( data . html _url , '_blank' )
} )
} else {
modalDialogCustom . alert ( data . message + ' ' + data . documentation _url + ' ' + JSON . stringify ( data . errors , null , '\t' ) )
}
}
}
// ------------------ copy files --------------
function copyFiles ( ) {
modalDialogCustom . prompt ( null , 'To which other remix-ide instance do you want to copy over all files?' , 'https://remix.ethereum.org' , ( target ) => {
doCopy ( target )
} )
function doCopy ( target ) {
// package only files from the browser storage.
packageFiles ( self . _deps . fileProviders [ 'browser' ] , ( error , packaged ) => {
if ( error ) {
console . log ( error )
} else {
$ ( '<iframe/>' , {
src : target ,
style : 'display:none;' ,
load : function ( ) { this . contentWindow . postMessage ( [ 'loadFiles' , packaged ] , '*' ) }
} ) . appendTo ( 'body' )
}
} )
}
}
}
get profile ( ) {
@ -314,24 +153,3 @@ module.exports = class Filepanel extends ApiFactory {
}
}
// return all the files, except the temporary/readonly ones..
function packageFiles ( filesProvider , callback ) {
var ret = { }
filesProvider . resolveDirectory ( filesProvider . type , ( error , files ) => {
if ( error ) callback ( error )
else {
async . eachSeries ( Object . keys ( files ) , ( path , cb ) => {
filesProvider . get ( path , ( error , content ) => {
if ( error ) cb ( error )
else {
ret [ path ] = { content }
cb ( )
}
} )
} , ( error ) => {
callback ( error , ret )
} )
}
} )
}