Merge pull request #1 from ethereum/master

Sync with main repo
pull/1/head
Levi Barnes 6 years ago committed by GitHub
commit e5469454b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 48
      src/app.js
  2. 33
      src/app/contract/contractParser.js
  3. 39
      src/app/staticanalysis/staticAnalysisView.js
  4. 46
      src/app/tabs/analysis-tab.js
  5. 36
      src/app/tabs/debugger-tab.js
  6. 42
      src/app/tabs/plugin-tab.js
  7. 291
      src/app/tabs/run-tab.js
  8. 4
      src/app/tabs/runTab/model/dropdownlogic.js
  9. 7
      src/app/tabs/runTab/model/recorder.js
  10. 13
      src/app/tabs/runTab/recorder.js
  11. 12
      src/app/tabs/styles/analysis-tab-styles.js
  12. 14
      src/app/tabs/styles/debugger-tab-styles.js
  13. 15
      src/app/tabs/styles/plugin-tab-styles.js
  14. 84
      src/app/tabs/styles/support-tab-styles.js
  15. 42
      src/app/tabs/styles/tabbed-menu-styles.js
  16. 7
      src/app/tabs/styles/test-tab-styles.js
  17. 145
      src/app/tabs/support-tab.js
  18. 43
      src/app/tabs/tabbed-menu.js
  19. 45
      src/app/tabs/test-tab.js

@ -1,5 +1,6 @@
'use strict'
var $ = require('jquery')
var csjs = require('csjs-inject')
var yo = require('yo-yo')
var async = require('async')
@ -423,14 +424,53 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
let compileTab = new CompileTab(self._components.registry)
let tabs = {
compile: compileTab,
run: new RunTab(self._components.registry),
run: new RunTab(
registry.get('udapp').api,
registry.get('udappUI').api,
registry.get('config').api,
registry.get('filemanager').api,
registry.get('editor').api,
registry.get('logCallback').api,
registry.get('filepanel').api,
registry.get('pluginmanager').api,
registry.get('compilersartefacts').api
),
settings: new SettingsTab(self._components.registry),
analysis: new AnalysisTab(self._components.registry),
debug: new DebuggerTab(self._components.registry),
support: new SupportTab(self._components.registry),
analysis: new AnalysisTab(registry),
debug: new DebuggerTab(),
support: new SupportTab(),
test: new TestTab(self._components.registry, compileTab)
}
registry.get('app').api.event.register('tabChanged', (tabName) => {
if (tabName === 'Support') tabs.support.loadTab()
})
let transactionContextAPI = {
getAddress: (cb) => {
cb(null, $('#txorigin').val())
},
getValue: (cb) => {
try {
var number = document.querySelector('#value').value
var select = document.getElementById('unit')
var index = select.selectedIndex
var selectedUnit = select.querySelectorAll('option')[index].dataset.unit
var unit = 'ether' // default
if (['ether', 'finney', 'gwei', 'wei'].indexOf(selectedUnit) >= 0) {
unit = selectedUnit
}
cb(null, executionContext.web3().toWei(number, unit))
} catch (e) {
cb(e)
}
},
getGasLimit: (cb) => {
cb(null, $('#gasLimit').val())
}
}
udapp.resetAPI(transactionContextAPI)
// ---------------- Righthand-panel --------------------
self._components.righthandpanel = new RighthandPanel({ tabs, pluginManager })
self._view.rightpanel.appendChild(self._components.righthandpanel.render())

@ -1,5 +1,6 @@
'use strict'
var solcTranslate = require('solc/translate')
var remixLib = require('remix-lib')
var txHelper = remixLib.execution.txHelper
@ -42,7 +43,7 @@ var getDetails = function (contractName, contract, source) {
}
if (source && contract.assembly !== null) {
detail['Assembly'] = formatAssemblyText(contract.evm.legacyAssembly, '', source.content)
detail['Assembly'] = solcTranslate.prettyPrintLegacyAssemblyJSON(contract.evm.legacyAssembly, source.content)
}
return detail
@ -58,36 +59,6 @@ var retrieveMetadataHash = function (bytecode) {
}
}
var formatAssemblyText = function (asm, prefix, source) {
if (typeof asm === typeof '' || asm === null || asm === undefined) {
return prefix + asm + '\n'
}
var text = prefix + '.code\n'
asm['.code'].forEach(function (item, _i) {
var v = item.value === undefined ? '' : item.value
var src = ''
if (item.begin !== undefined && item.end !== undefined) {
src = source.slice(item.begin, item.end).replace('\n', '\\n', 'g')
}
if (src.length > 30) {
src = src.slice(0, 30) + '...'
}
if (item.name !== 'tag') {
text += ' '
}
text += prefix + item.name + ' ' + v + '\t\t\t' + src + '\n'
})
text += prefix + '.data\n'
let asmData = (asm['.data'] || [])
for (let i in asmData) {
let item = asmData[i]
text += ' ' + prefix + '' + i + ':\n'
text += formatAssemblyText(item, prefix + ' ', source)
}
return text
}
var gethDeploy = function (contractName, jsonInterface, bytecode) {
var code = ''
var funABI = txHelper.getConstructorInterface(jsonInterface)

@ -50,7 +50,7 @@ staticAnalysisView.prototype.render = function () {
${this.modulesView}
</div>
<div class="${css.buttons}">
<button class=${css.buttonRun} onclick=${function () { self.run() }} >Run</button>
<button class="${css.buttonRun}" onclick="${function () { self.run() }}" >Run</button>
<label class="${css.label}" for="autorunstaticanalysis">
<input id="autorunstaticanalysis"
type="checkbox"
@ -59,8 +59,8 @@ staticAnalysisView.prototype.render = function () {
>
Auto run
</label>
<label class="${css.label}" for="checkallstaticanalysis">
<input id="checkallstaticanalysis"
<label class="${css.label}" for="checkAllEntries">
<input id="checkAllEntries"
type="checkbox"
onclick="${function (event) { self.checkAll(event) }}"
style="vertical-align:bottom"
@ -135,29 +135,23 @@ staticAnalysisView.prototype.run = function () {
}
}
staticAnalysisView.prototype.checkAll = function (event) {
if (!this.view) {
return
}
var all = this.view.querySelectorAll('[name="staticanalysismodule"]')
var isAnySelected = false
for (var i = 0; i < all.length; i++) {
if (all[i].checked === true) {
isAnySelected = true
break
}
}
for (var j = 0; j < all.length; j++) {
all[j].checked = !isAnySelected
staticAnalysisView.prototype.checkModule = function (event) {
let selected = this.view.querySelectorAll('[name="staticanalysismodule"]:checked')
let checkAll = this.view.querySelector('[id="checkAllEntries"]')
if (event.target.checked) {
checkAll.checked = true
} else if (!selected.length) {
checkAll.checked = false
}
event.target.checked = !isAnySelected
}
staticAnalysisView.prototype.checkModule = function (event) {
var selectAll = this.view.querySelector('[id="checkallstaticanalysis" ]')
if (event.target.checked) {
selectAll.checked = true
staticAnalysisView.prototype.checkAll = function (event) {
if (!this.view) {
return
}
// checks/unchecks all
var checkBoxes = this.view.querySelectorAll('[name="staticanalysismodule"]')
checkBoxes.forEach((checkbox) => { checkbox.checked = event.target.checked })
}
staticAnalysisView.prototype.renderModules = function () {
@ -170,6 +164,7 @@ staticAnalysisView.prototype.renderModules = function () {
<label class="${css.label}">
<input id="staticanalysismodule_${categoryId}_${i}"
type="checkbox"
class="staticAnalysisItem"
name="staticanalysismodule"
index=${item._index}
checked="true"

@ -1,43 +1,23 @@
var yo = require('yo-yo')
var csjs = require('csjs-inject')
var StaticAnalysis = require('../staticanalysis/staticAnalysisView')
var globalRegistry = require('../../global/registry')
var EventManager = require('../../lib/events')
var css = require('./styles/analysis-tab-styles')
class AnalysisTab {
module.exports = class AnalysisTab {
constructor (localRegistry) {
const self = this
self.event = new EventManager()
self._view = { el: null }
self.data = {}
self._components = {}
self._components.registry = localRegistry || globalRegistry
self._deps = {}
constructor (registry) {
this.event = new EventManager()
this.registry = registry
}
render () {
const self = this
var staticanalysis = new StaticAnalysis()
staticanalysis.event.register('staticAnaysisWarning', (count) => {
if (count > 0) {
const msg = `Static Analysis raised ${count} warning(s) that requires your attention. Check Solidity Static Analysis Module for more information.`
const settings = { type: 'staticAnalysisWarning', useSpan: true }
self.event.trigger('newStaticAnaysisWarningMessage', [msg, settings])
}
})
self._components.registry.put({api: staticanalysis, name: 'staticanalysis'})
if (self._view.el) return self._view.el
self._view.el = yo`
<div class="${css.analysisTabView} "id="staticanalysisView">${staticanalysis.render()}</div>`
this.registry.put({api: staticanalysis, name: 'staticanalysis'})
return self._view.el
if (this.el) return this.el
this.el = yo`<div class="${css.analysisTabView} "id="staticanalysisView">${staticanalysis.render()}</div>`
return this.el
}
}
const css = csjs`
.analysisTabView {
padding: 2%;
padding-bottom: 3em;
display: flex;
flex-direction: column;
}
`
module.exports = AnalysisTab

@ -1,48 +1,26 @@
var yo = require('yo-yo')
var csjs = require('csjs-inject')
var css = require('./styles/debugger-tab-styles')
var DebuggerUI = require('../debugger/debuggerUI')
var globalRegistry = require('../../global/registry')
var EventManager = require('../../lib/events')
var styles = require('../ui/styles-guide/theme-chooser').chooser()
const css = csjs`
.debuggerTabView {
padding: 2%;
}
.debugger {
margin-bottom: 1%;
${styles.rightPanel.debuggerTab.box_Debugger}
}
`
class DebuggerTab {
constructor (localRegistry) {
const self = this
self.event = new EventManager()
self._view = { el: null }
self.data = {}
self._components = {}
self._components.registry = localRegistry || globalRegistry
constructor () {
this.el = null
}
render () {
const self = this
if (self._view.el) return self._view.el
if (this.el) return this.el
self._view.el = yo`
this.el = yo`
<div class="${css.debuggerTabView}" id="debugView">
<div id="debugger" class="${css.debugger}"></div>
</div>`
this.debuggerUI = new DebuggerUI(self._view.el.querySelector('#debugger'))
// self._view.transactionDebugger = this.debuggerUI.view()
return self._view.el
this.debuggerUI = new DebuggerUI(this.el.querySelector('#debugger'))
return this.el
}
debugger () {
// return this._view.transactionDebugger
return this.debuggerUI
}
}

@ -1,36 +1,24 @@
var yo = require('yo-yo')
var csjs = require('csjs-inject')
var css = require('./styles/plugin-tab-styles')
var globalRegistry = require('../../global/registry')
var EventManager = require('../../lib/events')
class PluginTab {
module.exports = class plugintab {
constructor (json, localRegistry) {
const self = this
self.event = new EventManager()
self._view = { el: null }
self.data = { json }
self._components = {}
self._components.registry = localRegistry || globalRegistry
constructor (json) {
this.el = null
this.data = { json }
}
render () {
const self = this
if (self._view.el) return self._view.el
self._view.el = yo`
if (this.el) return this.el
this.el = yo`
<div class="${css.pluginTabView}" id="pluginView">
<iframe class="${css.iframe}" src="${self.data.json.url}/index.html"></iframe>
<iframe class="${css.iframe}" src="${this.data.json.url}/index.html"></iframe>
</div>`
return self._view.el
return this.el
}
}
const css = csjs`
.pluginTabView {
height: 100%;
width: 100%;
}
.iframe {
height: 100%;
width: 100%;
border: 0;
}
`
module.exports = PluginTab

@ -1,8 +1,5 @@
var $ = require('jquery')
var yo = require('yo-yo')
var EventManager = require('../../lib/events')
var globlalRegistry = require('../../global/registry')
var executionContext = require('../../execution-context')
var Card = require('../ui/card')
var css = require('./styles/run-tab-styles')
@ -15,170 +12,140 @@ var ContractDropdownUI = require('./runTab/contractDropdown.js')
var Recorder = require('./runTab/model/recorder.js')
var RecorderUI = require('./runTab/recorder.js')
function runTab (opts, localRegistry) {
var self = this
self.event = new EventManager()
self._view = {}
self.data = {
count: 0,
text: `All transactions (deployed contracts and function executions) in this environment can be saved and replayed in
another environment. e.g Transactions created in Javascript VM can be replayed in the Injected Web3.`
class RunTab {
constructor (udapp, udappUI, config, fileManager, editor, logCallback, filePanel, pluginManager, compilersArtefacts) {
this.event = new EventManager()
this.renderInstanceContainer()
this.renderSettings(udapp)
this.renderDropdown(udappUI, fileManager, pluginManager, compilersArtefacts, config, editor, udapp, filePanel, logCallback)
this.renderRecorder(udapp, udappUI, fileManager, config, logCallback)
this.renderRecorderCard()
this.renderContainer()
}
self._components = {}
self._components.registry = localRegistry || globlalRegistry
self._components.transactionContextAPI = {
getAddress: (cb) => {
cb(null, $('#txorigin').val())
},
getValue: (cb) => {
try {
var number = document.querySelector('#value').value
var select = document.getElementById('unit')
var index = select.selectedIndex
var selectedUnit = select.querySelectorAll('option')[index].dataset.unit
var unit = 'ether' // default
if (['ether', 'finney', 'gwei', 'wei'].indexOf(selectedUnit) >= 0) {
unit = selectedUnit
}
cb(null, executionContext.web3().toWei(number, unit))
} catch (e) {
cb(e)
}
},
getGasLimit: (cb) => {
cb(null, $('#gasLimit').val())
}
renderContainer () {
this.container = yo`<div class="${css.runTabView}" id="runTabView" ></div>`
var el = yo`
<div>
${this.settingsUI.render()}
${this.contractDropdownUI.render()}
${this.recorderCard.render()}
${this.instanceContainer}
</div>
`
this.container.appendChild(el)
}
// dependencies
self._deps = {
udapp: self._components.registry.get('udapp').api,
udappUI: self._components.registry.get('udappUI').api,
config: self._components.registry.get('config').api,
fileManager: self._components.registry.get('filemanager').api,
editor: self._components.registry.get('editor').api,
logCallback: self._components.registry.get('logCallback').api,
filePanel: self._components.registry.get('filepanel').api,
pluginManager: self._components.registry.get('pluginmanager').api,
compilersArtefacts: self._components.registry.get('compilersartefacts').api
renderInstanceContainer () {
this.instanceContainer = yo`<div class="${css.instanceContainer}"></div>`
const instanceContainerTitle = yo`
<div class=${css.instanceContainerTitle}
title="Autogenerated generic user interfaces for interaction with deployed contracts">
Deployed Contracts
<i class="${css.clearinstance} ${css.icon} fa fa-trash" onclick=${() => this.event.trigger('clearInstance', [])}
title="Clear instances list and reset recorder" aria-hidden="true">
</i>
</div>`
this.noInstancesText = yo`
<div class="${css.noInstancesText}">
Currently you have no contract instances to interact with.
</div>`
this.event.register('clearInstance', () => {
this.instanceContainer.innerHTML = '' // clear the instances list
this.instanceContainer.appendChild(instanceContainerTitle)
this.instanceContainer.appendChild(this.noInstancesText)
})
this.instanceContainer.appendChild(instanceContainerTitle)
this.instanceContainer.appendChild(this.noInstancesText)
}
self._deps.udapp.resetAPI(self._components.transactionContextAPI)
self._view.recorderCount = yo`<span>0</span>`
self._view.instanceContainer = yo`<div class="${css.instanceContainer}"></div>`
self._view.clearInstanceElement = yo`
<i class="${css.clearinstance} ${css.icon} fa fa-trash" onclick=${() => self.event.trigger('clearInstance', [])}
title="Clear instances list and reset recorder" aria-hidden="true">
</i>`
self._view.instanceContainerTitle = yo`
<div class=${css.instanceContainerTitle}
title="Autogenerated generic user interfaces for interaction with deployed contracts">
Deployed Contracts
${self._view.clearInstanceElement}
</div>`
self._view.noInstancesText = yo`
<div class="${css.noInstancesText}">
Currently you have no contract instances to interact with.
</div>`
var container = yo`<div class="${css.runTabView}" id="runTabView" ></div>`
var recorder = new Recorder(self._deps.udapp, self._deps.fileManager, self._deps.config)
recorder.event.register('newTxRecorded', (count) => {
this.data.count = count
this._view.recorderCount.innerText = count
})
recorder.event.register('cleared', () => {
this.data.count = 0
this._view.recorderCount.innerText = 0
})
executionContext.event.register('contextChanged', recorder.clearAll.bind(recorder))
self.event.register('clearInstance', recorder.clearAll.bind(recorder))
var recorderInterface = new RecorderUI(recorder, self)
recorderInterface.render()
self._view.collapsedView = yo`
<div class=${css.recorderCollapsedView}>
<div class=${css.recorderCount}>${self._view.recorderCount}</div>
</div>`
self._view.expandedView = yo`
<div class=${css.recorderExpandedView}>
<div class=${css.recorderDescription}>
${self.data.text}
</div>
<div class="${css.transactionActions}">
${recorderInterface.recordButton}
${recorderInterface.runButton}
</div>
</div>
</div>`
self.recorderOpts = {
title: 'Transactions recorded:',
collapsedView: self._view.collapsedView
renderSettings (udapp) {
var settings = new Settings(udapp)
this.settingsUI = new SettingsUI(settings)
this.settingsUI.event.register('clearInstance', () => {
this.event.trigger('clearInstance', [])
})
}
renderDropdown (udappUI, fileManager, pluginManager, compilersArtefacts, config, editor, udapp, filePanel, logCallback) {
var dropdownLogic = new DropdownLogic(fileManager, pluginManager, compilersArtefacts, config, editor, udapp, filePanel)
this.contractDropdownUI = new ContractDropdownUI(dropdownLogic, logCallback)
this.contractDropdownUI.event.register('clearInstance', () => {
var noInstancesText = this.noInstancesText
if (noInstancesText.parentNode) { noInstancesText.parentNode.removeChild(noInstancesText) }
})
this.contractDropdownUI.event.register('newContractABIAdded', (abi, address) => {
this.instanceContainer.appendChild(udappUI.renderInstanceFromABI(abi, address, address))
})
this.contractDropdownUI.event.register('newContractInstanceAdded', (contractObject, address, value) => {
this.instanceContainer.appendChild(udappUI.renderInstance(contractObject, address, value))
})
}
var recorderCard = new Card({}, {}, self.recorderOpts)
recorderCard.event.register('expandCollapseCard', (arrow, body, status) => {
body.innerHTML = ''
status.innerHTML = ''
if (arrow === 'down') {
status.appendChild(self._view.collapsedView)
body.appendChild(self._view.expandedView)
} else if (arrow === 'up') {
status.appendChild(self._view.collapsedView)
}
})
var settings = new Settings(self._deps.udapp)
var settingsUI = new SettingsUI(settings)
self.event.register('clearInstance', () => {
this._view.instanceContainer.innerHTML = '' // clear the instances list
this._view.instanceContainer.appendChild(self._view.instanceContainerTitle)
this._view.instanceContainer.appendChild(self._view.noInstancesText)
})
settingsUI.event.register('clearInstance', () => {
this.event.trigger('clearInstance', [])
})
var dropdownLogic = new DropdownLogic(
this._deps.fileManager,
this._deps.pluginManager,
this._deps.compilersArtefacts,
this._deps.compiler,
this._deps.config,
this._deps.editor,
this._deps.udapp,
this._deps.filePanel
)
var contractDropdownUI = new ContractDropdownUI(dropdownLogic, this._deps.logCallback)
contractDropdownUI.event.register('clearInstance', () => {
var noInstancesText = this._view.noInstancesText
if (noInstancesText.parentNode) { noInstancesText.parentNode.removeChild(noInstancesText) }
})
contractDropdownUI.event.register('newContractABIAdded', (abi, address) => {
this._view.instanceContainer.appendChild(this._deps.udappUI.renderInstanceFromABI(abi, address, address))
})
contractDropdownUI.event.register('newContractInstanceAdded', (contractObject, address, value) => {
this._view.instanceContainer.appendChild(this._deps.udappUI.renderInstance(contractObject, address, value))
})
this._view.instanceContainer.appendChild(this._view.instanceContainerTitle)
this._view.instanceContainer.appendChild(this._view.noInstancesText)
var el = yo`
<div>
${settingsUI.render()}
${contractDropdownUI.render()}
${recorderCard.render()}
${self._view.instanceContainer}
</div>
`
container.appendChild(el)
return { render () { return container } }
renderRecorder (udapp, udappUI, fileManager, config, logCallback) {
this.recorderCount = yo`<span>0</span>`
var recorder = new Recorder(udapp, fileManager, config)
recorder.event.register('recorderCountChange', (count) => {
this.recorderCount.innerText = count
})
this.event.register('clearInstance', recorder.clearAll.bind(recorder))
this.recorderInterface = new RecorderUI(recorder, logCallback)
this.recorderInterface.event.register('newScenario', (abi, address, contractName) => {
var noInstancesText = this.noInstancesText
if (noInstancesText.parentNode) { noInstancesText.parentNode.removeChild(noInstancesText) }
this.instanceContainer.appendChild(udappUI.renderInstanceFromABI(abi, address, contractName))
})
this.recorderInterface.render()
}
renderRecorderCard () {
const collapsedView = yo`
<div class=${css.recorderCollapsedView}>
<div class=${css.recorderCount}>${this.recorderCount}</div>
</div>`
const expandedView = yo`
<div class=${css.recorderExpandedView}>
<div class=${css.recorderDescription}>
All transactions (deployed contracts and function executions) in this environment can be saved and replayed in
another environment. e.g Transactions created in Javascript VM can be replayed in the Injected Web3.
</div>
<div class="${css.transactionActions}">
${this.recorderInterface.recordButton}
${this.recorderInterface.runButton}
</div>
</div>
</div>`
this.recorderCard = new Card({}, {}, { title: 'Transactions recorded:', collapsedView: collapsedView })
this.recorderCard.event.register('expandCollapseCard', (arrow, body, status) => {
body.innerHTML = ''
status.innerHTML = ''
if (arrow === 'down') {
status.appendChild(collapsedView)
body.appendChild(expandedView)
} else if (arrow === 'up') {
status.appendChild(collapsedView)
}
})
}
render () {
return this.container
}
}
module.exports = runTab
module.exports = RunTab

@ -9,10 +9,9 @@ var CompilerAbstract = require('../../../compiler/compiler-abstract')
var EventManager = remixLib.EventManager
class DropdownLogic {
constructor (fileManager, pluginManager, compilersArtefacts, compiler, config, editor, udapp, filePanel) {
constructor (fileManager, pluginManager, compilersArtefacts, config, editor, udapp, filePanel) {
this.pluginManager = pluginManager
this.compilersArtefacts = compilersArtefacts
this.compiler = compiler
this.config = config
this.editor = editor
this.udapp = udapp
@ -27,6 +26,7 @@ class DropdownLogic {
})
}
// TODO: can be moved up; the event in contractDropdown will have to refactored a method instead
listenToCompilationEvents () {
this.pluginManager.event.register('sendCompilationResult', (file, source, languageVersion, data) => {
// TODO check whether the tab is configured

@ -80,6 +80,13 @@ class Recorder {
this.data._createdContracts[address] = timestamp
this.data._createdContractsReverse[timestamp] = address
})
executionContext.event.register('contextChanged', this.clearAll.bind(this))
this.event.register('newTxRecorded', (count) => {
this.event.trigger('recorderCountChange', [count])
})
this.event.register('cleared', () => {
this.event.trigger('recorderCountChange', [0])
})
}
/**

@ -1,4 +1,6 @@
var yo = require('yo-yo')
var remixLib = require('remix-lib')
var EventManager = remixLib.EventManager
var csjs = require('csjs-inject')
var css = require('../styles/run-tab-styles')
@ -8,10 +10,10 @@ var confirmDialog = require('../../execution/confirmDialog')
class RecorderUI {
constructor (recorder, parentSelf) {
constructor (recorder, logCallBack) {
this.recorder = recorder
this.parentSelf = parentSelf
this.logCallBack = this.parentSelf._deps.logCallback
this.logCallBack = logCallBack
this.event = new EventManager()
}
render () {
@ -67,10 +69,7 @@ class RecorderUI {
return modalDialogCustom.alert(error)
}
var noInstancesText = this.parentSelf._view.noInstancesText
if (noInstancesText.parentNode) { noInstancesText.parentNode.removeChild(noInstancesText) }
this.parentSelf._view.instanceContainer.appendChild(this.parentSelf._deps.udappUI.renderInstanceFromABI(abi, address, contractName))
this.event.trigger('newScenario', [abi, address, contractName])
})
}

@ -0,0 +1,12 @@
var csjs = require('csjs-inject')
const css = csjs`
.analysisTabView {
padding: 2%;
padding-bottom: 3em;
display: flex;
flex-direction: column;
}
`
module.exports = css

@ -0,0 +1,14 @@
var csjs = require('csjs-inject')
var styles = require('../../ui/styles-guide/theme-chooser').chooser()
const css = csjs`
.debuggerTabView {
padding: 2%;
}
.debugger {
margin-bottom: 1%;
${styles.rightPanel.debuggerTab.box_Debugger}
}
`
module.exports = css

@ -0,0 +1,15 @@
var csjs = require('csjs-inject')
const css = csjs`
.pluginTabView {
height: 100%;
width: 100%;
}
.iframe {
height: 100%;
width: 100%;
border: 0;
}
`
module.exports = css

@ -0,0 +1,84 @@
const csjs = require('csjs-inject')
const styles = require('../../ui/styles-guide/theme-chooser').chooser()
const css = csjs`
.supportTabView {
height: 100%;
padding: 2%;
padding-bottom: 3em;
display: flex;
flex-direction: column;
overflow: hidden;
overflow-y: auto;
}
.chat {
${styles.rightPanel.supportTab.box_IframeContainer}
display: flex;
flex-direction: column;
align-items: center;
height: 85%;
padding: 0;
}
.chatTitle {
height: 40px;
width: 90%;
display: flex;
align-items: center;
justify-content: center;
margin-top: 15px;
}
.chatTitle:hover {
cursor: pointer;
}
.icon {
height: 70%;
margin-right: 2%;
}
.chatTitleText {
font-size: 17px;
font-weight: bold;
}
.chatTitleText {
opacity: 0.8;
}
.chatIframe {
width: 100%;
height: 100%;
transform: scale(0.9);
padding: 0;
border: none;
}
.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;
}
`
module.exports = css

@ -0,0 +1,42 @@
const csjs = require('csjs-inject')
const styles = require('../../ui/styles-guide/theme-chooser').chooser()
const css = csjs`
.menu {
display: flex;
background-color: ${styles.rightPanel.BackgroundColor_Pre};
list-style: none;
margin: 0;
padding: 0;
}
.active {
background-color: ${styles.rightPanel.backgroundColor_Tab};
color: ${styles.appProperties.mainText_Color}
}
.options {
float: left;
padding-top: 0.7em;
min-width: 60px;
font-size: 0.9em;
cursor: pointer;
font-size: 1em;
text-align: center;
}
.optionViews {
background-color: ${styles.rightPanel.backgroundColor_Tab};
overflow: scroll;
height: 100%;
}
.optionViews > div {
display: none;
}
.optionViews .pre {
word-wrap: break-word;
background-color: ${styles.rightPanel.BackgroundColor_Pre};
border-radius: 3px;
display: inline-block;
padding: 0 0.6em;
}
`
module.exports = css

@ -45,6 +45,8 @@ var css = csjs`
.buttons {
${styles.rightPanel.testTab.box_listTests};
margin: 2%;
display: flex;
align-items: center;
}
.runButton {
${styles.rightPanel.testTab.button_runTests};
@ -58,6 +60,9 @@ var css = csjs`
font-weight: bold;
margin-bottom: 1em;
}
.label {
display: flex;
align-items: center;
}
`
module.exports = css

@ -1,38 +1,30 @@
const yo = require('yo-yo')
const csjs = require('csjs-inject')
var css = require('./styles/support-tab-styles')
var globalRegistry = require('../../global/registry')
const styles = require('../ui/styles-guide/theme-chooser').chooser()
class SupportTab {
var EventManager = require('../../lib/events')
module.exports = class SupportTab {
constructor (localRegistry) {
const self = this
self.event = new EventManager()
self._view = { el: null, gitterIframe: '', config: {} }
self.data = { gitterIsLoaded: false }
self._components = {}
self._components.registry = localRegistry || globalRegistry
this.el = null
this.gitterIframe = ''
this.gitterIsLoaded = false
}
self._deps = {
app: self._components.registry.get('app').api
}
loadTab () {
if (this.gitterIsLoaded) return
self._deps.app.event.register('tabChanged', (tabName) => {
if (tabName !== 'Support' || self.data.gitterIsLoaded) return
const iframe = yo`<iframe class="${css.chatIframe}" src='https://gitter.im/ethereum/remix/~embed'>`
self._view.gitterIframe.parentNode.replaceChild(iframe, self._view.gitterIframe)
self._view.gitterIframe = iframe
self._view.el.style.display = 'block'
self.data.gitterIsLoaded = true
})
const iframe = yo`<iframe class="${css.chatIframe}" src='https://gitter.im/ethereum/remix/~embed'>`
this.gitterIframe.parentNode.replaceChild(iframe, this.gitterIframe)
this.gitterIframe = iframe
this.el.style.display = 'block'
this.gitterIsLoaded = true
}
render () {
const self = this
if (self._view.el) return self._view.el
self._view.gitterIframe = yo`<div></div>`
self._view.config.remixd = yo`
if (this.el) return this.el
this.gitterIframe = yo`<div></div>`
const remixd = yo`
<div class="${css.info}">
<div class=${css.title}>Accessing local files</div>
<div class="${css.crow}">
@ -44,7 +36,8 @@ module.exports = class SupportTab {
<div class="${css.crow}"><a target="_blank" href="https://remix.readthedocs.io/en/latest/tutorial_remixd_filesystem">http://remix.readthedocs.io/en/latest/tutorial_remixd_filesystem.html</a></div>
<div class="${css.crow}">Installation: <pre class=${css.remixdinstallation}>npm install remixd -g</pre></div>
</div>`
self._view.config.localremixd = yo`
const localremixd = yo`
<div class="${css.info}">
<div class=${css.title}>Running Remix locally</div>
<div class="${css.crow}">
@ -57,7 +50,8 @@ module.exports = class SupportTab {
</div>
<a target="_blank" href="https://github.com/horizon-games/remix-app">https://github.com/horizon-games/remix-app</a>
</div>`
self._view.el = yo`
this.el = yo`
<div class="${css.supportTabView}" id="supportView">
<div class="${css.infoBox}">
Have a question, found a bug or want to propose a feature? Have a look at the
@ -66,95 +60,18 @@ module.exports = class SupportTab {
<a target="_blank" href='https://solidity.readthedocs.io/en/latest/'> Solidity</a>.
</div>
<div class="${css.chat}">
<div class="${css.chatTitle}" onclick=${openLink} title='Click to open chat in Gitter'>
<div class="${css.chatTitle}" onclick=${() => { window.open('https://gitter.im/ethereum/remix') }} title='Click to open chat in Gitter'>
<div class="${css.chatTitleText}">ethereum/remix community chat</div>
</div>
${self._view.gitterIframe}
${this.gitterIframe}
</div>
${self._view.config.remixd}
${self._view.config.localremixd}
${remixd}
${localremixd}
</div>`
return self._view.el
function openLink () { window.open('https://gitter.im/ethereum/remix') }
return this.el
}
}
const css = csjs`
.supportTabView {
height: 100%;
padding: 2%;
padding-bottom: 3em;
display: flex;
flex-direction: column;
overflow: hidden;
overflow-y: auto;
}
.chat {
${styles.rightPanel.supportTab.box_IframeContainer}
display: flex;
flex-direction: column;
align-items: center;
height: 85%;
padding: 0;
}
.chatTitle {
height: 40px;
width: 90%;
display: flex;
align-items: center;
justify-content: center;
margin-top: 15px;
}
.chatTitle:hover {
cursor: pointer;
}
.icon {
height: 70%;
margin-right: 2%;
}
.chatTitleText {
font-size: 17px;
font-weight: bold;
}
.chatTitleText {
opacity: 0.8;
}
.chatIframe {
width: 100%;
height: 100%;
transform: scale(0.9);
padding: 0;
border: none;
}
.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;
}
`
module.exports = SupportTab

@ -1,13 +1,12 @@
var yo = require('yo-yo')
var csjs = require('csjs-inject')
var css = require('./styles/tabbed-menu-styles')
var globalRegistry = require('../../global/registry')
var helper = require('../../lib/helper')
var styles = require('../ui/styles-guide/theme-chooser').chooser()
var EventManager = require('../../lib/events')
module.exports = class TabbedMenu {
class TabbedMenu {
constructor (localRegistry) {
const self = this
self.event = new EventManager()
@ -91,40 +90,4 @@ module.exports = class TabbedMenu {
}
}
const css = csjs`
.menu {
display: flex;
background-color: ${styles.rightPanel.BackgroundColor_Pre};
list-style: none;
margin: 0;
padding: 0;
}
.active {
background-color: ${styles.rightPanel.backgroundColor_Tab};
color: ${styles.appProperties.mainText_Color}
}
.options {
float: left;
padding-top: 0.7em;
min-width: 60px;
font-size: 0.9em;
cursor: pointer;
font-size: 1em;
text-align: center;
}
.optionViews {
background-color: ${styles.rightPanel.backgroundColor_Tab};
overflow: scroll;
height: 100%;
}
.optionViews > div {
display: none;
}
.optionViews .pre {
word-wrap: break-word;
background-color: ${styles.rightPanel.BackgroundColor_Pre};
border-radius: 3px;
display: inline-block;
padding: 0 0.6em;
}
`
module.exports = TabbedMenu

@ -100,8 +100,8 @@ module.exports = class TestTab {
}
self._deps.filePanel.event.register('newTestFileCreated', file => {
var testList = document.querySelector("[class^='testList']")
var test = yo`<label><input onchange=${(e) => toggleCheckbox(e, file)} type="checkbox" checked="true">${file}</label>`
var testList = self.view.querySelector("[class^='testList']")
var test = yo`<label class="singleTestLabel"><input class="singleTest" onchange=${(e) => toggleCheckbox(e.target.checked, file)} type="checkbox" checked="true">${file}</label>`
testList.appendChild(test)
self.data.allTests.push(file)
self.data.selectedTests.push(file)
@ -133,13 +133,32 @@ module.exports = class TestTab {
function listTests () {
var tests = self.data.allTests
return tests.map(test => yo`<label><input onchange =${(e) => toggleCheckbox(e, test)} type="checkbox" checked="true">${test} </label>`)
return tests.map(test => yo`<label class="singleTestLabel"><input class="singleTest" onchange =${(e) => toggleCheckbox(e.target.checked, test)} type="checkbox" checked="true">${test} </label>`)
}
function toggleCheckbox (e, test) {
var selectedTests = self.data.selectedTests
selectedTests = e.target.checked ? [...selectedTests, test] : selectedTests.filter(el => el !== test)
function toggleCheckbox (eChecked, test) {
if (!self.data.selectedTests) {
self.data.selectedTests = self._view.el.querySelectorAll('.singleTest:checked')
}
let selectedTests = self.data.selectedTests
selectedTests = eChecked ? [...selectedTests, test] : selectedTests.filter(el => el !== test)
self.data.selectedTests = selectedTests
let checkAll = self._view.el.querySelector('[id="checkAllTests"]')
if (eChecked) {
checkAll.checked = true
} else if (!selectedTests.length) {
checkAll.checked = false
}
}
function checkAll (event) {
let checkBoxes = self._view.el.querySelectorAll('.singleTest')
const checkboxesLabels = self._view.el.querySelectorAll('.singleTestLabel')
// checks/unchecks all
for (let i = 0; i < checkBoxes.length; i++) {
checkBoxes[i].checked = event.target.checked
toggleCheckbox(event.target.checked, checkboxesLabels[i].innerText)
}
}
var runTests = function () {
@ -177,12 +196,20 @@ module.exports = class TestTab {
<br/>
For more details, see
How to test smart contracts guide in our documentation.
<div class=${css.generateTestFile} onclick=${generateTestFile}>Generate test file</div>
<div class="${css.generateTestFile}" onclick="${generateTestFile}">Generate test file</div>
</div>
<div class="${css.tests}">
${self.testList}
<div class=${css.buttons}>
<div class=${css.runButton} onclick=${runTests}>Run Tests</div>
<div class="${css.buttons}">
<div class="${css.runButton}" onclick="${runTests}">Run Tests</div>
<label class="${css.label}" for="checkAllTests">
<input id="checkAllTests"
type="checkbox"
onclick="${function (event) { checkAll(event) }}"
checked="true"
>
Check/Uncheck all
</label>
</div>
${testsOutput}
${testsSummary}

Loading…
Cancel
Save