diff --git a/assets/css/browser-solidity.css b/assets/css/browser-solidity.css
index 6b0c5db3ea..7c897d33e7 100644
--- a/assets/css/browser-solidity.css
+++ b/assets/css/browser-solidity.css
@@ -1,43 +1,3 @@
-.scroller {
- position: absolute;
- z-index: 999;
- text-align: center;
- cursor: pointer;
- display: none;
- padding: 0 0.9em;
- vertical-align: middle;
- background-color: rgba(255, 255, 255, 0.8);
- height: 100%;
- font-size: 1.3em;
-}
-
-.scroller i {
- line-height: 3em;
-}
-
-.scroller-right {
- right: 0;
-}
-
-.scroller-left {
- left: 0;
-}
-
-#files {
- list-style: none;
- margin: 0;
- font-size: 15px;
- height: 2.5em;
- box-sizing: border-box;
- line-height: 2em;
- padding: 0.5em 0 0;
- position: relative;
- left: 40px;
- top:0;
- min-width:3000px;
- border-bottom: 0 none;
-}
-
#files .file {
padding: 0 0.6em;
box-sizing: border-box;
@@ -51,22 +11,6 @@
color: #999;
}
-.toggleRHP {
- display: block;
- float: left;
- margin-top: 0.5em;
- padding: 0.6em;
- font-weight: bold;
- cursor: pointer;
- color: black;
-}
-
-.toggleRHP {
- float: right;
- position: absolute;
- right: 0;
-}
-
#files .file.active {
color: black;
font-weight: bold;
@@ -98,18 +42,6 @@
display: inline-block;
}
-#righthand-panel {
- position: absolute;
- top: 0;
- width: 37em;
- max-width: 80vw;
- right: 0;
- bottom: 0;
- overflow: auto;
- box-sizing: border-box;
- overflow: hidden;
-}
-
#header {
font-size: 13px;
height: 100%;
@@ -378,17 +310,6 @@
border: .2em dotted #ffbd01;
}
-#ghostbar {
- width: 1px;
- background-color: red;
- opacity: 0.5;
- position: absolute;
- cursor: col-resize;
- z-index: 9999;
- top: 0;
- bottom: 0;
-}
-
input[readonly] {
display: block;
width: 100%;
diff --git a/src/app.js b/src/app.js
index aa3338f887..53e587fbca 100644
--- a/src/app.js
+++ b/src/app.js
@@ -26,6 +26,7 @@ var ExecutionContext = require('./app/execution-context')
var Debugger = require('./app/debugger')
var StaticAnalysis = require('./app/staticanalysis/staticAnalysisView')
var FilePanel = require('./app/file-panel')
+var EditorPanel = require('./app/editor-panel')
var RighthandPanel = require('./app/righthand-panel')
var examples = require('./app/example-contracts')
@@ -43,44 +44,88 @@ var css = csjs`
position : relative;
width : 100vw;
height : 100vh;
+ overflow : hidden;
}
.centerpanel {
display : flex;
flex-direction : column;
position : absolute;
top : 0;
- left : 200px;
- right : 0;
bottom : 0;
- }
- .tabsbar {
overflow : hidden;
}
.leftpanel {
display : flex;
+ flex-direction : column;
position : absolute;
top : 0;
- left : 0;
- right : 0;
bottom : 0;
- width : 200px;
+ left : 0;
+ overflow : hidden;
}
- .dragbar2 {
- background-color : transparent;
+ .rightpanel {
+ display : flex;
+ flex-direction : column;
position : absolute;
- width : 0.5em;
- top : 3em;
+ top : 0;
+ right : 0;
bottom : 0;
- cursor : col-resize;
- z-index : 999;
- border-right : 2px solid hsla(215, 81%, 79%, .3);
+ overflow : hidden;
}
`
class App {
constructor (opts = {}) {
var self = this
+ self._api = {}
+ var fileStorage = new Storage('sol:')
+ self._api.config = new Config(fileStorage)
+ self._api.filesProviders = {}
+ self._api.filesProviders['browser'] = new Browserfiles(fileStorage)
+ self._api.filesProviders['localhost'] = new SharedFolder(new Remixd())
self._view = {}
+ self._components = {}
+ self.data = {
+ _layout: {
+ right: {
+ offset: self._api.config.get('right-offset') || 400,
+ show: true
+ }, // @TODO: adapt sizes proportionally to browser window size
+ left: {
+ offset: self._api.config.get('left-offset') || 200,
+ show: true
+ }
+ }
+ }
+ // ----------------- editor ----------------------------
+ self._components.editor = new Editor({}) // @TODO: put into editorpanel
+ // ----------------- editor panel ----------------------
+ self._components.editorpanel = new EditorPanel({
+ api: { editor: self._components.editor }
+ })
+ self._components.editorpanel.event.register('resize', direction => self._adjustLayout(direction))
+ }
+ _adjustLayout (direction, delta) {
+ var self = this
+ var layout = self.data._layout[direction]
+ if (layout) {
+ if (delta === undefined) {
+ layout.show = !layout.show
+ if (layout.show) delta = layout.offset
+ else delta = 0
+ } else {
+ self._api.config.set(`${direction}-offset`, delta)
+ layout.offset = delta
+ }
+ }
+ if (direction === 'left') {
+ self._view.leftpanel.style.width = delta + 'px'
+ self._view.centerpanel.style.left = delta + 'px'
+ }
+ if (direction === 'right') {
+ self._view.rightpanel.style.width = delta + 'px'
+ self._view.centerpanel.style.right = delta + 'px'
+ }
}
init () {
var self = this
@@ -89,31 +134,31 @@ class App {
render () {
var self = this
if (self._view.el) return self._view.el
- /***************************************************************************/
- self._view.leftpanel = yo`
-
-
-
+ self._view.leftpanel = yo`
+
+ ${''}
`
self._view.centerpanel = yo`
- ${self._view.tabsbar}
-
+ ${self._components.editorpanel.render()}
+
+ `
+ self._view.rightpanel = yo`
+
+ ${''}
`
self._view.el = yo`
${self._view.leftpanel}
-
${self._view.centerpanel}
-
${self._view.rightpanel}
`
+ // INIT
+ self._adjustLayout('left', self.data._layout.left.offset)
+ self._adjustLayout('right', self.data._layout.right.offset)
return self._view.el
}
}
@@ -126,6 +171,7 @@ function run () {
var queryParams = new QueryParams()
var gistHandler = new GistHandler()
+ var editor = self._components.editor
// The event listener needs to be registered as early as possible, because the
// parent will send the message upon the "load" event.
var filesToLoad = null
@@ -138,12 +184,9 @@ function run () {
}, false)
this.event = new EventManager()
- var fileStorage = new Storage('sol:')
- var config = new Config(fileStorage)
- var remixd = new Remixd()
- var filesProviders = {}
- filesProviders['browser'] = new Browserfiles(fileStorage)
- filesProviders['localhost'] = new SharedFolder(remixd)
+
+ var config = self._api.config
+ var filesProviders = self._api.filesProviders
var tabbedFiles = {} // list of files displayed in the tabs bar
@@ -271,9 +314,6 @@ function run () {
createName: createNonClashingName,
switchToFile: switchToFile,
event: this.event,
- editorFontSize: function (incr) {
- editor.editorFontSize(incr)
- },
currentFile: function () {
return config.get('currentFile')
},
@@ -288,29 +328,9 @@ function run () {
// TODO this should happen inside file-panel.js
var filepanelContainer = document.querySelector('#filepanel')
- filepanelContainer.appendChild(filePanel)
-
- filePanel.events.register('ui-hidden', function changeLayout (isHidden) {
- var value
- if (isHidden) {
- value = -parseInt(self._view.leftpanel.style.width)
- value = (isNaN(value) ? -self._view.leftpanel.getBoundingClientRect().width : value)
- self._view.leftpanel.style.position = 'absolute'
- self._view.leftpanel.style.left = (value - 5) + 'px'
- self._view.leftpanel.style.width = -value + 'px'
- self._view.centerpanel.style.left = '45px'
- } else {
- value = -parseInt(self._view.leftpanel.style.left) + 'px'
- self._view.leftpanel.style.position = 'static'
- self._view.leftpanel.style.width = value
- self._view.leftpanel.style.left = ''
- self._view.centerpanel.style.left = value
- }
- })
- filePanel.events.register('ui-resize', function changeLayout (width) {
- self._view.leftpanel.style.width = width + 'px'
- self._view.centerpanel.style.left = width + 'px'
- })
+ filepanelContainer.appendChild(filePanel.render())
+
+ filePanel.event.register('resize', delta => self._adjustLayout('left', delta))
function fileRenamedEvent (oldName, newName, isFolder) {
// TODO please never use 'window' when it is possible to use a variable
@@ -411,12 +431,8 @@ function run () {
})
})
- // ----------------- editor ----------------------
- var editor = new Editor(document.getElementById('input'))
-
// --------------------Files tabs-----------------------------
var $filesEl = $('#files')
- var FILE_SCROLL_DELTA = 300
// Switch tab
$filesEl.on('click', '.file:not(.active)', function (ev) {
@@ -497,7 +513,6 @@ function run () {
for (var file in tabbedFiles) {
$filesEl.append($('
' + file + ''))
}
-
var currentFileOpen = !!config.get('currentFile')
if (currentFileOpen) {
@@ -506,57 +521,9 @@ function run () {
}
$('#input').toggle(currentFileOpen)
$('#output').toggle(currentFileOpen)
+ self._components.editorpanel.refresh()
}
- var $scrollerRight = $('.scroller-right')
- var $scrollerLeft = $('.scroller-left')
-
- function widthOfList () {
- var itemsWidth = 0
- $('.file').each(function () {
- var itemWidth = $(this).outerWidth()
- itemsWidth += itemWidth
- })
- return itemsWidth
- }
-
- function widthOfVisible () {
- return document.querySelector('#editor-container').offsetWidth
- }
-
- function getLeftPosi () {
- return $filesEl.position().left
- }
-
- function reAdjust () {
- if (widthOfList() + getLeftPosi() > widthOfVisible()) {
- $scrollerRight.fadeIn('fast')
- } else {
- $scrollerRight.fadeOut('fast')
- }
-
- if (getLeftPosi() < 0) {
- $scrollerLeft.fadeIn('fast')
- } else {
- $scrollerLeft.fadeOut('fast')
- $filesEl.animate({ left: getLeftPosi() + 'px' }, 'slow')
- }
- }
-
- $scrollerRight.click(function () {
- var delta = (getLeftPosi() - FILE_SCROLL_DELTA)
- $filesEl.animate({ left: delta + 'px' }, 'slow', function () {
- reAdjust()
- })
- })
-
- $scrollerLeft.click(function () {
- var delta = Math.min((getLeftPosi() + FILE_SCROLL_DELTA), 0)
- $filesEl.animate({ left: delta + 'px' }, 'slow', function () {
- reAdjust()
- })
- })
-
var compiler = new Compiler(handleImportCall)
var offsetToLineColumnConverter = new OffsetToLineColumnConverter(compiler.event)
@@ -703,18 +670,9 @@ function run () {
// ---------------- Righthand-panel --------------------
var rhpAPI = {
config: config,
- setEditorSize (delta) {
- $('#righthand-panel').css('width', delta)
- self._view.centerpanel.style.right = delta + 'px'
- document.querySelector(`.${css.dragbar2}`).style.right = delta + 'px'
- onResize()
- },
- reAdjust: reAdjust,
warnCompilerLoading: (msg) => {
renderer.clear()
- if (msg) {
- renderer.error(msg, $('#output'), {type: 'warning'})
- }
+ if (msg) renderer.error(msg, $('#output'), {type: 'warning'})
},
executionContextChange: (context) => {
return executionContext.executionContextChange(context)
@@ -728,17 +686,16 @@ function run () {
app: self.event,
udapp: udapp.event
}
- var righthandPanel = new RighthandPanel(rhpAPI, rhpEvents, {}) // eslint-disable-line
- self._view.rightpanel.appendChild(righthandPanel.render())
- righthandPanel.init()
+ self._components.righthandpanel = new RighthandPanel(rhpAPI, rhpEvents, {})
+ self._view.rightpanel.appendChild(self._components.righthandpanel.render())
+ self._components.righthandpanel.init()
+ self._components.righthandpanel.event.register('resize', delta => self._adjustLayout('right', delta))
// ----------------- editor resize ---------------
function onResize () {
editor.resize(document.querySelector('#editorWrap').checked)
- reAdjust()
}
- window.onresize = onResize
onResize()
self._view.el.addEventListener('change', onResize)
diff --git a/src/app/editor-panel.js b/src/app/editor-panel.js
new file mode 100644
index 0000000000..5749563223
--- /dev/null
+++ b/src/app/editor-panel.js
@@ -0,0 +1,240 @@
+var csjs = require('csjs-inject')
+var yo = require('yo-yo')
+var EventManager = require('ethereum-remix').lib.EventManager
+
+var css = csjs`
+ .tabsbar {
+ display : flex;
+ overflow : hidden;
+ }
+ .tabs {
+ position : relative;
+ display : flex;
+ margin : 0;
+ left : 10px;
+ margin-right : 10px;
+ width : 100%;
+ overflow : hidden;
+ }
+ .files {
+ position : relative;
+ list-style : none;
+ margin : 0;
+ font-size : 15px;
+ height : 2.5em;
+ box-sizing : border-box;
+ line-height : 2em;
+ padding : 0.5em 0 0;
+ top : 0;
+ border-bottom : 0 none;
+ }
+ .changeeditorfontsize {
+ margin : 0;
+ }
+ .changeeditorfontsize i {
+ cursor : pointer;
+ display : block;
+ color : #111111;
+ }
+ .changeeditorfontsize i {
+ cursor : pointer;
+ }
+ .changeeditorfontsize i:hover {
+ color : orange;
+ }
+ .buttons {
+ display : flex;
+ flex-direction : row;
+ justify-content : space-around;
+ align-items : center;
+ min-width : 45px;
+ }
+ .toggleLHP {
+ display : flex;
+ padding : 10px;
+ width : 100%;
+ font-weight : bold;
+ color : black;
+ }
+ .toggleLHP i {
+ cursor : pointer;
+ }
+ .toggleLHP i:hover {
+ color : orange;
+ }
+ .scroller {
+ position : absolute;
+ z-index : 999;
+ text-align : center;
+ cursor : pointer;
+ padding : 0 0.9em;
+ vertical-align : middle;
+ background-color : rgba(255, 255, 255, 0.8);
+ height : 100%;
+ font-size : 1.3em;
+ }
+ .scroller i {
+ line-height : 3em;
+ }
+ .scrollerright {
+ right : 0;
+ margin-right : 15px;
+ }
+ .scrollerleft {
+ left : 0;
+ }
+ .toggleRHP {
+ margin-top : 0.5em;
+ padding : 0.6em;
+ font-weight : bold;
+ color : black;
+ right : 0;
+ }
+ .toggleRHP i {
+ cursor : pointer;
+ }
+ .toggleRHP i:hover {
+ color : orange;
+ }
+ .show {
+ opacity : 1;
+ transition : .3s opacity ease-in;
+ }
+ .hide {
+ opacity : 0;
+ pointer-events : none;
+ transition : .3s opacity ease-in;
+ }
+`
+
+class EditorPanel {
+ constructor (opts = {}) {
+ var self = this
+ self.data = {
+ _FILE_SCROLL_DELTA: 200
+ }
+ self._view = {}
+ self._api = { editor: opts.api.editor }
+ self.event = new EventManager()
+ }
+ refresh () {
+ var self = this
+ self._view.tabs.onmouseenter()
+ }
+ render () {
+ var self = this
+ if (self._view.el) return self._view.el
+ self._view.el = [
+ self._renderTabsbar(),
+ self._api.editor.render()
+ ]
+ return self._view.el
+ }
+ _renderTabsbar () {
+ var self = this
+ if (self._view.tabsbar) return self._view.tabsbar
+ self._view.filetabs = yo`
`
+ self._view.tabs = yo`
+
+
+
+
+ ${self._view.filetabs}
+
+
+
+
+ `
+ self._view.tabsbar = yo`
+
+
+
+
+
+
+
+
+
+
+ ${self._view.tabs}
+
+
+
+
+ `
+ return self._view.tabsbar
+ function toggleScrollers (event = {}) {
+ if (event.type) self.data._focus = event.type
+ var isMouseEnter = self.data._focus === 'mouseenter'
+ var leftArrow = this.children[0]
+ var rightArrow = this.children[2]
+ if (isMouseEnter && this.children[1].offsetWidth > this.offsetWidth) {
+ var hiddenLength = self._view.filetabs.offsetWidth - self._view.tabs.offsetWidth
+ var currentLeft = self._view.filetabs.offsetLeft || 0
+ var hiddenRight = hiddenLength + currentLeft
+ if (currentLeft < 0) {
+ leftArrow.classList.add(css.show)
+ leftArrow.classList.remove(css.hide)
+ }
+ if (hiddenRight > 0) {
+ rightArrow.classList.add(css.show)
+ rightArrow.classList.remove(css.hide)
+ }
+ } else {
+ leftArrow.classList.remove(css.show)
+ leftArrow.classList.add(css.hide)
+ rightArrow.classList.remove(css.show)
+ rightArrow.classList.add(css.hide)
+ }
+ }
+ function toggleLHP (event) {
+ this.children[0].classList.toggle('fa-angle-double-right')
+ this.children[0].classList.toggle('fa-angle-double-left')
+ self.event.trigger('resize', ['left'])
+ }
+ function toggleRHP (event) {
+ this.children[0].classList.toggle('fa-angle-double-right')
+ this.children[0].classList.toggle('fa-angle-double-left')
+ self.event.trigger('resize', ['right'])
+ }
+ function increase () { self._api.editor.editorFontSize(1) }
+ function decrease () { self._api.editor.editorFontSize(-1) }
+ function scrollLeft (event) {
+ var leftArrow = this
+ var rightArrow = this.nextElementSibling.nextElementSibling
+ var currentLeft = self._view.filetabs.offsetLeft || 0
+ if (currentLeft < 0) {
+ rightArrow.classList.add(css.show)
+ rightArrow.classList.remove(css.hide)
+ if (currentLeft < -self.data._FILE_SCROLL_DELTA) {
+ self._view.filetabs.style.left = `${currentLeft + self.data._FILE_SCROLL_DELTA}px`
+ } else {
+ self._view.filetabs.style.left = `${currentLeft - currentLeft}px`
+ leftArrow.classList.remove(css.show)
+ leftArrow.classList.add(css.hide)
+ }
+ }
+ }
+
+ function scrollRight (event) {
+ var rightArrow = this
+ var leftArrow = this.previousElementSibling.previousElementSibling
+ var hiddenLength = self._view.filetabs.offsetWidth - self._view.tabs.offsetWidth
+ var currentLeft = self._view.filetabs.offsetLeft || 0
+ var hiddenRight = hiddenLength + currentLeft
+ if (hiddenRight > 0) {
+ leftArrow.classList.add(css.show)
+ leftArrow.classList.remove(css.hide)
+ if (hiddenRight > self.data._FILE_SCROLL_DELTA) {
+ self._view.filetabs.style.left = `${currentLeft - self.data._FILE_SCROLL_DELTA}px`
+ } else {
+ self._view.filetabs.style.left = `${currentLeft - hiddenRight}px`
+ rightArrow.classList.remove(css.show)
+ rightArrow.classList.add(css.hide)
+ }
+ }
+ }
+ }
+}
+
+module.exports = EditorPanel
diff --git a/src/app/editor.js b/src/app/editor.js
index 799a9aa414..19ffda7088 100644
--- a/src/app/editor.js
+++ b/src/app/editor.js
@@ -24,12 +24,15 @@ document.head.appendChild(yo`
`)
-function Editor (editorElement) {
- var editor = ace.edit(editorElement)
- editorElement.editor = editor // required to access the editor during tests
- editorElement.className += ' ' + css['ace-editor']
+function Editor (opts = {}) {
+ var self = this
+ var el = yo`
`
+ var editor = ace.edit(el)
+ el.className += ' ' + css['ace-editor']
+ el.editor = editor // required to access the editor during tests
+ self.render = function () { return el }
var event = new EventManager()
- this.event = event
+ self.event = event
var sessions = {}
var sourceAnnotations = []
var readOnlySessions = {}
@@ -37,7 +40,6 @@ function Editor (editorElement) {
var emptySession = createSession('')
- var self = this
editor.on('guttermousedown', function (e) {
var target = e.domEvent.target
if (target.className.indexOf('ace_gutter-cell') === -1) {
diff --git a/src/app/file-panel.js b/src/app/file-panel.js
index 29ccd7bd00..316441d37e 100644
--- a/src/app/file-panel.js
+++ b/src/app/file-panel.js
@@ -13,6 +13,7 @@ var css = csjs`
display : flex;
flex-direction : row;
width : 100%;
+ height : 100%;
box-sizing : border-box;
}
.fileexplorer {
@@ -28,37 +29,39 @@ var css = csjs`
.newFile {
padding : 10px;
}
+ .newFile i {
+ cursor : pointer;
+ }
+ .newFile i:hover {
+ color : orange;
+ }
.connectToLocalhost {
padding : 10px;
}
- .uploadFile {
- padding : 10px;
+ .connectToLocalhost i {
+ cursor : pointer;
}
- .toggleLHP {
- display : flex;
- justify-content : flex-end;
+ .connectToLocalhost i:hover {
+ color : orange;
+ }
+ .uploadFile {
padding : 10px;
- width : 100%;
- font-weight : bold;
- cursor : pointer;
- color : black;
}
- .isVisible {
- position : absolute;
- left : 35px;
+ .uploadFile label:hover {
+ color : orange;
}
- .isHidden {
- position : absolute;
- height : 99%;
- left : -101%;
+ .uploadFile label {
+ cursor : pointer;
}
.treeview {
background-color : white;
}
.dragbar {
- position : relative;
- top : 36px;
- left : 2px;
+ position : absolute;
+ top : 37px;
+ width : 0.5em;
+ right : 0;
+ bottom : 0;
cursor : col-resize;
z-index : 999;
border-right : 2px solid hsla(215, 81%, 79%, .3);
@@ -73,13 +76,6 @@ var css = csjs`
top : 0;
bottom : 0;
}
- .changeeditorfontsize {
- padding: 10px;
- }
- .changeeditorfontsize i {
- display: block;
- color: #111111;
- }
`
var limit = 60
@@ -87,6 +83,7 @@ var canUpload = window.File || window.FileReader || window.FileList || window.Bl
var ghostbar = yo`
`
function filepanel (appAPI, filesProvider) {
+ var self = this
var fileExplorer = new FileExplorer(appAPI, filesProvider['browser'])
var fileSystemExplorer = new FileExplorer(appAPI, filesProvider['localhost'])
var dragbar = yo`
`
@@ -119,13 +116,6 @@ function filepanel (appAPI, filesProvider) {
-
-
-
-
-
-
-