Merge pull request #170 from ethereum/treeView

Tree view
pull/7/head
yann300 8 years ago committed by GitHub
commit 5601ceda4d
  1. 2
      src/ui/CalldataPanel.js
  2. 2
      src/ui/CallstackPanel.js
  3. 5
      src/ui/CodeListView.js
  4. 57
      src/ui/DropdownPanel.js
  5. 2
      src/ui/FullStoragesChanges.js
  6. 6
      src/ui/MemoryPanel.js
  7. 2
      src/ui/SolidityLocals.js
  8. 2
      src/ui/SolidityState.js
  9. 2
      src/ui/StackPanel.js
  10. 2
      src/ui/StepDetail.js
  11. 2
      src/ui/StoragePanel.js
  12. 70
      src/ui/TreeView.js
  13. 8
      src/ui/TxBrowser.js
  14. 7
      src/ui/VmDebugger.js
  15. 3
      src/ui/styles/dropdownPanel.js
  16. 16
      src/ui/styles/treeView.js
  17. 10
      test-browser/init.js
  18. 27
      test-browser/vmdebugger.js

@ -5,7 +5,7 @@ var yo = require('yo-yo')
function CalldataPanel (_parent, _traceManager) {
this.parent = _parent
this.traceManager = _traceManager
this.basicPanel = new DropdownPanel('Call Data')
this.basicPanel = new DropdownPanel('Call Data', {json: true})
this.init()
}

@ -5,7 +5,7 @@ var yo = require('yo-yo')
function CallstackPanel (_parent, _traceManager) {
this.parent = _parent
this.traceManager = _traceManager
this.basicPanel = new DropdownPanel('Call Stack')
this.basicPanel = new DropdownPanel('Call Stack', {json: true})
this.init()
}

@ -11,7 +11,7 @@ function CodeListView (_parent, _codeManager) {
this.address
this.codeView
this.itemSelected
this.basicPanel = new DropdownPanel('Instructions', true)
this.basicPanel = new DropdownPanel('Instructions', {json: false})
this.init()
}
@ -51,8 +51,7 @@ CodeListView.prototype.changed = function (code, address, index) {
this.code = code
this.address = address
this.codeView = this.renderAssemblyItems()
this.basicPanel.data = this.codeView
this.basicPanel.update()
this.basicPanel.setContent(this.codeView)
}
this.indexChanged(index)
}

@ -3,49 +3,40 @@ var yo = require('yo-yo')
var ui = require('../helpers/ui')
var styleDropdown = require('./styles/dropdownPanel')
var basicStyles = require('./styles/basicStyles')
var TreeView = require('./TreeView')
function DropdownPanel (_name, _raw) {
this.data
function DropdownPanel (_name, _opts) {
if (!_opts) {
_opts = {}
}
this.name = _name
this.json = _opts.json
if (this.json) {
this.treeView = new TreeView(_opts)
}
this.view
_raw = _raw === undefined ? false : _raw
this.raw = _raw
}
DropdownPanel.prototype.update = function (_data) {
if (!this.view) {
return
}
if (_data) {
this.data = _data
}
this.view.querySelector('.dropdownpanel div.dropdowncontent').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`<div>${item}</div>`)
})
} else {
for (var k in this.data) {
var content = typeof this.data[k] === 'string' ? this.data[k] : JSON.stringify(this.data[k])
div.appendChild(yo`<div><div title=${k} style=${ui.formatCss(basicStyles.truncate, {display: 'inline-block', 'width': '10%'})} >${k}</div><div title=${content} style=${ui.formatCss(basicStyles.truncate, {display: 'inline-block', 'width': '78%'})} >${content}</div></div>`)
}
}
this.view.querySelector('.dropdownpanel div.dropdowncontent').appendChild(div)
if (this.view) {
this.view.querySelector('.dropdownpanel .dropdownrawcontent').innerText = JSON.stringify(_data, null, '\t')
this.view.querySelector('.dropdownpanel button.btn').style.display = 'block'
this.view.querySelector('.dropdownpanel .dropdownrawcontent').innerText = data
} else {
this.view.querySelector('.dropdownpanel div.dropdowncontent').appendChild(this.data)
this.view.querySelector('.dropdownpanel button.btn').style.display = 'none'
if (this.json) {
this.treeView.update(_data)
}
}
}
DropdownPanel.prototype.setContent = function (node) {
var parent = this.view.querySelector('.dropdownpanel div.dropdowncontent')
parent.replaceChild(node, parent.firstElementChild)
}
DropdownPanel.prototype.render = function (overridestyle) {
var content = yo`<div>Empty</div>`
if (this.json) {
content = this.treeView.render({})
}
overridestyle === undefined ? {} : overridestyle
var self = this
var view = yo`<div>
@ -55,7 +46,7 @@ DropdownPanel.prototype.render = function (overridestyle) {
<div class='dropdownpanel' style=${ui.formatCss(styleDropdown.content)} style='display:none'>
<button onclick=${function () { self.toggleRaw() }} style=${ui.formatCss(basicStyles.button, styleDropdown.copyBtn)} title='raw' class="btn fa fa-eye" type="button">
</button>
<div style=${ui.formatCss(styleDropdown.inner, overridestyle)} class='dropdowncontent'><div>Empty</div></div>
<div style=${ui.formatCss(styleDropdown.inner, overridestyle)} class='dropdowncontent'>${content}</div>
<div style=${ui.formatCss(styleDropdown.inner, overridestyle)} class='dropdownrawcontent' style='display:none'></div>
</div>
</div>`

@ -8,7 +8,7 @@ function FullStoragesChanges (_parent, _traceManager) {
this.addresses = []
this.view
this.traceLength
this.basicPanel = new DropdownPanel('Full Storages Changes')
this.basicPanel = new DropdownPanel('Full Storages Changes', {json: true})
this.init()
}

@ -6,7 +6,11 @@ var yo = require('yo-yo')
function MemoryPanel (_parent, _traceManager) {
this.parent = _parent
this.traceManager = _traceManager
this.basicPanel = new DropdownPanel('Memory')
this.basicPanel = new DropdownPanel('Memory', {
json: true,
css: {
'font-family': 'monospace'
}})
this.init()
}

@ -9,7 +9,7 @@ class SolidityLocals {
this.parent = _parent
this.internalTreeCall = internalTreeCall
this.traceManager = _traceManager
this.basicPanel = new DropdownPanel('Solidity Locals')
this.basicPanel = new DropdownPanel('Solidity Locals', {json: true})
this.init()
}

@ -8,7 +8,7 @@ function SolidityState (_parent, _traceManager, _codeManager, _solidityProxy) {
this.traceManager = _traceManager
this.codeManager = _codeManager
this.solidityProxy = _solidityProxy
this.basicPanel = new DropdownPanel('Solidity State')
this.basicPanel = new DropdownPanel('Solidity State', {json: true})
this.init()
}

@ -6,7 +6,7 @@ var yo = require('yo-yo')
function StackPanel (_parent, _traceManager) {
this.parent = _parent
this.traceManager = _traceManager
this.basicPanel = new DropdownPanel('Stack')
this.basicPanel = new DropdownPanel('Stack', {json: true})
this.init()
}

@ -6,7 +6,7 @@ function StepDetail (_parent, _traceManager) {
this.parent = _parent
this.traceManager = _traceManager
this.basicPanel = new DropdownPanel('Step detail')
this.basicPanel = new DropdownPanel('Step detail', {json: true})
this.detail = initDetail()
this.view

@ -5,7 +5,7 @@ var yo = require('yo-yo')
function StoragePanel (_parent, _traceManager, _address) {
this.parent = _parent
this.traceManager = _traceManager
this.basicPanel = new DropdownPanel('Storage Changes')
this.basicPanel = new DropdownPanel('Storage Changes', {json: true})
this.address = _address
this.init()
this.disabled = false

@ -0,0 +1,70 @@
'use strict'
var yo = require('yo-yo')
var style = require('./styles/treeView')
var ui = require('../helpers/ui')
class TreeView {
constructor (opts) {
function noop (node) {
}
this.beforeJsonNodeRendered = opts.beforeJsonNodeRendered || noop
this.beforeJsonValueRendered = opts.beforeJsonValueRendered || noop
this.view = null
this.cssLabel = ui.formatCss(opts.css || {}, style.label)
this.cssList = ui.formatCss(opts.css || {}, style.list)
}
render (json) {
var view = yo`<div>${this.renderProperties(json, true)}</div>`
if (!this.view) {
this.view = view
}
return view
}
update (json) {
if (this.view) {
yo.update(this.view, this.render(json), {onBeforeElUpdated: (fromEl, toEl) => {
toEl.style.display = fromEl.style.display
toEl.className = fromEl.className
return true
}})
}
}
renderObject (item, key, expand) {
var label
if (item instanceof Array || item instanceof Object) {
var properties = this.renderProperties(item, false)
label = yo`<span style=${this.cssLabel}><label style='width: 10px' id='caret'></label><label>${key} - ${properties.length} items</label></span>`
var list = yo`<ul style=${this.cssList}>${properties}</ol>`
list.style.display = expand ? 'block' : 'none'
label.firstElementChild.className = expand ? 'fa fa-caret-down' : 'fa fa-caret-right'
label.onclick = function () {
this.firstElementChild.className = this.firstElementChild.className === 'fa fa-caret-right' ? 'fa fa-caret-down' : 'fa fa-caret-right'
var list = this.parentElement.querySelector('ul')
list.style.display = list.style.display === 'none' ? 'block' : 'none'
}
if (this.beforeJsonNodeRendered) {
this.beforeJsonNodeRendered(label, item, key)
}
return yo`<li style=${this.cssList}>${label}${list}</li>`
} else {
label = yo`<label style=${this.cssLabel}>${key}</label>`
if (this.beforeJsonValueRendered) {
this.beforeJsonValueRendered(label, item, key)
}
return yo`<li style=${this.cssList}>${label}: <span style=${this.cssLabel} >${item}</span></li>`
}
}
renderProperties (json, expand) {
var properties = Object.keys(json).map((innerkey) => {
return this.renderObject(json[innerkey], innerkey, expand)
})
return properties
}
}
module.exports = TreeView

@ -14,7 +14,7 @@ function TxBrowser (_parent) {
this.txNumber
this.view
this.displayConnectionSetting = true
this.basicPanel = new DropdownPanel('Transaction')
this.basicPanel = new DropdownPanel('Transaction', {json: true})
this.basicPanel.data = {}
var self = this
_parent.event.register('providerChanged', this, function (provider) {
@ -34,8 +34,7 @@ function TxBrowser (_parent) {
TxBrowser.prototype.setDefaultValues = function () {
this.connectInfo = ''
this.basicPanel.data = {}
this.basicPanel.update()
this.basicPanel.update({})
this.basicPanel.hide()
this.updateWeb3Url(util.web3.currentProvider.host)
if (this.view) {
@ -86,8 +85,7 @@ TxBrowser.prototype.update = function (error, tx) {
this.view.querySelector('#error').innerHTML = 'Cannot find transaction with reference. Block number: ' + this.blockNumber + '. Transaction index/hash: ' + this.txNumber
}
}
this.basicPanel.data = info
this.basicPanel.update()
this.basicPanel.update(info)
}
TxBrowser.prototype.updateWeb3Url = function (newhost) {

@ -24,17 +24,16 @@ function VmDebugger (_parent, _traceManager, _codeManager, _solidityProxy, _call
this.solidityLocals = new SolidityLocals(_parent, _traceManager, _callTree)
/* Return values - */
this.returnValuesPanel = new DropdownPanel('Return Value')
this.returnValuesPanel = new DropdownPanel('Return Value', {json: true})
this.returnValuesPanel.data = {}
_parent.event.register('indexChanged', this.returnValuesPanel, function (index) {
var self = this
_traceManager.getReturnValue(index, function (error, returnValue) {
if (error) {
self.data = [error]
self.update([error])
} else if (_parent.currentStepIndex === index) {
self.data = [returnValue]
self.update([returnValue])
}
self.update()
})
})
/* Return values - */

@ -13,8 +13,7 @@ module.exports = {
},
content: {
'color': '#111111',
'width': '100%',
'font-family': 'monospace'
'width': '100%'
},
inner: {
'padding': '2px',

@ -0,0 +1,16 @@
'use strict'
module.exports = {
list: {
'list-style-type': 'none',
'-webkit-margin-before': '0px',
'-webkit-margin-after': '0px',
'-webkit-margin-start': '0px',
'-webkit-margin-end': '0px',
'-webkit-padding-start': '0px',
'margin-left': '10px'
},
label: {
'vertical-align': 'top',
'font-family': 'arial,sans-serif'
}
}

@ -32,7 +32,7 @@ function extendBrowser (browser) {
}
browser.assertStepDetail = function (vmtracestepinfo, stepinfo, addmemoryinfo, gasinfo, remaininggasinfo, loadedaddressinfo) {
assertPanel('#stepdetail', browser, ['vmtracestep' + vmtracestepinfo, 'executionstep' + stepinfo, 'addmemory' + addmemoryinfo, 'gas' + gasinfo, 'remaininggas' + remaininggasinfo, 'loadedaddress' + loadedaddressinfo])
assertPanel('#stepdetail', browser, ['vmtracestep:' + vmtracestepinfo, 'executionstep:' + stepinfo, 'addmemory:' + addmemoryinfo, 'gas:' + gasinfo, 'remaininggas:' + remaininggasinfo, 'loadedaddress:' + loadedaddressinfo])
return browser
}
@ -141,8 +141,12 @@ function assertPanel (id, browser, value) {
return ret
}, [id, selector], function (returnValues) {
value.map(function (item, index) {
var testValue = returnValues.value[index].replace(/\r\n/g, '').replace(/\t/g, '').replace(/\s/g, '')
browser.assert.equal(testValue, value[index])
if (returnValues.value.length) {
var testValue = returnValues.value[index].replace(/\r\n/g, '').replace(/\t/g, '').replace(/\s/g, '')
browser.assert.equal(testValue, value[index])
} else {
browser.assert.equal(item, '')
}
})
})
return browser

@ -63,21 +63,20 @@ function panels (browser) {
.setValue('#txinput', '0x20ef65b8b186ca942fcccd634f37074dde49b541c27994fc7596740ef44cfd51')
.click('#load')
.click('#nextcall')
.assertStack(['0x', '0x60', '0x65', '0x38', '0x55', '0x60fe47b1'])
.pause(5000)
.assertStorageChanges(['0x000x38'])
.assertCallData(['0x60fe47b10000000000000000000000000000000000000000000000000000000000000038'])
.assertCallStack(['0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5'])
.assertStackValue(1, '0x60')
.assertMemoryValue(6, '0x6060606040526040516020806045833981????R??Q????E?9?')
.assertMemoryValue(7, '0x7001604052808051906020019091905050???R??Q???????PP')
.assertMemoryValue(8, '0x805b806001016000600050819055505b50?????????P??UP?P')
.assertStack(['0:0x', '1:0x60', '2:0x65', '3:0x38', '4:0x55', '5:0x60fe47b1'])
.assertStorageChanges(['0x00:0x38'])
.assertCallData(['0:0x60fe47b10000000000000000000000000000000000000000000000000000000000000038'])
.assertCallStack(['0:0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5'])
.assertStackValue(1, '1:0x60')
.assertMemoryValue(6, '0x60:60606040526040516020806045833981????R??Q????E?9?')
.assertMemoryValue(7, '0x70:01604052808051906020019091905050???R??Q???????PP')
.assertMemoryValue(8, '0x80:5b806001016000600050819055505b50?????????P??UP?P')
.click('#intoforward') // CREATE
.assertStack(['Empty'])
.assertStorageChanges(['Empty'])
.assertMemory(['Empty'])
.assertCallData(['0x0000000000000000000000000000000000000000000000000000000000000000000000000000006060606040526040516020806045833981016040528080519060200190919050505b806001016000600050819055'])
.assertCallStack(['0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5', '(ContractCreation-Step63)'])
.assertStack([''])
.assertStorageChanges([''])
.assertMemory([''])
.assertCallData(['0:0x0000000000000000000000000000000000000000000000000000000000000000000000000000006060606040526040516020806045833981016040528080519060200190919050505b806001016000600050819055'])
.assertCallStack(['0:0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5', '1:(ContractCreation-Step63)'])
return browser
}

Loading…
Cancel
Save