Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
B
baas-ide
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
guxukai
baas-ide
Commits
d7152cd6
Unverified
Commit
d7152cd6
authored
Sep 30, 2019
by
yann300
Committed by
GitHub
Sep 30, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2374 from ethereum/kuku
FE refactoring: added Discard changes for external folder. removed readonly.
parents
b4ba04d6
33d15900
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
136 additions
and
72 deletions
+136
-72
compiler-imports.js
src/app/compiler/compiler-imports.js
+9
-1
file-explorer.js
src/app/files/file-explorer.js
+57
-40
fileManager.js
src/app/files/fileManager.js
+5
-1
fileProvider.js
src/app/files/fileProvider.js
+56
-21
remixDProvider.js
src/app/files/remixDProvider.js
+4
-4
compile-tab.js
src/app/tabs/compile-tab.js
+2
-2
compileTab.js
src/app/tabs/compileTab/compileTab.js
+1
-1
contextMenu.js
src/app/ui/contextMenu.js
+1
-1
landing-page.js
src/app/ui/landing-page/landing-page.js
+1
-1
No files found.
src/app/compiler/compiler-imports.js
View file @
d7152cd6
...
...
@@ -110,10 +110,18 @@ module.exports = class CompilerImports extends Plugin {
})
}
import
(
url
,
loadingCb
,
cb
)
{
import
(
url
,
force
,
loadingCb
,
cb
)
{
if
(
typeof
force
!==
'boolean'
)
{
let
temp
=
loadingCb
loadingCb
=
force
cb
=
temp
force
=
false
}
if
(
!
loadingCb
)
loadingCb
=
()
=>
{}
if
(
!
cb
)
cb
=
()
=>
{}
var
self
=
this
if
(
force
)
delete
this
.
previouslyHandled
[
url
]
var
imported
=
this
.
previouslyHandled
[
url
]
if
(
imported
)
{
return
cb
(
null
,
imported
.
content
,
imported
.
cleanUrl
,
imported
.
type
,
url
)
...
...
src/app/files/file-explorer.js
View file @
d7152cd6
...
...
@@ -190,21 +190,56 @@ function fileExplorer (localRegistry, files, menuItems) {
}
})
/**
* Extracts first two folders as a subpath from the path.
**/
function
extractExternalFolder
(
path
)
{
const
firstSlIndex
=
path
.
indexOf
(
'/'
,
1
)
if
(
firstSlIndex
===
-
1
)
return
''
const
secondSlIndex
=
path
.
indexOf
(
'/'
,
firstSlIndex
+
1
)
if
(
secondSlIndex
===
-
1
)
return
''
return
path
.
substring
(
0
,
secondSlIndex
)
}
self
.
treeView
.
event
.
register
(
'nodeRightClick'
,
function
(
key
,
data
,
label
,
event
)
{
if
(
self
.
files
.
readonly
)
return
if
(
key
===
self
.
files
.
type
)
return
MENU_HANDLE
&&
MENU_HANDLE
.
hide
(
null
,
true
)
MENU_HANDLE
=
contextMenu
(
event
,
{
'Rename'
:
()
=>
{
if
(
self
.
files
.
readonly
)
{
return
tooltip
(
'cannot rename folder. '
+
self
.
files
.
type
+
' is a read only explorer'
)
}
let
actions
=
{}
const
provider
=
self
.
_deps
.
fileManager
.
fileProviderOf
(
key
)
if
(
provider
.
isExternalFolder
(
key
))
{
actions
[
'Discard changes'
]
=
()
=>
{
modalDialogCustom
.
confirm
(
'Discard changes'
,
'Are you sure you want to discard all your changes?'
,
()
=>
{
files
.
discardChanges
(
key
)
},
()
=>
{}
)
}
}
else
{
const
folderPath
=
extractExternalFolder
(
key
)
if
(
folderPath
===
'browser/gists'
)
{
actions
[
'Push changes to gist'
]
=
()
=>
{
const
id
=
key
.
substr
(
key
.
lastIndexOf
(
'/'
)
+
1
,
key
.
length
-
1
)
modalDialogCustom
.
confirm
(
'Push back to Gist'
,
'Are you sure you want to push all your changes back to Gist?'
,
()
=>
{
self
.
toGist
(
id
)
},
()
=>
{}
)
}
}
actions
[
'Rename'
]
=
()
=>
{
if
(
self
.
files
.
isReadOnly
(
key
))
{
return
tooltip
(
'cannot rename folder. '
+
self
.
files
.
type
+
' is a read only explorer'
)
}
var
name
=
label
.
querySelector
(
'span[data-path="'
+
key
+
'"]'
)
if
(
name
)
editModeOn
(
name
)
},
'Delete'
:
()
=>
{
if
(
self
.
files
.
readonly
)
{
return
tooltip
(
'cannot delete folder. '
+
self
.
files
.
type
+
' is a read only explorer'
)
}
modalDialogCustom
.
confirm
(
'Confirm to delete a folder'
,
'Are you sure you want to delete this folder?'
,
()
=>
{
files
.
remove
(
key
)
},
()
=>
{})
}
})
}
actions
[
'Delete'
]
=
()
=>
{
if
(
self
.
files
.
isReadOnly
(
key
))
{
return
tooltip
(
'cannot delete folder. '
+
self
.
files
.
type
+
' is a read only explorer'
)
}
modalDialogCustom
.
confirm
(
'Confirm to delete a folder'
,
'Are you sure you want to delete this folder?'
,
()
=>
{
files
.
remove
(
key
)
},
()
=>
{})
}
MENU_HANDLE
=
contextMenu
(
event
,
actions
)
})
self
.
treeView
.
event
.
register
(
'leafRightClick'
,
function
(
key
,
data
,
label
,
event
)
{
...
...
@@ -212,29 +247,20 @@ function fileExplorer (localRegistry, files, menuItems) {
MENU_HANDLE
&&
MENU_HANDLE
.
hide
(
null
,
true
)
let
actions
=
{}
const
provider
=
self
.
_deps
.
fileManager
.
fileProviderOf
(
key
)
if
(
!
provider
.
is
ReadOnly
(
key
))
{
if
(
!
provider
.
is
ExternalFolder
(
key
))
{
actions
[
'Rename'
]
=
()
=>
{
if
(
self
.
files
.
readonly
)
{
return
tooltip
(
'cannot rename file. '
+
self
.
files
.
type
+
' is a read only explorer'
)
}
if
(
self
.
files
.
isReadOnly
(
key
)
)
{
return
tooltip
(
'cannot rename file. '
+
self
.
files
.
type
+
' is a read only explorer'
)
}
var
name
=
label
.
querySelector
(
'span[data-path="'
+
key
+
'"]'
)
if
(
name
)
editModeOn
(
name
)
}
actions
[
'Delete'
]
=
()
=>
{
if
(
self
.
files
.
readonly
)
{
return
tooltip
(
'cannot delete file. '
+
self
.
files
.
type
+
' is a read only explorer'
)
}
if
(
self
.
files
.
isReadOnly
(
key
)
)
{
return
tooltip
(
'cannot delete file. '
+
self
.
files
.
type
+
' is a read only explorer'
)
}
modalDialogCustom
.
confirm
(
'Delete a file'
,
'Are you sure you want to delete this file?'
,
()
=>
{
files
.
remove
(
key
)
},
()
=>
{}
)
}
}
else
{
actions
[
'Delete from remix'
]
=
()
=>
{
modalDialogCustom
.
confirm
(
'Delete from remix'
,
'Are you sure you want to delete this file from remix?'
,
()
=>
{
files
.
remove
(
key
)
},
()
=>
{}
)
}
}
MENU_HANDLE
=
contextMenu
(
event
,
actions
)
})
...
...
@@ -403,6 +429,7 @@ fileExplorer.prototype.toGist = function (id) {
let
proccedResult
=
function
(
error
,
data
)
{
if
(
error
)
{
modalDialogCustom
.
alert
(
'Failed to manage gist: '
+
error
)
console
.
log
(
'Failed to manage gist: '
+
error
)
}
else
{
if
(
data
.
html_url
)
{
modalDialogCustom
.
confirm
(
'Gist is ready'
,
`The gist is at
${
data
.
html_url
}
. Would you like to open it in a new window?`
,
()
=>
{
...
...
@@ -414,7 +441,7 @@ fileExplorer.prototype.toGist = function (id) {
}
}
this
.
packageFiles
(
this
.
files
,
(
error
,
packaged
)
=>
{
this
.
packageFiles
(
this
.
files
,
'browser/gists/'
+
id
,
(
error
,
packaged
)
=>
{
if
(
error
)
{
console
.
log
(
error
)
modalDialogCustom
.
alert
(
'Failed to create gist: '
+
error
)
...
...
@@ -445,7 +472,9 @@ fileExplorer.prototype.toGist = function (id) {
}),
this
.
files
.
origGistFiles
)
// adding new files
updatedFileList
.
forEach
((
file
)
=>
{
allItems
[
file
]
=
packaged
[
file
]
const
_items
=
file
.
split
(
'/'
)
const
_fileName
=
_items
[
_items
.
length
-
1
]
allItems
[
_fileName
]
=
packaged
[
file
]
})
tooltip
(
'Saving gist ('
+
id
+
') ...'
)
...
...
@@ -479,21 +508,19 @@ fileExplorer.prototype.toGist = function (id) {
}
// return all the files, except the temporary/readonly ones..
fileExplorer
.
prototype
.
packageFiles
=
function
(
filesProvider
,
callback
)
{
fileExplorer
.
prototype
.
packageFiles
=
function
(
filesProvider
,
directory
,
callback
)
{
var
ret
=
{}
filesProvider
.
resolveDirectory
(
'/'
,
(
error
,
files
)
=>
{
filesProvider
.
resolveDirectory
(
directory
,
(
error
,
files
)
=>
{
if
(
error
)
callback
(
error
)
else
{
async
.
eachSeries
(
Object
.
keys
(
files
),
(
path
,
cb
)
=>
{
filesProvider
.
get
(
path
,
(
error
,
content
)
=>
{
if
(
error
)
return
cb
(
error
)
if
(
/^
\s
+$/
.
test
(
content
)
||
!
content
.
length
)
{
content
=
'// this line is added to create a gist. Empty file is not allowed.'
}
if
(
error
)
cb
(
error
)
else
{
ret
[
path
]
=
{
content
}
cb
()
}
ret
[
path
]
=
{
content
}
cb
()
})
},
(
error
)
=>
{
callback
(
error
,
ret
)
...
...
@@ -515,7 +542,7 @@ fileExplorer.prototype.copyFiles = function () {
)
function
doCopy
(
target
)
{
// package only files from the browser storage.
self
.
packageFiles
(
self
.
files
,
(
error
,
packaged
)
=>
{
self
.
packageFiles
(
self
.
files
,
'/'
,
(
error
,
packaged
)
=>
{
if
(
error
)
{
console
.
log
(
error
)
}
else
{
...
...
@@ -532,16 +559,6 @@ fileExplorer.prototype.copyFiles = function () {
}
}
// ------------------ gist publish --------------
fileExplorer
.
prototype
.
updateGist
=
function
()
{
const
gistId
=
this
.
files
.
id
if
(
!
gistId
)
{
tooltip
(
'no gist content is currently loaded.'
)
}
else
{
this
.
toGist
(
gistId
)
}
}
fileExplorer
.
prototype
.
createNewFile
=
function
()
{
let
self
=
this
modalDialogCustom
.
prompt
(
'Create new file'
,
'File Path (Untitled.sol, Folder1/Untitled.sol)'
,
'Untitled.sol'
,
(
input
)
=>
{
...
...
src/app/files/fileManager.js
View file @
d7152cd6
...
...
@@ -49,7 +49,7 @@ class FileManager extends Plugin {
localhostExplorer
:
this
.
_components
.
registry
.
get
(
'fileproviders/localhost'
).
api
,
filesProviders
:
this
.
_components
.
registry
.
get
(
'fileproviders'
).
api
}
this
.
_deps
.
browserExplorer
.
event
.
register
(
'fileChanged'
,
(
path
)
=>
{
this
.
fileChangedEvent
(
path
)
})
this
.
_deps
.
browserExplorer
.
event
.
register
(
'fileRenamed'
,
(
oldName
,
newName
,
isFolder
)
=>
{
this
.
fileRenamedEvent
(
oldName
,
newName
,
isFolder
)
})
this
.
_deps
.
localhostExplorer
.
event
.
register
(
'fileRenamed'
,
(
oldName
,
newName
,
isFolder
)
=>
{
this
.
fileRenamedEvent
(
oldName
,
newName
,
isFolder
)
})
this
.
_deps
.
browserExplorer
.
event
.
register
(
'fileRemoved'
,
(
path
)
=>
{
this
.
fileRemovedEvent
(
path
)
})
...
...
@@ -58,6 +58,10 @@ class FileManager extends Plugin {
this
.
_deps
.
localhostExplorer
.
event
.
register
(
'closed'
,
(
event
)
=>
{
this
.
removeTabsOf
(
this
.
_deps
.
localhostExplorer
)
})
}
fileChangedEvent
(
path
)
{
this
.
syncEditor
(
path
)
}
fileRenamedEvent
(
oldName
,
newName
,
isFolder
)
{
if
(
!
isFolder
)
{
this
.
_deps
.
config
.
set
(
'currentFile'
,
''
)
...
...
src/app/files/fileProvider.js
View file @
d7152cd6
'use strict'
var
EventManager
=
require
(
'../../lib/events'
)
const
CompilerImport
=
require
(
'../compiler/compiler-imports'
)
const
EventManager
=
require
(
'../../lib/events'
)
const
modalDialogCustom
=
require
(
'../ui/modal-dialog-custom'
)
const
tooltip
=
require
(
'../ui/tooltip'
)
const
remixLib
=
require
(
'remix-lib'
)
const
Storage
=
remixLib
.
Storage
class
FileProvider
{
constructor
(
name
)
{
this
.
event
=
new
EventManager
()
this
.
type
=
name
this
.
normalizedNames
=
{}
// contains the raw url associated with the displayed path
this
.
readonlyItems
=
[
'browser'
]
this
.
providerExternalsStorage
=
new
Storage
(
'providerExternals:'
)
this
.
externalFolders
=
[
this
.
type
+
'/swarm'
,
this
.
type
+
'/ipfs'
,
this
.
type
+
'/github'
,
this
.
type
+
'/gist'
,
this
.
type
+
'/https'
]
}
addNormalizedName
(
path
,
url
)
{
this
.
providerExternalsStorage
.
set
(
this
.
type
+
'/'
+
path
,
url
)
}
removeNormalizedName
(
path
)
{
this
.
providerExternalsStorage
.
remove
(
path
)
}
normalizedNameExists
(
path
)
{
return
this
.
providerExternalsStorage
.
exists
(
path
)
}
getNormalizedName
(
path
)
{
return
this
.
providerExternalsStorage
.
get
(
path
)
}
isExternalFolder
(
path
)
{
return
this
.
externalFolders
.
includes
(
path
)
}
discardChanges
(
path
)
{
this
.
remove
(
path
)
const
compilerImport
=
new
CompilerImport
()
this
.
providerExternalsStorage
.
keys
().
map
(
value
=>
{
if
(
value
.
indexOf
(
path
)
===
0
)
{
compilerImport
.
import
(
this
.
getNormalizedName
(
value
),
true
,
(
loadingMsg
)
=>
{
tooltip
(
loadingMsg
)
},
(
error
,
content
,
cleanUrl
,
type
,
url
)
=>
{
if
(
error
)
{
modalDialogCustom
.
alert
(
error
)
}
else
{
this
.
addExternal
(
type
+
'/'
+
cleanUrl
,
content
,
url
)
}
}
)
}
})
}
exists
(
path
,
cb
)
{
...
...
@@ -25,7 +71,7 @@ class FileProvider {
get
(
path
,
cb
)
{
cb
=
cb
||
function
()
{}
if
(
this
.
normalizedName
s
[
path
])
path
=
this
.
normalizedNames
[
path
]
// ensure we actually use the normalized path from here
if
(
this
.
normalizedName
Exists
(
path
))
path
=
this
.
getNormalizedName
(
path
)
// ensure we actually use the normalized path from here
var
unprefixedpath
=
this
.
removePrefix
(
path
)
var
exists
=
window
.
remixFileSystem
.
existsSync
(
unprefixedpath
)
if
(
!
exists
)
return
cb
(
null
,
null
)
...
...
@@ -36,12 +82,10 @@ class FileProvider {
set
(
path
,
content
,
cb
)
{
cb
=
cb
||
function
()
{}
if
(
this
.
isReadOnly
(
path
))
{
cb
(
new
Error
(
'It is not possible to modify a readonly item'
))
return
false
}
var
unprefixedpath
=
this
.
removePrefix
(
path
)
var
exists
=
window
.
remixFileSystem
.
existsSync
(
unprefixedpath
)
if
(
exists
&&
window
.
remixFileSystem
.
readFileSync
(
unprefixedpath
,
'utf8'
)
===
content
)
return
true
if
(
!
exists
&&
unprefixedpath
.
indexOf
(
'/'
)
!==
-
1
)
{
const
paths
=
unprefixedpath
.
split
(
'/'
)
paths
.
pop
()
// last element should the filename
...
...
@@ -70,26 +114,17 @@ class FileProvider {
return
true
}
addReadOnly
(
path
,
content
,
url
)
{
this
.
readonlyItems
.
push
(
this
.
type
+
'/'
+
path
)
if
(
!
url
)
this
.
normalizedNames
[
url
]
=
path
// this will not add a folder as readonly but keep the original url to be able to restore it later
addExternal
(
path
,
content
,
url
)
{
if
(
url
)
this
.
addNormalizedName
(
path
,
url
)
return
this
.
set
(
path
,
content
)
}
isReadOnly
(
path
)
{
return
this
.
readonlyItems
.
includes
(
path
)
}
_removeFromReadonlyList
(
path
)
{
const
indexToRemove
=
this
.
readonlyItems
.
indexOf
(
path
)
if
(
indexToRemove
!==
-
1
)
{
this
.
readonlyItems
.
splice
(
indexToRemove
,
1
)
}
return
false
}
remove
(
path
)
{
this
.
_removeFromReadonlyList
(
path
)
var
unprefixedpath
=
this
.
removePrefix
(
path
)
if
(
!
this
.
_exists
(
unprefixedpath
))
{
return
false
...
...
src/app/files/remixDProvider.js
View file @
d7152cd6
...
...
@@ -113,10 +113,6 @@ module.exports = class RemixDProvider {
return
true
}
addReadOnly
(
path
,
content
)
{
return
false
}
isReadOnly
(
path
)
{
return
this
.
_readOnlyMode
||
this
.
_readOnlyFiles
[
path
]
===
1
}
...
...
@@ -154,6 +150,10 @@ module.exports = class RemixDProvider {
return
true
}
isExternalFolder
(
path
)
{
return
false
}
removePrefix
(
path
)
{
path
=
path
.
indexOf
(
this
.
type
)
===
0
?
path
.
replace
(
this
.
type
,
''
)
:
path
if
(
path
[
0
]
===
'/'
)
return
path
.
substring
(
1
)
...
...
src/app/tabs/compile-tab.js
View file @
d7152cd6
...
...
@@ -313,7 +313,7 @@ class CompileTab extends ViewPlugin {
modalDialogCustom
.
alert
(
yo
`<span>Metadata published successfully.<br> <pre>
${
result
}
</pre> </span>`
)
}
},
(
item
)
=>
{
// triggered each time there's a new verified publish (means hash correspond)
this
.
fileProvider
.
add
ReadOnly
(
'swarm/'
+
item
.
hash
,
item
.
content
)
this
.
fileProvider
.
add
External
(
'swarm/'
+
item
.
hash
,
item
.
content
)
})
}
else
{
publishOnIpfs
(
contract
,
this
.
fileManager
,
function
(
err
,
uploaded
)
{
...
...
@@ -330,7 +330,7 @@ class CompileTab extends ViewPlugin {
modalDialogCustom
.
alert
(
yo
`<span>Metadata published successfully.<br> <pre>
${
result
}
</pre> </span>`
)
}
},
(
item
)
=>
{
// triggered each time there's a new verified publish (means hash correspond)
this
.
fileProvider
.
add
ReadOnly
(
'ipfs/'
+
item
.
hash
,
item
.
content
)
this
.
fileProvider
.
add
External
(
'ipfs/'
+
item
.
hash
,
item
.
content
)
})
}
}
...
...
src/app/tabs/compileTab/compileTab.js
View file @
d7152cd6
...
...
@@ -93,7 +93,7 @@ class CompileTab {
if
(
error
)
return
cb
(
error
)
if
(
this
.
fileProvider
)
{
this
.
fileProvider
.
add
ReadOnly
(
cleanUrl
,
content
,
url
)
this
.
fileProvider
.
add
External
(
cleanUrl
,
content
,
url
)
}
cb
(
null
,
content
)
})
...
...
src/app/ui/contextMenu.js
View file @
d7152cd6
...
...
@@ -45,7 +45,7 @@ module.exports = (event, items) => {
current
.
onclick
=
()
=>
{
hide
(
null
,
true
);
items
[
item
]()
}
return
current
})
var
container
=
yo
`<div class="
${
css
.
container
}
bg-light"><ul id='menuitems'>
${
menu
}
</ul></div>`
var
container
=
yo
`<div class="
p-1
${
css
.
container
}
bg-light"><ul id='menuitems'>
${
menu
}
</ul></div>`
container
.
style
.
left
=
event
.
pageX
+
'px'
container
.
style
.
top
=
event
.
pageY
+
'px'
container
.
style
.
display
=
'block'
...
...
src/app/ui/landing-page/landing-page.js
View file @
d7152cd6
...
...
@@ -106,7 +106,7 @@ export class LandingPage extends ViewPlugin {
if
(
error
)
{
modalDialogCustom
.
alert
(
error
)
}
else
{
fileProviders
[
'browser'
].
add
ReadOnly
(
type
+
'/'
+
cleanUrl
,
content
,
url
)
fileProviders
[
'browser'
].
add
External
(
type
+
'/'
+
cleanUrl
,
content
,
url
)
this
.
verticalIcons
.
select
(
'fileExplorers'
)
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment