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
3396f0ac
Unverified
Commit
3396f0ac
authored
Feb 28, 2018
by
yann300
Committed by
GitHub
Feb 28, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1120 from ethereum/pluginAPISetup
[Plugins] store Config file
parents
359c4d2e
bc11663d
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
283 additions
and
2 deletions
+283
-2
app.js
src/app.js
+16
-1
browser-files-tree.js
src/app/files/browser-files-tree.js
+133
-0
fileManager.js
src/app/files/fileManager.js
+2
-0
file-panel.js
src/app/panels/file-panel.js
+7
-0
config.js
src/config.js
+1
-0
pluginManager.js
src/pluginManager.js
+45
-1
index.html
test-browser/plugin/index.html
+46
-0
remix.js
test-browser/plugin/remix.js
+32
-0
sharedFolderExplorer.js
test-browser/tests/sharedFolderExplorer.js
+1
-0
No files found.
src/app.js
View file @
3396f0ac
...
...
@@ -17,6 +17,7 @@ var GistHandler = require('./lib/gist-handler')
var
helper
=
require
(
'./lib/helper'
)
var
Storage
=
remixLib
.
Storage
var
Browserfiles
=
require
(
'./app/files/browser-files'
)
var
BrowserfilesTree
=
require
(
'./app/files/browser-files-tree'
)
var
chromeCloudStorageSync
=
require
(
'./app/files/chromeCloudStorageSync'
)
var
SharedFolder
=
require
(
'./app/files/shared-folder'
)
var
Config
=
require
(
'./config'
)
...
...
@@ -111,11 +112,14 @@ class App {
var
self
=
this
self
.
_api
=
{}
var
fileStorage
=
new
Storage
(
'sol:'
)
var
configStorage
=
new
Storage
(
'config:'
)
self
.
_api
.
config
=
new
Config
(
fileStorage
)
executionContext
.
init
(
self
.
_api
.
config
)
executionContext
.
listenOnLastBlock
()
self
.
_api
.
filesProviders
=
{}
self
.
_api
.
filesProviders
[
'browser'
]
=
new
Browserfiles
(
fileStorage
)
self
.
_api
.
filesProviders
[
'config'
]
=
new
BrowserfilesTree
(
'config'
,
configStorage
)
self
.
_api
.
filesProviders
[
'config'
].
init
()
var
remixd
=
new
Remixd
()
remixd
.
event
.
register
(
'system'
,
(
message
)
=>
{
if
(
message
.
error
)
toolTip
(
message
.
error
)
...
...
@@ -204,7 +208,7 @@ function run () {
var
self
=
this
if
(
window
.
location
.
hostname
===
'yann300.github.io'
)
{
modalDialogCustom
.
alert
(
`This UNSTABLE ALPHA branch of Remix has been moved to http://ethereum.github.io/remix-live-alpha.`
)
modalDialogCustom
.
alert
(
'This UNSTABLE ALPHA branch of Remix has been moved to http://ethereum.github.io/remix-live-alpha.'
)
}
else
if
(
window
.
location
.
hostname
===
'ethereum.github.io'
&&
window
.
location
.
pathname
.
indexOf
(
'/remix-live-alpha'
)
===
0
)
{
modalDialogCustom
.
alert
(
`This instance of the Remix IDE is an UNSTABLE ALPHA branch.\n
...
...
@@ -697,6 +701,17 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
},
newAccount
:
(
pass
,
cb
)
=>
{
udapp
.
newAccount
(
pass
,
cb
)
},
setConfig
:
(
mod
,
path
,
content
,
cb
)
=>
{
self
.
_api
.
filesProviders
[
'config'
].
set
(
mod
+
'/'
+
path
,
content
)
cb
()
},
getConfig
:
(
mod
,
path
,
cb
)
=>
{
cb
(
null
,
self
.
_api
.
filesProviders
[
'config'
].
get
(
mod
+
'/'
+
path
))
},
removeConfig
:
(
mod
,
path
,
cb
)
=>
{
cb
(
null
,
self
.
_api
.
filesProviders
[
'config'
].
remove
(
mod
+
'/'
+
path
))
if
(
cb
)
cb
()
}
}
var
rhpEvents
=
{
...
...
src/app/files/browser-files-tree.js
0 → 100644
View file @
3396f0ac
'use strict'
var
EventManager
=
require
(
'remix-lib'
).
EventManager
function
FilesTree
(
name
,
storage
)
{
var
self
=
this
var
event
=
new
EventManager
()
this
.
event
=
event
this
.
type
=
name
this
.
structFile
=
'.'
+
name
+
'.tree'
this
.
tree
=
{}
this
.
exists
=
function
(
path
,
cb
)
{
cb
(
null
,
this
.
_exists
(
path
))
}
function
updateRefs
(
path
,
type
)
{
var
split
=
path
.
split
(
'/'
)
// this should be unprefixed path
var
crawlpath
=
self
.
tree
var
intermediatePath
=
''
split
.
forEach
((
pathPart
,
index
)
=>
{
intermediatePath
+=
pathPart
if
(
!
crawlpath
[
pathPart
])
crawlpath
[
intermediatePath
]
=
{}
if
(
index
<
split
.
length
-
1
)
{
crawlpath
=
crawlpath
[
intermediatePath
]
intermediatePath
+=
'/'
}
else
if
(
type
===
'add'
)
{
crawlpath
[
intermediatePath
]
=
path
}
else
if
(
type
===
'remove'
&&
crawlpath
[
intermediatePath
])
{
delete
crawlpath
[
intermediatePath
]
}
})
storage
.
set
(
self
.
structFile
,
JSON
.
stringify
(
self
.
tree
))
}
this
.
_exists
=
function
(
path
)
{
var
unprefixedpath
=
this
.
removePrefix
(
path
)
return
storage
.
exists
(
unprefixedpath
)
}
this
.
init
=
function
(
cb
)
{
var
tree
=
storage
.
get
(
this
.
structFile
)
this
.
tree
=
tree
?
JSON
.
parse
(
tree
)
:
{}
if
(
cb
)
cb
()
}
this
.
get
=
function
(
path
,
cb
)
{
var
unprefixedpath
=
this
.
removePrefix
(
path
)
var
content
=
storage
.
get
(
unprefixedpath
)
if
(
cb
)
{
cb
(
null
,
content
)
}
return
content
}
this
.
set
=
function
(
path
,
content
)
{
var
unprefixedpath
=
this
.
removePrefix
(
path
)
updateRefs
(
unprefixedpath
,
'add'
)
var
exists
=
storage
.
exists
(
unprefixedpath
)
if
(
!
storage
.
set
(
unprefixedpath
,
content
))
{
return
false
}
if
(
!
exists
)
{
event
.
trigger
(
'fileAdded'
,
[
this
.
type
+
'/'
+
unprefixedpath
,
false
])
}
else
{
event
.
trigger
(
'fileChanged'
,
[
this
.
type
+
'/'
+
unprefixedpath
])
}
return
true
}
this
.
addReadOnly
=
function
(
path
,
content
)
{
return
this
.
set
(
path
,
content
)
}
this
.
isReadOnly
=
function
(
path
)
{
return
false
}
this
.
remove
=
function
(
path
)
{
var
unprefixedpath
=
this
.
removePrefix
(
path
)
updateRefs
(
unprefixedpath
,
'remove'
)
if
(
!
this
.
_exists
(
unprefixedpath
))
{
return
false
}
if
(
!
storage
.
remove
(
unprefixedpath
))
{
return
false
}
event
.
trigger
(
'fileRemoved'
,
[
this
.
type
+
'/'
+
unprefixedpath
])
return
true
}
this
.
rename
=
function
(
oldPath
,
newPath
,
isFolder
)
{
var
unprefixedoldPath
=
this
.
removePrefix
(
oldPath
)
var
unprefixednewPath
=
this
.
removePrefix
(
newPath
)
updateRefs
(
unprefixedoldPath
,
'remove'
)
updateRefs
(
unprefixednewPath
,
'add'
)
if
(
storage
.
exists
(
unprefixedoldPath
))
{
if
(
!
storage
.
rename
(
unprefixedoldPath
,
unprefixednewPath
))
{
return
false
}
event
.
trigger
(
'fileRenamed'
,
[
this
.
type
+
'/'
+
unprefixedoldPath
,
this
.
type
+
'/'
+
unprefixednewPath
,
isFolder
])
return
true
}
return
false
}
this
.
resolveDirectory
=
function
(
path
,
callback
)
{
var
self
=
this
if
(
path
[
0
]
===
'/'
)
path
=
path
.
substring
(
1
)
if
(
!
path
)
return
callback
(
null
,
{
[
self
.
type
]:
{
}
})
var
tree
=
{}
path
=
self
.
removePrefix
(
path
)
var
split
=
path
.
split
(
'/'
)
// this should be unprefixed path
var
crawlpath
=
self
.
tree
split
.
forEach
((
pathPart
,
index
)
=>
{
if
(
crawlpath
[
pathPart
])
crawlpath
=
crawlpath
[
pathPart
]
})
for
(
var
item
in
crawlpath
)
{
tree
[
item
]
=
{
isDirectory
:
typeof
crawlpath
[
item
]
!==
'string'
}
}
callback
(
null
,
tree
)
}
this
.
removePrefix
=
function
(
path
)
{
path
=
path
.
indexOf
(
this
.
type
)
===
0
?
path
.
replace
(
this
.
type
,
''
)
:
path
if
(
path
[
0
]
===
'/'
)
return
path
.
substring
(
1
)
return
path
}
}
module
.
exports
=
FilesTree
src/app/files/fileManager.js
View file @
3396f0ac
...
...
@@ -24,8 +24,10 @@ class FileManager {
this
.
opt
=
opt
this
.
opt
.
filesProviders
[
'browser'
].
event
.
register
(
'fileRenamed'
,
(
oldName
,
newName
,
isFolder
)
=>
{
this
.
fileRenamedEvent
(
oldName
,
newName
,
isFolder
)
})
this
.
opt
.
filesProviders
[
'localhost'
].
event
.
register
(
'fileRenamed'
,
(
oldName
,
newName
,
isFolder
)
=>
{
this
.
fileRenamedEvent
(
oldName
,
newName
,
isFolder
)
})
this
.
opt
.
filesProviders
[
'config'
].
event
.
register
(
'fileRenamed'
,
(
oldName
,
newName
,
isFolder
)
=>
{
this
.
fileRenamedEvent
(
oldName
,
newName
,
isFolder
)
})
this
.
opt
.
filesProviders
[
'browser'
].
event
.
register
(
'fileRemoved'
,
(
path
)
=>
{
this
.
fileRemovedEvent
(
path
)
})
this
.
opt
.
filesProviders
[
'localhost'
].
event
.
register
(
'fileRemoved'
,
(
path
)
=>
{
this
.
fileRemovedEvent
(
path
)
})
this
.
opt
.
filesProviders
[
'config'
].
event
.
register
(
'fileRemoved'
,
(
path
)
=>
{
this
.
fileRemovedEvent
(
path
)
})
// tabs
var
$filesEl
=
$
(
'#files'
)
...
...
src/app/panels/file-panel.js
View file @
3396f0ac
...
...
@@ -45,6 +45,7 @@ function filepanel (appAPI, filesProvider) {
var
swarmExplorer
=
new
FileExplorer
(
appAPI
,
filesProvider
[
'swarm'
])
var
githubExplorer
=
new
FileExplorer
(
appAPI
,
filesProvider
[
'github'
])
var
gistExplorer
=
new
FileExplorer
(
appAPI
,
filesProvider
[
'gist'
])
var
configExplorer
=
new
FileExplorer
(
appAPI
,
filesProvider
[
'config'
])
var
dragbar
=
yo
`<div onmousedown=
${
mousedown
}
class=
${
css
.
dragbar
}
></div>`
...
...
@@ -91,6 +92,7 @@ function filepanel (appAPI, filesProvider) {
</div>
<div class=
${
css
.
treeviews
}
>
<div class=
${
css
.
treeview
}
>
${
fileExplorer
.
init
()}
</div>
<div class="configexplorer
${
css
.
treeview
}
">
${
configExplorer
.
init
()}
</div>
<div class="filesystemexplorer
${
css
.
treeview
}
">
${
fileSystemExplorer
.
init
()}
</div>
<div class="swarmexplorer
${
css
.
treeview
}
">
${
swarmExplorer
.
init
()}
</div>
<div class="githubexplorer
${
css
.
treeview
}
">
${
githubExplorer
.
init
()}
</div>
...
...
@@ -106,6 +108,7 @@ function filepanel (appAPI, filesProvider) {
self
.
event
=
event
var
element
=
template
()
fileExplorer
.
ensureRoot
()
configExplorer
.
ensureRoot
()
var
websocketconn
=
element
.
querySelector
(
'.websocketconn'
)
filesProvider
[
'localhost'
].
remixd
.
event
.
register
(
'connecting'
,
(
event
)
=>
{
websocketconn
.
style
.
color
=
styles
.
colors
.
yellow
...
...
@@ -134,6 +137,10 @@ function filepanel (appAPI, filesProvider) {
appAPI
.
switchFile
(
path
)
})
configExplorer
.
events
.
register
(
'focus'
,
function
(
path
)
{
appAPI
.
switchFile
(
path
)
})
fileSystemExplorer
.
events
.
register
(
'focus'
,
function
(
path
)
{
appAPI
.
switchFile
(
path
)
})
...
...
src/config.js
View file @
3396f0ac
...
...
@@ -35,6 +35,7 @@ function Config (storage) {
this
.
ensureStorageUpdated
=
function
(
key
)
{
if
(
key
===
'currentFile'
)
{
if
(
this
.
items
[
key
]
&&
this
.
items
[
key
]
!==
''
&&
this
.
items
[
key
].
indexOf
(
'config/'
)
!==
0
&&
this
.
items
[
key
].
indexOf
(
'browser/'
)
!==
0
&&
this
.
items
[
key
].
indexOf
(
'localhost/'
)
!==
0
&&
this
.
items
[
key
].
indexOf
(
'swarm/'
)
!==
0
&&
...
...
src/pluginManager.js
View file @
3396f0ac
...
...
@@ -7,12 +7,35 @@
* - compilationData (that is triggered just after a focus - and send the current compilation data or null)
* - compilationFinished (that is only sent to the plugin that has focus)
*
* @param {String} txHash - hash of the transaction
* Plugin can emit messages and receive response.
*
* CONFIG:
* - getConfig(filename). The data to send should be formatted like:
* {
* type: 'getConfig',
* arguments: ['filename.ext'],
* id: <requestid>
* }
* the plugin will reveice a response like:
* {
* type: 'getConfig',
* id: <requestid>
* error,
* result
* }
* same apply for the other call
* - setConfig(filename, content)
* - removeConfig
*
* See index.html and remix.js in test-browser folder for sample
*
*/
class
PluginManager
{
constructor
(
api
,
events
)
{
var
self
=
this
this
.
plugins
=
{}
this
.
inFocus
var
allowedapi
=
{
'setConfig'
:
1
,
'getConfig'
:
1
,
'removeConfig'
:
1
}
events
.
compiler
.
register
(
'compilationFinished'
,
(
success
,
data
,
source
)
=>
{
if
(
this
.
inFocus
)
{
// trigger to the current focus
...
...
@@ -46,6 +69,27 @@ class PluginManager {
}))
}
})
window
.
addEventListener
(
'message'
,
(
event
)
=>
{
function
response
(
type
,
callid
,
error
,
result
)
{
self
.
post
(
self
.
inFocus
,
JSON
.
stringify
({
id
:
callid
,
type
:
type
,
error
:
error
,
result
:
result
}))
}
if
(
event
.
type
===
'message'
&&
this
.
inFocus
&&
this
.
plugins
[
this
.
inFocus
]
&&
this
.
plugins
[
this
.
inFocus
].
origin
===
event
.
origin
)
{
var
data
=
JSON
.
parse
(
event
.
data
)
data
.
arguments
.
unshift
(
this
.
inFocus
)
if
(
allowedapi
[
data
.
type
])
{
data
.
arguments
.
push
((
error
,
result
)
=>
{
response
(
data
.
type
,
data
.
id
,
error
,
result
)
})
api
[
data
.
type
].
apply
({},
data
.
arguments
)
}
}
},
false
)
}
register
(
desc
,
content
)
{
this
.
plugins
[
desc
.
title
]
=
{
content
,
origin
:
desc
.
url
}
...
...
test-browser/plugin/index.html
0 → 100644
View file @
3396f0ac
<!DOCTYPE html>
<html>
<head>
<meta
charset=
"utf-8"
>
<!--
The MIT License (MIT)
Copyright (c) 2014, 2015, the individual contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<meta
http-equiv=
"X-UA-Compatible"
content=
"chrome=1"
>
<title></title>
<link
rel=
"stylesheet"
href=
"assets/css/pygment_trac.css"
>
<link
rel=
"stylesheet"
href=
"assets/css/font-awesome.min.css"
>
<script
type=
"text/javascript"
src=
"remix.js"
></script>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1, user-scalable=no"
>
</head>
<body>
<div>
PLUGIN
</div>
<input
type=
"text"
id=
"filename"
></input>
<input
type=
"text"
id=
"valuetosend"
></input>
<br>
<input
type=
"button"
id=
"testmessageadd"
>
add config
</input>
<br>
<input
type=
"button"
id=
"testmessageremove"
>
remove config
</input>
<br>
<input
type=
"button"
id=
"testmessagerget"
>
get config
</input>
<br>
<br>
<div
id=
'compilationdata'
></div>
</body>
</html>
test-browser/plugin/remix.js
0 → 100644
View file @
3396f0ac
function
receiveMessage
(
event
)
{
console
.
log
(
'receiveMessage'
,
event
.
data
,
event
.
source
,
event
.
origin
)
document
.
getElementById
(
'compilationdata'
).
innerHTML
+=
event
.
data
+
'<br>'
}
window
.
addEventListener
(
'message'
,
receiveMessage
,
false
)
window
.
onload
=
function
()
{
document
.
querySelector
(
'input#testmessageadd'
).
addEventListener
(
'click'
,
function
()
{
window
.
parent
.
postMessage
(
JSON
.
stringify
({
type
:
'setConfig'
,
arguments
:
[
document
.
getElementById
(
'filename'
).
value
,
document
.
getElementById
(
'valuetosend'
).
value
],
id
:
34
}),
'http://127.0.0.1:8080'
)
})
document
.
querySelector
(
'input#testmessageremove'
).
addEventListener
(
'click'
,
function
()
{
window
.
parent
.
postMessage
(
JSON
.
stringify
({
type
:
'removeConfig'
,
arguments
:
[
document
.
getElementById
(
'filename'
).
value
],
id
:
35
}),
'http://127.0.0.1:8080'
)
})
document
.
querySelector
(
'input#testmessagerget'
).
addEventListener
(
'click'
,
function
()
{
window
.
parent
.
postMessage
(
JSON
.
stringify
({
type
:
'getConfig'
,
arguments
:
[
document
.
getElementById
(
'filename'
).
value
],
id
:
36
}),
'http://127.0.0.1:8080'
)
})
}
test-browser/tests/sharedFolderExplorer.js
View file @
3396f0ac
...
...
@@ -71,6 +71,7 @@ function runTests (browser, testData) {
.
waitForElementVisible
(
'[data-path="localhost/contract1.sol"]'
)
.
assert
.
containsText
(
'[data-path="localhost/contract1.sol"]'
,
'contract1.sol'
)
.
assert
.
containsText
(
'[data-path="localhost/contract2.sol"]'
,
'contract2.sol'
)
.
waitForElementVisible
(
'[data-path="localhost/folder1/contract1.sol"]'
)
.
assert
.
containsText
(
'[data-path="localhost/folder1/contract1.sol"]'
,
'contract1.sol'
)
.
assert
.
containsText
(
'[data-path="localhost/folder1/contract2.sol"]'
,
'contract2.sol'
)
// load and test sub folder
.
click
(
'[data-path="localhost/folder1/contract2.sol"]'
)
...
...
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