diff --git a/package.json b/package.json
index f4318b021d..897b47627e 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,7 @@
},
"devDependencies": {
"browserify": "^13.0.1",
+ "clipboard": "^1.5.12",
"ethereumjs-util": "^4.5.0",
"http-server": "^0.9.0",
"nightwatch": "^0.9.5",
diff --git a/src/code/opcodes.js b/src/code/opcodes.js
index dd51c2bb20..021a3686f3 100644
--- a/src/code/opcodes.js
+++ b/src/code/opcodes.js
@@ -102,45 +102,45 @@ var codes = {
0x7e: ['PUSH', 3, 0, 1, false],
0x7f: ['PUSH', 3, 0, 1, false],
- 0x80: ['DUP', 3, 0, 1, false],
- 0x81: ['DUP', 3, 0, 1, false],
- 0x82: ['DUP', 3, 0, 1, false],
- 0x83: ['DUP', 3, 0, 1, false],
- 0x84: ['DUP', 3, 0, 1, false],
- 0x85: ['DUP', 3, 0, 1, false],
- 0x86: ['DUP', 3, 0, 1, false],
- 0x87: ['DUP', 3, 0, 1, false],
- 0x88: ['DUP', 3, 0, 1, false],
- 0x89: ['DUP', 3, 0, 1, false],
- 0x8a: ['DUP', 3, 0, 1, false],
- 0x8b: ['DUP', 3, 0, 1, false],
- 0x8c: ['DUP', 3, 0, 1, false],
- 0x8d: ['DUP', 3, 0, 1, false],
- 0x8e: ['DUP', 3, 0, 1, false],
- 0x8f: ['DUP', 3, 0, 1, false],
-
- 0x90: ['SWAP', 3, 0, 0, false],
- 0x91: ['SWAP', 3, 0, 0, false],
- 0x92: ['SWAP', 3, 0, 0, false],
- 0x93: ['SWAP', 3, 0, 0, false],
- 0x94: ['SWAP', 3, 0, 0, false],
- 0x95: ['SWAP', 3, 0, 0, false],
- 0x96: ['SWAP', 3, 0, 0, false],
- 0x97: ['SWAP', 3, 0, 0, false],
- 0x98: ['SWAP', 3, 0, 0, false],
- 0x99: ['SWAP', 3, 0, 0, false],
- 0x9a: ['SWAP', 3, 0, 0, false],
- 0x9b: ['SWAP', 3, 0, 0, false],
- 0x9c: ['SWAP', 3, 0, 0, false],
- 0x9d: ['SWAP', 3, 0, 0, false],
- 0x9e: ['SWAP', 3, 0, 0, false],
- 0x9f: ['SWAP', 3, 0, 0, false],
-
- 0xa0: ['LOG', 375, 2, 0, false],
- 0xa1: ['LOG', 375, 3, 0, false],
- 0xa2: ['LOG', 375, 4, 0, false],
- 0xa3: ['LOG', 375, 5, 0, false],
- 0xa4: ['LOG', 375, 6, 0, false],
+ 0x80: ['DUP1', 3, 0, 1, false],
+ 0x81: ['DUP2', 3, 0, 1, false],
+ 0x82: ['DUP3', 3, 0, 1, false],
+ 0x83: ['DUP4', 3, 0, 1, false],
+ 0x84: ['DUP5', 3, 0, 1, false],
+ 0x85: ['DUP6', 3, 0, 1, false],
+ 0x86: ['DUP7', 3, 0, 1, false],
+ 0x87: ['DUP8', 3, 0, 1, false],
+ 0x88: ['DUP9', 3, 0, 1, false],
+ 0x89: ['DUP10', 3, 0, 1, false],
+ 0x8a: ['DUP11', 3, 0, 1, false],
+ 0x8b: ['DUP12', 3, 0, 1, false],
+ 0x8c: ['DUP13', 3, 0, 1, false],
+ 0x8d: ['DUP14', 3, 0, 1, false],
+ 0x8e: ['DUP15', 3, 0, 1, false],
+ 0x8f: ['DUP16', 3, 0, 1, false],
+
+ 0x90: ['SWAP1', 3, 0, 0, false],
+ 0x91: ['SWAP2', 3, 0, 0, false],
+ 0x92: ['SWAP3', 3, 0, 0, false],
+ 0x93: ['SWAP4', 3, 0, 0, false],
+ 0x94: ['SWAP5', 3, 0, 0, false],
+ 0x95: ['SWAP6', 3, 0, 0, false],
+ 0x96: ['SWAP7', 3, 0, 0, false],
+ 0x97: ['SWAP8', 3, 0, 0, false],
+ 0x98: ['SWAP9', 3, 0, 0, false],
+ 0x99: ['SWAP10', 3, 0, 0, false],
+ 0x9a: ['SWAP11', 3, 0, 0, false],
+ 0x9b: ['SWAP12', 3, 0, 0, false],
+ 0x9c: ['SWAP13', 3, 0, 0, false],
+ 0x9d: ['SWAP14', 3, 0, 0, false],
+ 0x9e: ['SWAP15', 3, 0, 0, false],
+ 0x9f: ['SWAP16', 3, 0, 0, false],
+
+ 0xa0: ['LOG0', 375, 2, 0, false],
+ 0xa1: ['LOG1', 375, 3, 0, false],
+ 0xa2: ['LOG2', 375, 4, 0, false],
+ 0xa3: ['LOG3', 375, 5, 0, false],
+ 0xa4: ['LOG4', 375, 6, 0, false],
// '0xf0' range - closures
0xf0: ['CREATE', 32000, 3, 1, true],
diff --git a/src/helpers/traceHelper.js b/src/helpers/traceHelper.js
index 4243cbd17a..dee13c88e9 100644
--- a/src/helpers/traceHelper.js
+++ b/src/helpers/traceHelper.js
@@ -25,6 +25,10 @@ module.exports = {
return step.op === 'RETURN'
},
+ isStopInstruction: function (step) {
+ return step.op === 'STOP'
+ },
+
isSSTOREInstruction: function (step) {
return step.op === 'SSTORE'
},
diff --git a/src/helpers/ui.js b/src/helpers/ui.js
index acdf14f5d5..2860d2da44 100644
--- a/src/helpers/ui.js
+++ b/src/helpers/ui.js
@@ -1,7 +1,7 @@
'use strict'
module.exports = {
formatMemory: function (mem, width) {
- var ret = ''
+ var ret = {}
if (!mem) {
return ret
}
@@ -13,7 +13,7 @@ module.exports = {
for (var k = 0; k < mem.length; k += (width * 2)) {
var memory = mem.substr(k, width * 2)
var content = this.tryConvertAsciiFormat(memory)
- ret += '0x' + (k / 2).toString(16) + '\t\t' + content.raw + '\t' + content.ascii + '\n'
+ ret['0x' + (k / 2).toString(16)] = content.raw + '\t' + content.ascii
}
return ret
},
@@ -51,5 +51,9 @@ module.exports = {
}
hex = hex.replace(/^0+/, '')
return '0x' + hex
+ },
+
+ runInBrowser: function () {
+ return typeof window !== 'undefined'
}
}
diff --git a/src/trace/traceAnalyser.js b/src/trace/traceAnalyser.js
index fbeafabb4e..cdc3839545 100644
--- a/src/trace/traceAnalyser.js
+++ b/src/trace/traceAnalyser.js
@@ -118,7 +118,7 @@ TraceAnalyser.prototype.buildDepth = function (index, step, tx, callStack, conte
this.traceCache.pushSteps(index, context.currentCallIndex)
context.lastCallIndex = context.currentCallIndex
context.currentCallIndex = 0
- } else if (traceHelper.isReturnInstruction(step)) {
+ } else if (traceHelper.isReturnInstruction(step) || traceHelper.isStopInstruction(step)) {
if (index + 1 < this.trace.length) {
callStack.pop()
this.traceCache.pushCallChanges(step, index + 1)
diff --git a/src/trace/traceManager.js b/src/trace/traceManager.js
index 2be9a48c1c..56e535efc0 100644
--- a/src/trace/traceManager.js
+++ b/src/trace/traceManager.js
@@ -222,7 +222,11 @@ TraceManager.prototype.getReturnValue = function (stepIndex, callback) {
if (check) {
return callback(check, null)
}
- callback(null, this.traceCache.returnValues[stepIndex])
+ if (!this.traceCache.returnValues[stepIndex]) {
+ callback('current step is not a return step')
+ } else {
+ callback(null, this.traceCache.returnValues[stepIndex])
+ }
}
TraceManager.prototype.getCurrentStep = function (stepIndex, callback) {
diff --git a/src/ui/ASMCode.js b/src/ui/ASMCode.js
deleted file mode 100644
index c53fe59453..0000000000
--- a/src/ui/ASMCode.js
+++ /dev/null
@@ -1,55 +0,0 @@
-'use strict'
-var style = require('./styles/basicStyles')
-var yo = require('yo-yo')
-var ui = require('../helpers/ui')
-
-function ASMCode (_parent, _codeManager) {
- this.parent = _parent
- this.codeManager = _codeManager
- this.code
- this.address
- this.codeView
-
- this.init()
-}
-
-ASMCode.prototype.render = function () {
- var view = (
- yo``
- )
- if (!this.view) {
- this.view = view
- }
- return view
-}
-
-ASMCode.prototype.init = function () {
- this.codeManager.register('changed', this, this.changed)
-}
-
-ASMCode.prototype.indexChanged = function (index) {
- document.getElementById('asmitems').value = index
-}
-
-ASMCode.prototype.changed = function (code, address, index) {
- if (this.address !== address) {
- this.code = code
- this.address = address
- this.renderAssemblyItems()
- yo.update(this.view, this.render())
- }
- this.indexChanged(index)
-}
-
-ASMCode.prototype.renderAssemblyItems = function () {
- if (this.code) {
- this.codeView = this.code.map(function (item, i) {
- return yo``
- })
- return this.codeView
- }
-}
-
-module.exports = ASMCode
diff --git a/src/ui/ButtonNavigator.js b/src/ui/ButtonNavigator.js
index 8a60f1a861..570010e304 100644
--- a/src/ui/ButtonNavigator.js
+++ b/src/ui/ButtonNavigator.js
@@ -1,6 +1,8 @@
'use strict'
var util = require('../helpers/global')
var EventManager = require('../lib/eventManager')
+var style = require('./styles/basicStyles')
+var ui = require('../helpers/ui')
var yo = require('yo-yo')
function ButtonNavigator (_traceManager) {
@@ -21,19 +23,19 @@ module.exports = ButtonNavigator
ButtonNavigator.prototype.render = function () {
var self = this
var view = yo`
-
`
diff --git a/src/ui/CalldataPanel.js b/src/ui/CalldataPanel.js
index e798ebb0f3..fdd0c43e43 100644
--- a/src/ui/CalldataPanel.js
+++ b/src/ui/CalldataPanel.js
@@ -1,11 +1,11 @@
'use strict'
-var BasicPanel = require('./BasicPanel')
+var DropdownPanel = require('./DropdownPanel')
var yo = require('yo-yo')
function CalldataPanel (_parent, _traceManager) {
this.parent = _parent
this.traceManager = _traceManager
- this.basicPanel = new BasicPanel('Call Data')
+ this.basicPanel = new DropdownPanel('Call Data')
this.init()
}
@@ -21,22 +21,14 @@ CalldataPanel.prototype.init = function () {
self.traceManager.getCallDataAt(index, function (error, calldata) {
if (error) {
- self.basicPanel.data = ''
+ self.basicPanel.data = {}
console.log(error)
} else if (self.parent.currentStepIndex === index) {
- self.basicPanel.data = self.format(calldata)
+ self.basicPanel.data = calldata
}
self.basicPanel.update()
})
})
}
-CalldataPanel.prototype.format = function (calldata) {
- var ret = ''
- for (var key in calldata) {
- ret += calldata[key] + '\n'
- }
- return ret
-}
-
module.exports = CalldataPanel
diff --git a/src/ui/CallstackPanel.js b/src/ui/CallstackPanel.js
index 31e38361dc..89b0821074 100644
--- a/src/ui/CallstackPanel.js
+++ b/src/ui/CallstackPanel.js
@@ -1,11 +1,11 @@
'use strict'
-var BasicPanel = require('./BasicPanel')
+var DropdownPanel = require('./DropdownPanel')
var yo = require('yo-yo')
function CallstackPanel (_parent, _traceManager) {
this.parent = _parent
this.traceManager = _traceManager
- this.basicPanel = new BasicPanel('Call Stack')
+ this.basicPanel = new DropdownPanel('Call Stack')
this.init()
}
@@ -22,21 +22,13 @@ CallstackPanel.prototype.init = function () {
self.traceManager.getCallStackAt(index, function (error, callstack) {
if (error) {
console.log(error)
- self.basicPanel.data = ''
+ self.basicPanel.data = {}
} else if (self.parent.currentStepIndex === index) {
- self.basicPanel.data = self.format(callstack)
+ self.basicPanel.data = callstack
}
self.basicPanel.update()
})
})
}
-CallstackPanel.prototype.format = function (callstack) {
- var ret = ''
- for (var key in callstack) {
- ret += callstack[key] + '\n'
- }
- return ret
-}
-
module.exports = CallstackPanel
diff --git a/src/ui/DropdownPanel.js b/src/ui/DropdownPanel.js
new file mode 100644
index 0000000000..bff418f4da
--- /dev/null
+++ b/src/ui/DropdownPanel.js
@@ -0,0 +1,78 @@
+'use strict'
+var yo = require('yo-yo')
+var ui = require('../helpers/ui')
+var styleDropdown = require('./styles/dropdownPanel')
+var style = require('./styles/basicStyles')
+var basicStyles = require('./styles/basicStyles')
+var Clipboard
+if (ui.runInBrowser()) {
+ Clipboard = require('clipboard')
+}
+
+function DropdownPanel (_name, _raw) {
+ this.data
+ this.name = _name
+ this.view
+ this.clipboard
+ _raw = _raw === undefined ? false : _raw
+ this.raw = _raw
+}
+
+DropdownPanel.prototype.update = function () {
+ this.view.querySelector('.dropdownpanel div').innerHTML = ''
+ if (!this.raw) {
+ var data = JSON.stringify(this.data, null, '\t')
+ if (!this.data || data === '[]' || data === '{}') {
+ this.data = ['Empty']
+ }
+ var div = document.createElement('div')
+ if (Array.isArray(this.data)) {
+ this.data.map(function (item, i) {
+ div.appendChild(yo`${item}
`)
+ })
+ } else {
+ for (var k in this.data) {
+ div.appendChild(yo``)
+ }
+ }
+ this.view.querySelector('.dropdownpanel div').appendChild(div)
+ this.view.querySelector('.btn').setAttribute('data-clipboard-text', data)
+ if (Clipboard && !this.clipboard) {
+ this.clipboard = new Clipboard(this.view.querySelector('.btn'))
+ }
+ } else {
+ this.view.querySelector('.dropdownpanel div').appendChild(this.data)
+ this.view.querySelector('.btn').style.display = 'none'
+ }
+}
+
+DropdownPanel.prototype.render = function (overridestyle) {
+ overridestyle === undefined ? {} : overridestyle
+ var self = this
+ var view = yo`
+
+
+
+ Copy to clipboard
+
+
Empty
+
+
`
+ if (!this.view) {
+ this.view = view
+ }
+ return view
+}
+
+DropdownPanel.prototype.toggle = function () {
+ var el = this.view.querySelector('.dropdownpanel')
+ if (el.style.display === '') {
+ el.style.display = 'none'
+ } else {
+ el.style.display = ''
+ }
+}
+
+module.exports = DropdownPanel
diff --git a/src/ui/Ethdebugger.js b/src/ui/Ethdebugger.js
index 84e4f70e3f..bc7d20404d 100644
--- a/src/ui/Ethdebugger.js
+++ b/src/ui/Ethdebugger.js
@@ -3,7 +3,6 @@ var TxBrowser = require('./TxBrowser')
var StepManager = require('./StepManager')
var TraceManager = require('../trace/traceManager')
var VmDebugger = require('./VmDebugger')
-var Sticker = require('./Sticker')
var style = require('./styles/basicStyles')
var util = require('../helpers/global')
var EventManager = require('../lib/eventManager')
@@ -49,7 +48,6 @@ function Ethdebugger () {
self.stepChanged(stepIndex)
})
this.vmDebugger = new VmDebugger(this, this.traceManager, this.codeManager)
- this.sticker = new Sticker(this, this.traceManager)
}
Ethdebugger.prototype.web3 = function () {
@@ -83,14 +81,10 @@ Ethdebugger.prototype.debug = function (tx) {
Ethdebugger.prototype.render = function () {
var view = yo`
-
VM Debugger
-
+
${this.txBrowser.render()}
${this.stepManager.render()}
-
- ${this.sticker.render()}
-
${this.statusMessage}
${this.vmDebugger.render()}
`
@@ -121,7 +115,7 @@ Ethdebugger.prototype.startDebugging = function (blockNumber, txIndex, tx) {
this.tx = tx
var self = this
this.traceManager.resolveTrace(tx, function (error, result) {
- console.log('trace loaded ' + result + ' ' + error)
+ console.log('trace loaded ' + result)
if (result) {
self.statusMessage = ''
yo.update(self.view, self.render())
diff --git a/src/ui/FullStoragesChanges.js b/src/ui/FullStoragesChanges.js
index 3ddf9f0dbb..d78847d0fe 100644
--- a/src/ui/FullStoragesChanges.js
+++ b/src/ui/FullStoragesChanges.js
@@ -1,5 +1,5 @@
'use strict'
-var BasicPanel = require('./BasicPanel')
+var DropdownPanel = require('./DropdownPanel')
var yo = require('yo-yo')
function FullStoragesChanges (_parent, _traceManager) {
@@ -8,7 +8,7 @@ function FullStoragesChanges (_parent, _traceManager) {
this.addresses = []
this.view
this.traceLength
- this.basicPanel = new BasicPanel('Full Storages Changes', '1205px', '100px')
+ this.basicPanel = new DropdownPanel('Full Storages Changes')
this.init()
}
@@ -20,14 +20,6 @@ FullStoragesChanges.prototype.render = function () {
return view
}
-FullStoragesChanges.prototype.hide = function () {
- this.view.style.display = 'none'
-}
-
-FullStoragesChanges.prototype.show = function () {
- this.view.style.display = 'block'
-}
-
FullStoragesChanges.prototype.init = function () {
var self = this
this.parent.register('newTraceLoaded', this, function (length) {
@@ -35,9 +27,8 @@ FullStoragesChanges.prototype.init = function () {
self.traceManager.getAddresses(function (error, addresses) {
if (!error) {
self.addresses = addresses
- self.basicPanel.data = ''
- yo.update(self.view, self.render())
- self.hide()
+ self.basicPanel.data = {}
+ self.basicPanel.update()
}
})
@@ -58,14 +49,11 @@ FullStoragesChanges.prototype.init = function () {
self.traceManager.getStorageAt(index, null, function (error, result) {
if (!error) {
storageJSON[self.addresses[k]] = result
- self.basicPanel.data = JSON.stringify(storageJSON, null, '\t')
- yo.update(self.view, self.render())
- self.show()
+ self.basicPanel.data = storageJSON
+ self.basicPanel.update()
}
}, self.addresses[k])
}
- } else {
- self.hide()
}
})
}
diff --git a/src/ui/ListView.js b/src/ui/ListView.js
new file mode 100644
index 0000000000..89a364d48b
--- /dev/null
+++ b/src/ui/ListView.js
@@ -0,0 +1,65 @@
+'use strict'
+var style = require('./styles/basicStyles')
+var yo = require('yo-yo')
+var ui = require('../helpers/ui')
+var DropdownPanel = require('./DropdownPanel')
+
+function ListView (_parent, _codeManager) {
+ this.parent = _parent
+ this.codeManager = _codeManager
+ this.code
+ this.address
+ this.codeView
+ this.itemSelected
+ this.basicPanel = new DropdownPanel('Assembly', true)
+ this.init()
+}
+
+ListView.prototype.render = function () {
+ return yo`
${this.basicPanel.render({height: style.instructionsList.height})}
`
+}
+
+ListView.prototype.init = function () {
+ var self = this
+ this.codeManager.register('changed', this, this.changed)
+ this.parent.register('traceUnloaded', this, function () {
+ self.changed([], '', -1)
+ })
+}
+
+ListView.prototype.indexChanged = function (index) {
+ if (index >= 0) {
+ if (this.itemSelected) {
+ this.itemSelected.removeAttribute('style')
+ this.itemSelected.firstChild.removeAttribute('style')
+ }
+ this.itemSelected = this.codeView.children[index]
+ this.itemSelected.setAttribute('style', ui.formatCss({'background-color': '#eeeeee'}))
+ this.itemSelected.firstChild.setAttribute('style', ui.formatCss({'margin-left': '2px'}))
+ this.codeView.scrollTop = this.itemSelected.offsetTop - parseInt(this.codeView.style.height.replace('px', ''))
+ }
+}
+
+ListView.prototype.changed = function (code, address, index) {
+ if (this.address !== address) {
+ this.code = code
+ this.address = address
+ this.codeView = this.renderAssemblyItems()
+ this.basicPanel.data = this.codeView
+ this.basicPanel.update()
+ }
+ this.indexChanged(index)
+}
+
+ListView.prototype.renderAssemblyItems = function () {
+ if (this.code) {
+ var codeView = this.code.map(function (item, i) {
+ return yo`
${item}`
+ })
+ return yo`
`
+ }
+}
+
+module.exports = ListView
diff --git a/src/ui/MemoryPanel.js b/src/ui/MemoryPanel.js
index 0a7e6a8ef7..369d0cc63b 100644
--- a/src/ui/MemoryPanel.js
+++ b/src/ui/MemoryPanel.js
@@ -1,12 +1,12 @@
'use strict'
-var BasicPanel = require('./BasicPanel')
+var DropdownPanel = require('./DropdownPanel')
var util = require('../helpers/ui')
var yo = require('yo-yo')
function MemoryPanel (_parent, _traceManager) {
this.parent = _parent
this.traceManager = _traceManager
- this.basicPanel = new BasicPanel('Memory')
+ this.basicPanel = new DropdownPanel('Memory')
this.init()
}
@@ -23,7 +23,7 @@ MemoryPanel.prototype.init = function () {
self.traceManager.getMemoryAt(index, function (error, memory) {
if (error) {
console.log(error)
- self.basicPanel.data = ''
+ self.basicPanel.data = {}
} else if (self.parent.currentStepIndex === index) {
self.basicPanel.data = util.formatMemory(memory, 16)
}
diff --git a/src/ui/StackPanel.js b/src/ui/StackPanel.js
index 956ea1fb65..e2afa43e23 100644
--- a/src/ui/StackPanel.js
+++ b/src/ui/StackPanel.js
@@ -1,12 +1,12 @@
'use strict'
-var BasicPanel = require('./BasicPanel')
+var DropdownPanel = require('./DropdownPanel')
var ui = require('../helpers/ui')
var yo = require('yo-yo')
function StackPanel (_parent, _traceManager) {
this.parent = _parent
this.traceManager = _traceManager
- this.basicPanel = new BasicPanel('Stack')
+ this.basicPanel = new DropdownPanel('Stack')
this.init()
}
@@ -22,7 +22,7 @@ StackPanel.prototype.init = function () {
self.traceManager.getStackAt(index, function (error, stack) {
if (error) {
- self.basicPanel.data = ''
+ self.basicPanel.data = {}
console.log(error)
} else if (self.parent.currentStepIndex === index) {
self.basicPanel.data = self.format(stack)
@@ -33,10 +33,10 @@ StackPanel.prototype.init = function () {
}
StackPanel.prototype.format = function (stack) {
- var ret = ''
+ var ret = []
for (var key in stack) {
var hex = ui.normalizeHex(stack[key])
- ret += hex + '\n'
+ ret.push(hex)
}
return ret
}
diff --git a/src/ui/StepDetail.js b/src/ui/StepDetail.js
new file mode 100644
index 0000000000..b0bc4f04a4
--- /dev/null
+++ b/src/ui/StepDetail.js
@@ -0,0 +1,105 @@
+'use strict'
+var yo = require('yo-yo')
+var DropdownPanel = require('./DropdownPanel')
+
+function StepDetail (_parent, _traceManager) {
+ this.parent = _parent
+ this.traceManager = _traceManager
+
+ this.basicPanel = new DropdownPanel('Step detail')
+
+ this.detail = initDetail()
+ this.view
+ this.init()
+}
+
+StepDetail.prototype.render = function () {
+ return yo`
${this.basicPanel.render()}
`
+}
+
+StepDetail.prototype.init = function () {
+ var self = this
+ this.parent.register('traceUnloaded', this, function () {
+ self.detail = initDetail()
+ self.basicPanel.update()
+ })
+
+ this.parent.register('newTraceLoaded', this, function () {
+ self.detail = initDetail()
+ self.basicPanel.update()
+ })
+
+ this.parent.register('indexChanged', this, function (index) {
+ if (index < 0) return
+
+ self.detail.vmTraceStep = index
+
+ self.traceManager.getCurrentStep(index, function (error, step) {
+ if (error) {
+ console.log(error)
+ self.detail.step = '-'
+ } else {
+ self.detail.step = step
+ }
+ self.basicPanel.data = self.detail
+ self.basicPanel.update()
+ })
+
+ self.traceManager.getMemExpand(index, function (error, addmem) {
+ if (error) {
+ console.log(error)
+ self.detail.addmemory = '-'
+ } else {
+ self.detail.addmemory = addmem
+ }
+ self.basicPanel.data = self.detail
+ self.basicPanel.update()
+ })
+
+ self.traceManager.getStepCost(index, function (error, gas) {
+ if (error) {
+ console.log(error)
+ self.detail.gas = '-'
+ } else {
+ self.detail.gas = gas
+ }
+ self.basicPanel.data = self.detail
+ self.basicPanel.update()
+ })
+
+ self.traceManager.getCurrentCalledAddressAt(index, function (error, address) {
+ if (error) {
+ console.log(error)
+ self.detail.loadedAddress = '-'
+ } else {
+ self.detail.loadedAddress = address
+ }
+ self.basicPanel.data = self.detail
+ self.basicPanel.update()
+ })
+
+ self.traceManager.getRemainingGas(index, function (error, remaingas) {
+ if (error) {
+ console.log(error)
+ self.detail.remainingGas = '-'
+ } else {
+ self.detail.remainingGas = remaingas
+ }
+ self.basicPanel.data = self.detail
+ self.basicPanel.update()
+ })
+ })
+}
+
+module.exports = StepDetail
+
+function initDetail () {
+ return {
+ vmTraceStep: '-',
+ step: '-',
+ addmemory: '',
+ gas: '',
+ remainingGas: '-',
+ loadedAddress: '-'
+ }
+}
diff --git a/src/ui/StepManager.js b/src/ui/StepManager.js
index bb7763e824..bcb3c6089c 100644
--- a/src/ui/StepManager.js
+++ b/src/ui/StepManager.js
@@ -1,11 +1,9 @@
'use strict'
var ButtonNavigator = require('./ButtonNavigator')
var Slider = require('./Slider')
-var style = require('./styles/basicStyles')
var util = require('../helpers/global')
var EventManager = require('../lib/eventManager')
var yo = require('yo-yo')
-var ui = require('../helpers/ui')
function StepManager (_parent, _traceManager) {
util.extend(this, new EventManager())
@@ -49,7 +47,7 @@ function StepManager (_parent, _traceManager) {
StepManager.prototype.render = function () {
return (
- yo`
+ yo`
${this.slider.render()}
${this.buttonNavigator.render()}
`
diff --git a/src/ui/Sticker.js b/src/ui/Sticker.js
deleted file mode 100644
index e32f76b11d..0000000000
--- a/src/ui/Sticker.js
+++ /dev/null
@@ -1,150 +0,0 @@
-'use strict'
-var yo = require('yo-yo')
-
-function Sticker (_parent, _traceManager) {
- this.parent = _parent
- this.traceManager = _traceManager
-
- this.vmTraceStep = '-'
- this.step = '-'
- this.addmemory = '-'
- this.gas = '-'
- this.remainingGas = '-'
- this.loadedAddress = '-'
- this.hide = true
-
- this.view
- this.init()
-}
-
-Sticker.prototype.render = function () {
- var view = yo`
-
-
-
-
- VMtracestep:
- |
-
- ${this.vmTraceStep}
- |
-
-
-
- Step:
- |
-
- ${this.step}
- |
-
-
-
- Add memory:
- |
-
- ${this.addmemory}
- |
-
-
-
- Gas:
- |
-
- ${this.gas}
- |
-
-
-
- Remaining gas:
- |
-
- ${this.remainingGas}
- |
-
-
-
- Loaded address:
- |
-
- ${this.loadedAddress}
- |
-
-
-
-
`
- if (!this.view) {
- this.view = view
- }
- return view
-}
-
-Sticker.prototype.init = function () {
- var self = this
- this.parent.register('traceUnloaded', this, function () {
- self.hide = true
- yo.update(self.view, self.render())
- })
-
- this.parent.register('newTraceLoaded', this, function () {
- self.hide = false
- yo.update(self.view, self.render())
- })
-
- this.parent.register('indexChanged', this, function (index) {
- if (index < 0) return
-
- self.vmTraceStep = index
-
- self.traceManager.getCurrentStep(index, function (error, step) {
- if (error) {
- console.log(error)
- self.step = '-'
- } else {
- self.step = step
- }
- yo.update(self.view, self.render())
- })
-
- self.traceManager.getMemExpand(index, function (error, addmem) {
- if (error) {
- console.log(error)
- self.addmemory = '-'
- } else {
- self.addmemory = addmem
- }
- yo.update(self.view, self.render())
- })
-
- self.traceManager.getStepCost(index, function (error, gas) {
- if (error) {
- console.log(error)
- self.gas = '-'
- } else {
- self.gas = gas
- }
- yo.update(self.view, self.render())
- })
-
- self.traceManager.getCurrentCalledAddressAt(index, function (error, address) {
- if (error) {
- console.log(error)
- self.loadedAddress = '-'
- } else {
- self.loadedAddress = address
- }
- yo.update(self.view, self.render())
- })
-
- self.traceManager.getRemainingGas(index, function (error, remaingas) {
- if (error) {
- console.log(error)
- self.remainingGas = '-'
- } else {
- self.remainingGas = remaingas
- }
- yo.update(self.view, self.render())
- })
- })
-}
-
-module.exports = Sticker
diff --git a/src/ui/StoragePanel.js b/src/ui/StoragePanel.js
index abe41e5b73..d4fde442d3 100644
--- a/src/ui/StoragePanel.js
+++ b/src/ui/StoragePanel.js
@@ -1,11 +1,11 @@
'use strict'
-var BasicPanel = require('./BasicPanel')
+var DropdownPanel = require('./DropdownPanel')
var yo = require('yo-yo')
function StoragePanel (_parent, _traceManager, _address) {
this.parent = _parent
this.traceManager = _traceManager
- this.basicPanel = new BasicPanel('Storage Changes')
+ this.basicPanel = new DropdownPanel('Storage Changes')
this.address = _address
this.init()
this.disabled = false
@@ -25,21 +25,13 @@ StoragePanel.prototype.init = function () {
self.traceManager.getStorageAt(index, self.parent.tx, function (error, storage) {
if (error) {
console.log(error)
- self.basicPanel.data = self.formatStorage(storage)
+ self.basicPanel.data = {}
} else if (self.parent.currentStepIndex === index) {
- self.basicPanel.data = self.formatStorage(storage)
+ self.basicPanel.data = storage
}
self.basicPanel.update()
}, self.address)
})
}
-StoragePanel.prototype.formatStorage = function (storage) {
- var ret = ''
- for (var key in storage) {
- ret += key + ' ' + storage[key] + '\n'
- }
- return ret
-}
-
module.exports = StoragePanel
diff --git a/src/ui/TxBrowser.js b/src/ui/TxBrowser.js
index a4d18413f9..6362d228ea 100644
--- a/src/ui/TxBrowser.js
+++ b/src/ui/TxBrowser.js
@@ -5,17 +5,17 @@ var traceHelper = require('../helpers/traceHelper')
var yo = require('yo-yo')
var ui = require('../helpers/ui')
var init = require('../helpers/init')
+var DropdownPanel = require('./DropdownPanel')
function TxBrowser (_parent) {
util.extend(this, new EventManager())
this.blockNumber
this.txNumber
- this.hash
- this.from
- this.to
this.view
this.displayConnectionSetting = true
+ this.basicPanel = new DropdownPanel('Transaction')
+ this.basicPanel.data = {}
var self = this
_parent.register('providerChanged', this, function (provider) {
self.displayConnectionSetting = provider === 'INTERNAL'
@@ -33,12 +33,11 @@ function TxBrowser (_parent) {
// invokation: 0x20ef65b8b186ca942fcccd634f37074dde49b541c27994fc7596740ef44cfd51
TxBrowser.prototype.setDefaultValues = function () {
- this.from = ' - '
- this.to = ' - '
- this.hash = ' - '
this.blockNumber = null
this.txNumber = ''
this.connectInfo = ''
+ this.basicPanel.data = {}
+ this.basicPanel.update()
this.updateWeb3Url(util.web3.currentProvider.host)
}
@@ -57,23 +56,24 @@ TxBrowser.prototype.submit = function () {
} catch (e) {
console.log(e)
}
- console.log(JSON.stringify(tx))
+ var info = {}
if (tx) {
if (!tx.to) {
tx.to = traceHelper.contractCreationToken('0')
}
- this.from = tx.from
- this.to = tx.to
- this.hash = tx.hash
+ info.from = tx.from
+ info.to = tx.to
+ info.hash = tx.hash
this.trigger('newTraceRequested', [this.blockNumber, this.txNumber, tx])
} else {
var mes = '
'
- this.from = mes
- this.to = mes
- this.hash = mes
+ info.from = mes
+ info.to = mes
+ info.hash = mes
console.log('cannot find ' + this.blockNumber + ' ' + this.txNumber)
}
- yo.update(this.view, this.render())
+ this.basicPanel.data = info
+ this.basicPanel.update()
}
TxBrowser.prototype.updateWeb3Url = function (newhost) {
@@ -110,13 +110,16 @@ TxBrowser.prototype.updateTxN = function (ev) {
TxBrowser.prototype.load = function (txHash) {
this.txNumber = txHash
- yo.update(this.view, this.render())
this.submit()
}
+TxBrowser.prototype.unload = function (txHash) {
+ this.trigger('unloadRequested')
+ this.init()
+}
+
TxBrowser.prototype.init = function (ev) {
this.setDefaultValues()
- yo.update(this.view, this.render())
}
TxBrowser.prototype.connectionSetting = function () {
@@ -131,43 +134,16 @@ TxBrowser.prototype.connectionSetting = function () {
TxBrowser.prototype.render = function () {
var self = this
- var view = yo`
+ var view = yo`
`
if (!this.view) {
diff --git a/src/ui/VmDebugger.js b/src/ui/VmDebugger.js
index e8236ab2ae..08a5a05210 100644
--- a/src/ui/VmDebugger.js
+++ b/src/ui/VmDebugger.js
@@ -1,39 +1,36 @@
'use strict'
-var style = require('./styles/basicStyles')
-var ASMCode = require('./ASMCode')
+var ListView = require('./ListView')
var CalldataPanel = require('./CalldataPanel')
var MemoryPanel = require('./MemoryPanel')
var CallstackPanel = require('./CallstackPanel')
var StackPanel = require('./StackPanel')
var StoragePanel = require('./StoragePanel')
-var BasicPanel = require('./BasicPanel')
var FullStoragesChangesPanel = require('./FullStoragesChanges')
+var StepDetail = require('./StepDetail')
+var DropdownPanel = require('./DropdownPanel')
var yo = require('yo-yo')
-var ui = require('../helpers/ui')
function VmDebugger (_parent, _traceManager, _codeManager) {
- this.asmCode = new ASMCode(_parent, _codeManager)
+ this.asmCode = new ListView(_parent, _codeManager)
this.stackPanel = new StackPanel(_parent, _traceManager)
this.storagePanel = new StoragePanel(_parent, _traceManager)
this.memoryPanel = new MemoryPanel(_parent, _traceManager)
this.calldataPanel = new CalldataPanel(_parent, _traceManager)
this.callstackPanel = new CallstackPanel(_parent, _traceManager)
+ this.stepDetail = new StepDetail(_parent, _traceManager)
/* Return values - */
- this.returnValuesPanel = new BasicPanel('Return Value', '1205px', '100px')
+ this.returnValuesPanel = new DropdownPanel('Return Value')
+ this.returnValuesPanel.data = {}
_parent.register('indexChanged', this.returnValuesPanel, function (index) {
var self = this
_traceManager.getReturnValue(index, function (error, returnValue) {
if (error) {
- console.log(error)
- self.data = ''
+ self.data = [error]
} else if (_parent.currentStepIndex === index) {
- self.data = returnValue
+ self.data = [returnValue]
}
self.update()
- if (!returnValue) {
- self.hide()
- }
})
})
/* Return values - */
@@ -52,45 +49,18 @@ function VmDebugger (_parent, _traceManager, _codeManager) {
VmDebugger.prototype.render = function () {
var view = yo`
-
-
-
-
-
- ${this.returnValuesPanel.render()}
- |
-
-
-
- ${this.fullStoragesChangesPanel.render()}
- |
-
-
-
- ${this.asmCode.render()}
- |
-
- ${this.stackPanel.render()}
- |
-
-
-
- ${this.storagePanel.render()}
- |
-
- ${this.memoryPanel.render()}
- |
-
-
-
- ${this.calldataPanel.render()}
- |
-
- ${this.callstackPanel.render()}
- |
-
-
-
+
+
+ ${this.asmCode.render()}
+ ${this.stepDetail.render()}
+ ${this.stackPanel.render()}
+ ${this.storagePanel.render()}
+ ${this.memoryPanel.render()}
+ ${this.calldataPanel.render()}
+ ${this.callstackPanel.render()}
+ ${this.returnValuesPanel.render()}
+ ${this.fullStoragesChangesPanel.render()}
+
`
if (!this.view) {
diff --git a/src/ui/img/play-arrow.png b/src/ui/img/play-arrow.png
new file mode 100644
index 0000000000..3414a07289
Binary files /dev/null and b/src/ui/img/play-arrow.png differ
diff --git a/src/ui/styles/basicStyles.js b/src/ui/styles/basicStyles.js
index e91abb1e4c..cf1b93869d 100644
--- a/src/ui/styles/basicStyles.js
+++ b/src/ui/styles/basicStyles.js
@@ -1,5 +1,11 @@
'use strict'
module.exports = {
+ truncate: {
+ 'white-space': 'nowrap',
+ 'overflow': 'hidden',
+ 'text-overflow': 'ellipsis',
+ 'margin-right': '5px'
+ },
font: {
'font-family': 'arial,sans-serif'
},
@@ -14,8 +20,11 @@ module.exports = {
'font-style': 'italic'
},
instructionsList: {
- 'width': '600px',
- 'height': '330px'
+ 'width': '72%',
+ 'height': '330px',
+ 'overflow-y': 'scroll',
+ 'list-style-type': 'none',
+ 'margin': 'auto'
},
transactionInfo: {
'margin-top': '5px'
@@ -53,5 +62,28 @@ module.exports = {
vmargin: {
'margin-top': '10px',
'margin-bottom': '10px'
+ },
+ button: {
+ '-moz-box-shadow': 'inset 0px 1px 0px 0px #ffffff',
+ '-webkit-box-shadow': 'inset 0px 1px 0px 0px #ffffff',
+ 'box-shadow': 'inset 0px 1px 0px 0px #ffffff',
+ 'background': '-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #f9f9f9), color-stop(1, #e9e9e9))', // eslint-disable-line
+ 'background': '-moz-linear-gradient(top, #f9f9f9 5%, #e9e9e9 100%)', // eslint-disable-line
+ 'background': '-webkit-linear-gradient(top, #f9f9f9 5%, #e9e9e9 100%)', // eslint-disable-line
+ 'background': '-o-linear-gradient(top, #f9f9f9 5%, #e9e9e9 100%)', // eslint-disable-line
+ 'background': '-ms-linear-gradient(top, #f9f9f9 5%, #e9e9e9 100%)', // eslint-disable-line
+ 'background': 'linear-gradient(to bottom, #f9f9f9 5%, #e9e9e9 100%)', // eslint-disable-line
+ 'filter': "progid:DXImageTransform.Microsoft.gradient(startColorstr='#f9f9f9', endColorstr='#e9e9e9',GradientType=0)", // eslint-disable-line
+ 'background-color': '#f9f9f9',
+ '-moz-border-radius': '6px',
+ '-webkit-border-radius': '6px',
+ 'border-radius': '6px',
+ 'border': '1px solid #dcdcdc',
+ 'display': 'inline-block',
+ 'cursor': 'pointer',
+ 'color': '#666666',
+ 'font-family': 'Arial',
+ 'text-decoration': 'none',
+ 'text-shadow': '0px 1px 0px #ffffff'
}
}
diff --git a/src/ui/styles/dropdownPanel.js b/src/ui/styles/dropdownPanel.js
new file mode 100644
index 0000000000..72fedb1f38
--- /dev/null
+++ b/src/ui/styles/dropdownPanel.js
@@ -0,0 +1,28 @@
+'use strict'
+module.exports = {
+ title: {
+ 'border': '1px solid #dadada',
+ 'background-color': '#eeeeee',
+ 'width': '100%',
+ 'color': '#363f47',
+ 'margin-top': '5px',
+ 'font-style': 'italic'
+ },
+ titleInner: {
+ 'display': 'inline-block',
+ 'cursor': 'pointer'
+ },
+ content: {
+ 'color': '#9b9b9b',
+ 'width': '100%',
+ 'font-family': 'monospace'
+ },
+ inner: {
+ 'padding': '2px',
+ 'margin-left': '10px'
+ },
+ copyBtn: {
+ 'float': 'right',
+ 'margin-top': '3px'
+ }
+}