${self._view.compileButton}
+ ${self._view.warnCompilationSlow}
${self._view.autoCompile}
Auto compile
- ${self._view.warnCompilationSlow}
+
+
${self._view.optimize}
+
Enable Optimization
+
${self._view.hideWarningsBox}
Hide warnings
@@ -324,9 +383,93 @@ module.exports = class CompileTab {
}
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`
Select new compiler version `)
+ self.data.allversions.forEach(build => self._view.versionSelector.appendChild(yo`
${build.longVersion} `))
+ 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`
+ .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 {
padding: 2%;
}
diff --git a/src/app/tabs/settings-tab.js b/src/app/tabs/settings-tab.js
index 24cb2f8814..71cf9757f8 100644
--- a/src/app/tabs/settings-tab.js
+++ b/src/app/tabs/settings-tab.js
@@ -1,17 +1,12 @@
-/* global Worker */
var yo = require('yo-yo')
var csjs = require('csjs-inject')
-var minixhr = require('minixhr')
var remixLib = require('remix-lib')
+const defaultPlugins = require('../plugin/plugins')
var globalRegistry = require('../../global/registry')
-var QueryParams = require('../../lib/query-params')
-var helper = require('../../lib/helper')
-var modal = require('../ui/modal-dialog-custom')
var tooltip = require('../ui/tooltip')
var copyToClipboard = require('../ui/copy-to-clipboard')
var styleGuide = require('../ui/styles-guide/theme-chooser')
-
var styles = styleGuide.chooser()
var Storage = remixLib.Storage
var EventManager = remixLib.EventManager
@@ -31,33 +26,19 @@ module.exports = class SettingsTab {
}
self._view = { /* eslint-disable */
el: null,
- optionVM: null, personal: null, optimize: null, warnPersonalMode: null,
+ optionVM: null, personal: null, warnPersonalMode: null,
pluginInput: null, versionSelector: null, version: null,
theme: { dark: null, light: null },
+ plugins: {},
config: {
- solidity: null, general: null, themes: null,
- plugin: null, remixd: null, localremixd: null
+ general: null, themes: null,
+ plugin: null
}
} /* eslint-enable */
- self.data = {
- allversions: null,
- selectedVersion: null,
- baseurl: 'https://solc-bin.ethereum.org/bin'
- }
+ self.data = {}
self.event = new EventManager()
- self._components.queryParams = new QueryParams()
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._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 () {
const self = this
@@ -75,8 +56,6 @@ module.exports = class SettingsTab {
if (self._deps.config.get('settings/always-use-vm')) self._view.optionVM.setAttribute('checked', '')
self._view.personal = yo`
`
if (self._deps.config.get('settings/personal-mode')) self._view.personal.setAttribute('checked', '')
- self._view.optimize = yo`
`
- 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.
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, ...).
@@ -84,23 +63,11 @@ module.exports = class SettingsTab {
Remix never persist any passphrase.`.split('\n').map(s => s.trim()).join(' ')
self._view.warnPersonalMode = yo`
`
self._view.pluginInput = yo`
`
- self._view.versionSelector = yo`
-
- Select new compiler version
- `
- if (self.data.allversions && self.data.selectedVersion) self._updateVersionSelector()
- self._view.version = yo`
`
+
self._view.theme.light = yo`
`
self._view.theme.dark = yo`
`
self._view.theme[self.data.currentTheme].setAttribute('checked', 'checked')
- self._view.config.solidity = yo`
-
-
Solidity version
-
Current version: ${self._view.version}
-
- ${self._view.versionSelector}
-
-
`
+
self._view.config.general = yo`
General settings
@@ -112,10 +79,6 @@ module.exports = class SettingsTab {
Text Wrap
-
-
${self._view.optimize}
-
Enable Optimization
-
${self._view.personal}>
Enable Personal Mode ${self._view.warnPersonalMode}>
@@ -146,67 +109,75 @@ module.exports = class SettingsTab {
Dark Theme
`
+ self._view.config.plugins = yo`
`
self._view.config.plugin = yo`
`
- self._view.config.remixd = yo`
-
-
Remixd
-
- Remixd is a tool which allow Remix IDE to access files located in your local computer.
- it can also be used to setup a development environment.
+
+ ${self._view.config.plugins}
-
More infos:
-
-
-
Installation:
npm install remixd -g
-
`
- self._view.config.localremixd = yo`
-
`
self._view.el = yo`
-
- ${self._view.config.solidity}
+
${self._view.config.general}
+ ${self._view.config.plugin}
${self._view.gistToken}
${self._view.config.themes}
- ${self._view.config.plugin}
- ${self._view.config.remixd}
- ${self._view.config.localremixd}
`
- function onchangeOption (event) {
- self._deps.config.set('settings/always-use-vm', !self._deps.config.get('settings/always-use-vm'))
+
+ function loadPlugins (plugins, opt) {
+ for (var k in plugins) {
+ var plugin = plugins[k]
+ if (!self._view.plugins[plugin.title]) self._view.plugins[plugin.title] = {}
+ self._view.plugins[plugin.title].json = plugin
+ self._view.plugins[plugin.title].el = yo`
+
{ onLoadPlugin(plugin.title) }}>${plugin.title}
+ ${opt.removable ? yo`
{ onRemovePlugin(plugin.title) }}> ` : yo`
`}
+
`
+ self._view.config.plugins.appendChild(self._view.plugins[plugin.title].el)
+ }
+ }
+
+ function getSavedPlugin () {
+ var savedPlugin = self._deps.config.get('settings/plugins-list')
+ return savedPlugin ? JSON.parse(savedPlugin) : {}
}
+ function setSavedPlugin (savedPlugins) {
+ self._deps.config.set('settings/plugins-list', JSON.stringify(savedPlugins))
+ }
+ loadPlugins(defaultPlugins, {removable: false})
+ loadPlugins(getSavedPlugin(), {removable: true})
+
function onLoadPlugin (name) {
- // @TODO: BAD! REFACTOR: no module should trigger events of another modules emitter
- self._deps.righthandpanel.event.trigger('plugin-name-loadRequest', [name])
+ self.event.trigger('plugin-loadRequest', [self._view.plugins[name].json])
+ }
+ function onRemovePlugin (name) {
+ var savedPlugin = getSavedPlugin()
+ delete savedPlugin[name]
+ setSavedPlugin(savedPlugin)
+ if (self._view.plugins[name]) {
+ self._view.plugins[name].el.parentNode.removeChild(self._view.plugins[name].el)
+ delete self._view.plugins[name]
+ }
}
function onloadPluginJson (event) {
try {
var json = JSON.parse(self._view.pluginInput.value)
} catch (e) {
- return modal.alert('cannot parse the plugin definition to JSON')
+ return tooltip('cannot parse the plugin definition to JSON')
}
- // @TODO: BAD! REFACTOR: no module should trigger events of another modules emitter
- self._deps.righthandpanel.event.trigger('plugin-loadRequest', [json])
+ var savedPlugin = getSavedPlugin()
+ if (self._view.plugins[json.title]) return tooltip('Plugin already loaded')
+ savedPlugin[json.title] = json
+ setSavedPlugin(savedPlugin)
+ loadPlugins([json], {removable: true})
+ }
+
+ function onchangeOption (event) {
+ self._deps.config.set('settings/always-use-vm', !self._deps.config.get('settings/always-use-vm'))
}
function onswitch2darkTheme (event) {
styleGuide.switchTheme('dark')
@@ -216,79 +187,11 @@ module.exports = class SettingsTab {
styleGuide.switchTheme('light')
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) {
self._deps.config.set('settings/personal-mode', !self._deps.config.get('settings/personal-mode'))
}
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`
Select new compiler version `)
- self.data.allversions.forEach(build => self._view.versionSelector.appendChild(yo`
${build.longVersion} `))
- 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`
@@ -297,7 +200,7 @@ const css = csjs`
display: flex;
}
.info {
- ${styles.rightPanel.settingsTab.box_SolidityVersionInfo}
+ ${styles.rightPanel.settingsTab.box_SolidityVersionInfo};
margin-bottom: 1em;
word-break: break-word;
}
@@ -327,11 +230,6 @@ const css = csjs`
padding: .5em;
font-weight: bold;
}
- .select {
- font-weight: bold;
- margin-top: 1em;
- ${styles.rightPanel.settingsTab.dropdown_SelectCompiler};
- }
.heading {
margin-bottom: 0;
}
@@ -356,18 +254,48 @@ const css = csjs`
width: inherit;
display: inline-block;
}
+ .initPlugin {
+ vertical-align: top;
+ ${styles.rightPanel.settingsTab.button_initPlugin};
+ width: inherit;
+ display: block;
+ max-height: inherit;
+ padding:7px;
+ }
+
+ .removePlugin {
+ cursor: pointer;
+ }
i.warnIt {
color: ${styles.appProperties.warningText_Color};
}
.icon {
margin-right: .5em;
}
- .remixdinstallation {
- padding: 3px;
- border-radius: 2px;
- margin-left: 5px;
- }
.savegisttoken {
margin-left: 5px;
}
+ .aPlugin {
+ display: inline-block;
+ padding-left: 10px;
+ padding-top: 4px;
+ padding-bottom: 6px;
+ max-width: 100px;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ vertical-align: middle;
+ }
+ .pluginLoad {
+ vertical-align: top;
+ max-height: inherit;
+ margin: 2px;
+
+ }
+ .removePlugin{
+ padding-left: 7px;
+ padding-right: 7px;
+ border-left: 2px solid ${styles.appProperties.primary_BackgroundColor};
+ margin-left: 10px;
+ }
`
diff --git a/src/app/tabs/support-tab.js b/src/app/tabs/support-tab.js
index 042f94f29c..e98edbe56d 100644
--- a/src/app/tabs/support-tab.js
+++ b/src/app/tabs/support-tab.js
@@ -11,7 +11,7 @@ module.exports = class SupportTab {
constructor (localRegistry) {
const self = this
self.event = new EventManager()
- self._view = { el: null, gitterIframe: '' }
+ self._view = { el: null, gitterIframe: '', config: {} }
self.data = { gitterIsLoaded: false }
self._components = {}
self._components.registry = localRegistry || globalRegistry
@@ -33,6 +33,31 @@ module.exports = class SupportTab {
const self = this
if (self._view.el) return self._view.el
self._view.gitterIframe = yo`
`
+ self._view.config.remixd = yo`
+
+
Accessing local files
+
+ Remixd is a tool which allow Remix IDE to access files located in your local computer.
+ it can also be used to setup a development environment.
+
+
More infos:
+
+
+
Installation:
npm install remixd -g
+
`
+ self._view.config.localremixd = yo`
+
`
self._view.el = yo`
@@ -47,6 +72,8 @@ module.exports = class SupportTab {
${self._view.gitterIframe}
+ ${self._view.config.remixd}
+ ${self._view.config.localremixd}
`
return self._view.el
function openLink () { window.open('https://gitter.im/ethereum/remix') }
@@ -55,12 +82,13 @@ module.exports = class SupportTab {
const css = csjs`
.supportTabView {
- height: 100vh;
+ height: 100%;
padding: 2%;
padding-bottom: 3em;
display: flex;
flex-direction: column;
overflow: hidden;
+ overflow-y: auto;
}
.chat {
${styles.rightPanel.supportTab.box_IframeContainer}
@@ -102,4 +130,32 @@ const css = csjs`
.infoBox {
${styles.rightPanel.supportTab.box_SupportInfo}
}
+ .remixdinstallation {
+ padding: 3px;
+ border-radius: 2px;
+ margin-left: 5px;
+ }
+ .info {
+ ${styles.rightPanel.settingsTab.box_SolidityVersionInfo};
+ margin-top: 1em;
+ word-break: break-word;
+ }
+ .title {
+ font-size: 1.1em;
+ font-weight: bold;
+ margin-bottom: 1em;
+ }
+ .crow {
+ display: flex;
+ overflow: auto;
+ clear: both;
+ padding: .2em;
+ }
+ .crow label {
+ cursor:pointer;
+ }
+ .crowNoFlex {
+ overflow: auto;
+ clear: both;
+ }
`
diff --git a/src/app/ui/styles-guide/style-guide.js b/src/app/ui/styles-guide/style-guide.js
index 07e9899e72..9c8a1ea8d5 100644
--- a/src/app/ui/styles-guide/style-guide.js
+++ b/src/app/ui/styles-guide/style-guide.js
@@ -701,6 +701,11 @@ function styleGuide () {
BackgroundColor: appProperties.secondaryButton_BackgroundColor,
BorderColor: appProperties.secondaryButton_BorderColor,
Color: appProperties.secondaryButton_TextColor
+ }),
+ button_initPlugin: appProperties.uiElements.button({
+ BackgroundColor: appProperties.transactButton_BackgroundColor,
+ BorderColor: appProperties.transactButton_BorderColor,
+ Color: appProperties.secondaryButton_TextColor
})
},
diff --git a/src/app/ui/styles-guide/styleGuideDark.js b/src/app/ui/styles-guide/styleGuideDark.js
index 8e2ca1aa3b..adc48801f6 100644
--- a/src/app/ui/styles-guide/styleGuideDark.js
+++ b/src/app/ui/styles-guide/styleGuideDark.js
@@ -684,6 +684,18 @@ function styleGuideDark () {
BackgroundColor: appProperties.dropdown_BackgroundColor,
BorderColor: appProperties.dropdown_BorderColor,
Color: appProperties.dropdown_TextColor
+ }),
+
+ button_LoadPlugin: appProperties.uiElements.button({
+ BackgroundColor: appProperties.secondaryButton_BackgroundColor,
+ BorderColor: appProperties.secondaryButton_BorderColor,
+ Color: appProperties.secondaryButton_TextColor
+ }),
+
+ button_initPlugin: appProperties.uiElements.button({
+ BackgroundColor: appProperties.transactButton_BackgroundColor,
+ BorderColor: appProperties.transactButton_BorderColor,
+ Color: appProperties.secondaryButton_TextColor
})
},