Commit d8bcd009 authored by yann300's avatar yann300

move solidity version selector to compile tab

parent 90006730
/* global Worker */
const yo = require('yo-yo') const yo = require('yo-yo')
const csjs = require('csjs-inject') const csjs = require('csjs-inject')
const copy = require('clipboard-copy') const copy = require('clipboard-copy')
var minixhr = require('minixhr')
var tooltip = require('../ui/tooltip')
var QueryParams = require('../../lib/query-params')
var globalRegistry = require('../../global/registry') var globalRegistry = require('../../global/registry')
const TreeView = require('../ui/TreeView') const TreeView = require('../ui/TreeView')
const modalDialog = require('../ui/modaldialog') const modalDialog = require('../ui/modaldialog')
...@@ -11,6 +14,7 @@ const styleGuide = require('../ui/styles-guide/theme-chooser') ...@@ -11,6 +14,7 @@ const styleGuide = require('../ui/styles-guide/theme-chooser')
const parseContracts = require('../contract/contractParser') const parseContracts = require('../contract/contractParser')
const publishOnSwarm = require('../contract/publishOnSwarm') const publishOnSwarm = require('../contract/publishOnSwarm')
const addTooltip = require('../ui/tooltip') const addTooltip = require('../ui/tooltip')
var helper = require('../../lib/helper')
const styles = styleGuide.chooser() const styles = styleGuide.chooser()
...@@ -27,10 +31,15 @@ module.exports = class CompileTab { ...@@ -27,10 +31,15 @@ module.exports = class CompileTab {
errorContainer: null, errorContainer: null,
errorContainerHead: null, errorContainerHead: null,
contractNames: null, contractNames: null,
contractEl: null contractEl: null,
config: {
solidity: null
},
optimize: null
} }
self._components = {} self._components = {}
self._components.registry = localRegistry || globalRegistry self._components.registry = localRegistry || globalRegistry
self._components.queryParams = new QueryParams()
// dependencies // dependencies
self._deps = { self._deps = {
app: self._components.registry.get('app').api, app: self._components.registry.get('app').api,
...@@ -47,8 +56,15 @@ module.exports = class CompileTab { ...@@ -47,8 +56,15 @@ module.exports = class CompileTab {
compileTimeout: null, compileTimeout: null,
contractsDetails: {}, contractsDetails: {},
maxTime: 1000, maxTime: 1000,
timeout: 300 timeout: 300,
allversions: null,
selectedVersion: null,
baseurl: 'https://solc-bin.ethereum.org/bin'
} }
self.data.optimize = !!self._components.queryParams.get().optimize
self._components.queryParams.update({ optimize: self.data.optimize })
self._deps.compiler.setOptimize(self.data.optimize)
self._deps.editor.event.register('contentChanged', scheduleCompilation) self._deps.editor.event.register('contentChanged', scheduleCompilation)
self._deps.editor.event.register('sessionSwitched', scheduleCompilation) self._deps.editor.event.register('sessionSwitched', scheduleCompilation)
function scheduleCompilation () { function scheduleCompilation () {
...@@ -149,6 +165,44 @@ module.exports = class CompileTab { ...@@ -149,6 +165,44 @@ module.exports = class CompileTab {
render () { render () {
const self = this const self = this
if (self._view.el) return self._view.el if (self._view.el) return self._view.el
function onchangeLoadVersion (event) {
self.data.selectedVersion = self._view.versionSelector.value
self._updateVersionSelector()
}
function onchangeOptimize (event) {
self.data.optimize = !!self._view.optimize.checked
self._components.queryParams.update({ optimize: self.data.optimize })
self._deps.compiler.setOptimize(self.data.optimize)
self._deps.app.runCompiler()
}
self._deps.compiler.event.register('compilerLoaded', (version) => self.setVersionText(version))
self.fetchAllVersion((allversions, selectedVersion) => {
self.data.allversions = allversions
self.data.selectedVersion = selectedVersion
if (self._view.versionSelector) self._updateVersionSelector()
})
self._view.optimize = yo`<input onchange=${onchangeOptimize} id="optimize" type="checkbox">`
if (self.data.optimize) self._view.optimize.setAttribute('checked', '')
self._view.versionSelector = yo`
<select onchange=${onchangeLoadVersion} class="${css.select}" id="versionSelector" disabled>
<option disabled selected>Select new compiler version</option>
</select>`
if (self.data.allversions && self.data.selectedVersion) self._updateVersionSelector()
self._view.version = yo`<span id="version"></span>`
self._view.config.solidity = yo`
<div class="${css.info}">
<span>Current version:</span> ${self._view.version}
<div class="${css.crow}">
${self._view.versionSelector}
</div>
</div>`
self._view.warnCompilationSlow = yo`<i title="Compilation Slow" style="visibility:hidden" class="${css.warnCompilationSlow} fa fa-exclamation-triangle" aria-hidden="true"></i>` self._view.warnCompilationSlow = yo`<i title="Compilation Slow" style="visibility:hidden" class="${css.warnCompilationSlow} fa fa-exclamation-triangle" aria-hidden="true"></i>`
self._view.compileIcon = yo`<i class="fa fa-refresh ${css.icon}" aria-hidden="true"></i>` self._view.compileIcon = yo`<i class="fa fa-refresh ${css.icon}" aria-hidden="true"></i>`
self._view.compileButton = yo`<div class="${css.compileButton}" onclick=${compile} id="compile" title="Compile source code">${self._view.compileIcon} Start to compile</div>` self._view.compileButton = yo`<div class="${css.compileButton}" onclick=${compile} id="compile" title="Compile source code">${self._view.compileIcon} Start to compile</div>`
...@@ -158,13 +212,18 @@ module.exports = class CompileTab { ...@@ -158,13 +212,18 @@ module.exports = class CompileTab {
if (self.data.hideWarnings) self._view.hideWarningsBox.setAttribute('checked', '') if (self.data.hideWarnings) self._view.hideWarningsBox.setAttribute('checked', '')
self._view.compileContainer = yo` self._view.compileContainer = yo`
<div class="${css.compileContainer}"> <div class="${css.compileContainer}">
${self._view.config.solidity}
<div class="${css.compileButtons}"> <div class="${css.compileButtons}">
${self._view.compileButton} ${self._view.compileButton}
${self._view.warnCompilationSlow}
<div class="${css.autocompileContainer}"> <div class="${css.autocompileContainer}">
${self._view.autoCompile} ${self._view.autoCompile}
<span class="${css.autocompileText}">Auto compile</span> <span class="${css.autocompileText}">Auto compile</span>
</div> </div>
${self._view.warnCompilationSlow} <div class="${css.crow}">
<div>${self._view.optimize}</div>
<span class="${css.checkboxText}">Enable Optimization</span>
</div>
<div class=${css.hideWarningsContainer}> <div class=${css.hideWarningsContainer}>
${self._view.hideWarningsBox} ${self._view.hideWarningsBox}
<span class="${css.autocompileText}">Hide warnings</span> <span class="${css.autocompileText}">Hide warnings</span>
...@@ -324,9 +383,93 @@ module.exports = class CompileTab { ...@@ -324,9 +383,93 @@ module.exports = class CompileTab {
} }
return self._view.el return self._view.el
} }
setVersionText (text) {
const self = this
self.data.version = text
if (self._view.version) self._view.version.innerText = text
}
_updateVersionSelector () {
const self = this
self._view.versionSelector.innerHTML = ''
self._view.versionSelector.appendChild(yo`<option disabled selected>Select new compiler version</option>`)
self.data.allversions.forEach(build => self._view.versionSelector.appendChild(yo`<option value=${build.path}>${build.longVersion}</option>`))
self._view.versionSelector.removeAttribute('disabled')
self._components.queryParams.update({ version: self.data.selectedVersion })
var url
if (self.data.selectedVersion === 'builtin') {
var location = window.document.location
location = location.protocol + '//' + location.host + '/' + location.pathname
if (location.endsWith('index.html')) location = location.substring(0, location.length - 10)
if (!location.endsWith('/')) location += '/'
url = location + 'soljson.js'
} else {
if (self.data.selectedVersion.indexOf('soljson') !== 0 || helper.checkSpecialChars(self.data.selectedVersion)) {
return console.log('loading ' + self.data.selectedVersion + ' not allowed')
}
url = `${self.data.baseurl}/${self.data.selectedVersion}`
}
var isFirefox = typeof InstallTrigger !== 'undefined'
if (document.location.protocol !== 'file:' && Worker !== undefined && isFirefox) {
// Workers cannot load js on "file:"-URLs and we get a
// "Uncaught RangeError: Maximum call stack size exceeded" error on Chromium,
// resort to non-worker version in that case.
self._deps.compiler.loadVersion(true, url)
self.setVersionText('(loading using worker)')
} else {
self._deps.compiler.loadVersion(false, url)
self.setVersionText('(loading)')
}
}
fetchAllVersion (callback) {
var self = this
minixhr(`${self.data.baseurl}/list.json`, function (json, event) {
// @TODO: optimise and cache results to improve app loading times
var allversions, selectedVersion
if (event.type !== 'error') {
try {
const data = JSON.parse(json)
allversions = data.builds.slice().reverse()
selectedVersion = data.releases[data.latestRelease]
if (self._components.queryParams.get().version) selectedVersion = self._components.queryParams.get().version
} catch (e) {
tooltip('Cannot load compiler version list. It might have been blocked by an advertisement blocker. Please try deactivating any of them from this page and reload.')
}
} else {
allversions = [{ path: 'builtin', longVersion: 'latest local version' }]
selectedVersion = 'builtin'
}
callback(allversions, selectedVersion)
})
}
} }
const css = csjs` const css = csjs`
.crow {
display: flex;
overflow: auto;
clear: both;
padding: .2em;
}
.checkboxText {
font-weight: normal;
}
.crow label {
cursor:pointer;
}
.crowNoFlex {
overflow: auto;
clear: both;
}
.select {
font-weight: bold;
margin-top: 1em;
${styles.rightPanel.settingsTab.dropdown_SelectCompiler};
}
.info {
${styles.rightPanel.settingsTab.box_SolidityVersionInfo}
margin-bottom: 1em;
word-break: break-word;
}
.compileTabView { .compileTabView {
padding: 2%; padding: 2%;
} }
......
/* global Worker */
var yo = require('yo-yo') var yo = require('yo-yo')
var csjs = require('csjs-inject') var csjs = require('csjs-inject')
var minixhr = require('minixhr')
var remixLib = require('remix-lib') var remixLib = require('remix-lib')
var globalRegistry = require('../../global/registry') var globalRegistry = require('../../global/registry')
var QueryParams = require('../../lib/query-params')
var helper = require('../../lib/helper')
var modal = require('../ui/modal-dialog-custom') var modal = require('../ui/modal-dialog-custom')
var tooltip = require('../ui/tooltip') var tooltip = require('../ui/tooltip')
var copyToClipboard = require('../ui/copy-to-clipboard') var copyToClipboard = require('../ui/copy-to-clipboard')
...@@ -31,33 +27,18 @@ module.exports = class SettingsTab { ...@@ -31,33 +27,18 @@ module.exports = class SettingsTab {
} }
self._view = { /* eslint-disable */ self._view = { /* eslint-disable */
el: null, el: null,
optionVM: null, personal: null, optimize: null, warnPersonalMode: null, optionVM: null, personal: null, warnPersonalMode: null,
pluginInput: null, versionSelector: null, version: null, pluginInput: null, versionSelector: null, version: null,
theme: { dark: null, light: null }, theme: { dark: null, light: null },
config: { config: {
solidity: null, general: null, themes: null, general: null, themes: null,
plugin: null, remixd: null, localremixd: null plugin: null, remixd: null, localremixd: null
} }
} /* eslint-enable */ } /* eslint-enable */
self.data = { self.data = {}
allversions: null,
selectedVersion: null,
baseurl: 'https://solc-bin.ethereum.org/bin'
}
self.event = new EventManager() self.event = new EventManager()
self._components.queryParams = new QueryParams()
self._components.themeStorage = new Storage('style:') self._components.themeStorage = new Storage('style:')
self.data.optimize = !!self._components.queryParams.get().optimize
self._components.queryParams.update({ optimize: self.data.optimize })
self._deps.compiler.setOptimize(self.data.optimize)
self.data.currentTheme = self._components.themeStorage.get('theme') || 'light' self.data.currentTheme = self._components.themeStorage.get('theme') || 'light'
self._deps.compiler.event.register('compilerLoaded', (version) => self.setVersionText(version))
self.fetchAllVersion((allversions, selectedVersion) => {
self.data.allversions = allversions
self.data.selectedVersion = selectedVersion
if (self._view.versionSelector) self._updateVersionSelector()
})
} }
render () { render () {
const self = this const self = this
...@@ -75,8 +56,6 @@ module.exports = class SettingsTab { ...@@ -75,8 +56,6 @@ module.exports = class SettingsTab {
if (self._deps.config.get('settings/always-use-vm')) self._view.optionVM.setAttribute('checked', '') if (self._deps.config.get('settings/always-use-vm')) self._view.optionVM.setAttribute('checked', '')
self._view.personal = yo`<input onchange=${onchangePersonal} id="personal" type="checkbox">` self._view.personal = yo`<input onchange=${onchangePersonal} id="personal" type="checkbox">`
if (self._deps.config.get('settings/personal-mode')) self._view.personal.setAttribute('checked', '') if (self._deps.config.get('settings/personal-mode')) self._view.personal.setAttribute('checked', '')
self._view.optimize = yo`<input onchange=${onchangeOptimize} id="optimize" type="checkbox">`
if (self.data.optimize) self._view.optimize.setAttribute('checked', '')
var warnText = `Transaction sent over Web3 will use the web3.personal API - be sure the endpoint is opened before enabling it. var warnText = `Transaction sent over Web3 will use the web3.personal API - be sure the endpoint is opened before enabling it.
This mode allows to provide the passphrase in the Remix interface without having to unlock the account. This mode allows to provide the passphrase in the Remix interface without having to unlock the account.
Although this is very convenient, you should completely trust the backend you are connected to (Geth, Parity, ...). Although this is very convenient, you should completely trust the backend you are connected to (Geth, Parity, ...).
...@@ -84,23 +63,11 @@ module.exports = class SettingsTab { ...@@ -84,23 +63,11 @@ module.exports = class SettingsTab {
Remix never persist any passphrase.`.split('\n').map(s => s.trim()).join(' ') Remix never persist any passphrase.`.split('\n').map(s => s.trim()).join(' ')
self._view.warnPersonalMode = yo`<i title=${warnText} class="${css.icon} fa fa-exclamation-triangle" aria-hidden="true"></i>` self._view.warnPersonalMode = yo`<i title=${warnText} class="${css.icon} fa fa-exclamation-triangle" aria-hidden="true"></i>`
self._view.pluginInput = yo`<textarea rows="4" cols="70" id="plugininput" type="text" class="${css.pluginTextArea}" ></textarea>` self._view.pluginInput = yo`<textarea rows="4" cols="70" id="plugininput" type="text" class="${css.pluginTextArea}" ></textarea>`
self._view.versionSelector = yo`
<select onchange=${onchangeLoadVersion} class="${css.select}" id="versionSelector" disabled>
<option disabled selected>Select new compiler version</option>
</select>`
if (self.data.allversions && self.data.selectedVersion) self._updateVersionSelector()
self._view.version = yo`<span id="version"></span>`
self._view.theme.light = yo`<input onchange=${onswitch2lightTheme} class="${css.col1}" name="theme" id="themeLight" type="radio">` self._view.theme.light = yo`<input onchange=${onswitch2lightTheme} class="${css.col1}" name="theme" id="themeLight" type="radio">`
self._view.theme.dark = yo`<input onchange=${onswitch2darkTheme} class="${css.col1}" name="theme" id="themeDark" type="radio">` self._view.theme.dark = yo`<input onchange=${onswitch2darkTheme} class="${css.col1}" name="theme" id="themeDark" type="radio">`
self._view.theme[self.data.currentTheme].setAttribute('checked', 'checked') self._view.theme[self.data.currentTheme].setAttribute('checked', 'checked')
self._view.config.solidity = yo`
<div class="${css.info}">
<div class=${css.title}>Solidity version</div>
<span>Current version:</span> ${self._view.version}
<div class="${css.crow}">
${self._view.versionSelector}
</div>
</div>`
self._view.config.general = yo` self._view.config.general = yo`
<div class="${css.info}"> <div class="${css.info}">
<div class=${css.title}>General settings</div> <div class=${css.title}>General settings</div>
...@@ -113,10 +80,6 @@ module.exports = class SettingsTab { ...@@ -113,10 +80,6 @@ module.exports = class SettingsTab {
<span class="${css.checkboxText}">Text Wrap</span> <span class="${css.checkboxText}">Text Wrap</span>
</div> </div>
<div class="${css.crow}"> <div class="${css.crow}">
<div>${self._view.optimize}</div>
<span class="${css.checkboxText}">Enable Optimization</span>
</div>
<div class="${css.crow}">
<div>${self._view.personal}></div> <div>${self._view.personal}></div>
<span class="${css.checkboxText}">Enable Personal Mode ${self._view.warnPersonalMode}></span> <span class="${css.checkboxText}">Enable Personal Mode ${self._view.warnPersonalMode}></span>
</div> </div>
...@@ -184,7 +147,6 @@ module.exports = class SettingsTab { ...@@ -184,7 +147,6 @@ module.exports = class SettingsTab {
</div>` </div>`
self._view.el = yo` self._view.el = yo`
<div class="${css.settingsTabView} "id="settingsView"> <div class="${css.settingsTabView} "id="settingsView">
${self._view.config.solidity}
${self._view.config.general} ${self._view.config.general}
${self._view.gistToken} ${self._view.gistToken}
${self._view.config.themes} ${self._view.config.themes}
...@@ -216,79 +178,11 @@ module.exports = class SettingsTab { ...@@ -216,79 +178,11 @@ module.exports = class SettingsTab {
styleGuide.switchTheme('light') styleGuide.switchTheme('light')
window.location.reload() window.location.reload()
} }
function onchangeOptimize (event) {
self.data.optimize = !!self._view.optimize.checked
self._components.queryParams.update({ optimize: self.data.optimize })
self._deps.compiler.setOptimize(self.data.optimize)
self._deps.app.runCompiler()
}
function onchangeLoadVersion (event) {
self.data.selectedVersion = self._view.versionSelector.value
self._updateVersionSelector()
}
function onchangePersonal (event) { function onchangePersonal (event) {
self._deps.config.set('settings/personal-mode', !self._deps.config.get('settings/personal-mode')) self._deps.config.set('settings/personal-mode', !self._deps.config.get('settings/personal-mode'))
} }
return self._view.el return self._view.el
} }
setVersionText (text) {
const self = this
self.data.version = text
if (self._view.version) self._view.version.innerText = text
}
_updateVersionSelector () {
const self = this
self._view.versionSelector.innerHTML = ''
self._view.versionSelector.appendChild(yo`<option disabled selected>Select new compiler version</option>`)
self.data.allversions.forEach(build => self._view.versionSelector.appendChild(yo`<option value=${build.path}>${build.longVersion}</option>`))
self._view.versionSelector.removeAttribute('disabled')
self._components.queryParams.update({ version: self.data.selectedVersion })
var url
if (self.data.selectedVersion === 'builtin') {
var location = window.document.location
location = location.protocol + '//' + location.host + '/' + location.pathname
if (location.endsWith('index.html')) location = location.substring(0, location.length - 10)
if (!location.endsWith('/')) location += '/'
url = location + 'soljson.js'
} else {
if (self.data.selectedVersion.indexOf('soljson') !== 0 || helper.checkSpecialChars(self.data.selectedVersion)) {
return console.log('loading ' + self.data.selectedVersion + ' not allowed')
}
url = `${self.data.baseurl}/${self.data.selectedVersion}`
}
var isFirefox = typeof InstallTrigger !== 'undefined'
if (document.location.protocol !== 'file:' && Worker !== undefined && isFirefox) {
// Workers cannot load js on "file:"-URLs and we get a
// "Uncaught RangeError: Maximum call stack size exceeded" error on Chromium,
// resort to non-worker version in that case.
self._deps.compiler.loadVersion(true, url)
self.setVersionText('(loading using worker)')
} else {
self._deps.compiler.loadVersion(false, url)
self.setVersionText('(loading)')
}
}
fetchAllVersion (callback) {
var self = this
minixhr(`${self.data.baseurl}/list.json`, function (json, event) {
// @TODO: optimise and cache results to improve app loading times
var allversions, selectedVersion
if (event.type !== 'error') {
try {
const data = JSON.parse(json)
allversions = data.builds.slice().reverse()
selectedVersion = data.releases[data.latestRelease]
if (self._components.queryParams.get().version) selectedVersion = self._components.queryParams.get().version
} catch (e) {
tooltip('Cannot load compiler version list. It might have been blocked by an advertisement blocker. Please try deactivating any of them from this page and reload.')
}
} else {
allversions = [{ path: 'builtin', longVersion: 'latest local version' }]
selectedVersion = 'builtin'
}
callback(allversions, selectedVersion)
})
}
} }
const css = csjs` const css = csjs`
...@@ -297,7 +191,7 @@ const css = csjs` ...@@ -297,7 +191,7 @@ const css = csjs`
display: flex; display: flex;
} }
.info { .info {
${styles.rightPanel.settingsTab.box_SolidityVersionInfo} ${styles.rightPanel.settingsTab.box_SolidityVersionInfo};
margin-bottom: 1em; margin-bottom: 1em;
word-break: break-word; word-break: break-word;
} }
...@@ -327,11 +221,6 @@ const css = csjs` ...@@ -327,11 +221,6 @@ const css = csjs`
padding: .5em; padding: .5em;
font-weight: bold; font-weight: bold;
} }
.select {
font-weight: bold;
margin-top: 1em;
${styles.rightPanel.settingsTab.dropdown_SelectCompiler};
}
.heading { .heading {
margin-bottom: 0; margin-bottom: 0;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment