diff --git a/src/ui/CalldataPanel.js b/src/ui/CalldataPanel.js index f5e6aa550f..e2fef57b74 100644 --- a/src/ui/CalldataPanel.js +++ b/src/ui/CalldataPanel.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() } diff --git a/src/ui/CallstackPanel.js b/src/ui/CallstackPanel.js index 6ceeca026c..a9ecdbac5e 100644 --- a/src/ui/CallstackPanel.js +++ b/src/ui/CallstackPanel.js @@ -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() } diff --git a/src/ui/CodeListView.js b/src/ui/CodeListView.js index d355dbb751..3dc8fe0022 100644 --- a/src/ui/CodeListView.js +++ b/src/ui/CodeListView.js @@ -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) } diff --git a/src/ui/DropdownPanel.js b/src/ui/DropdownPanel.js index 1caf7ea2dc..8f36e1071d 100644 --- a/src/ui/DropdownPanel.js +++ b/src/ui/DropdownPanel.js @@ -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`
${item}
`) - }) - } 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`
${k}
${content}
`) - } - } - 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`
Empty
` + if (this.json) { + content = this.treeView.render({}) + } overridestyle === undefined ? {} : overridestyle var self = this var view = yo`
@@ -55,7 +46,7 @@ DropdownPanel.prototype.render = function (overridestyle) {
` diff --git a/src/ui/FullStoragesChanges.js b/src/ui/FullStoragesChanges.js index 641b4e8879..9c4d4c6769 100644 --- a/src/ui/FullStoragesChanges.js +++ b/src/ui/FullStoragesChanges.js @@ -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() } diff --git a/src/ui/MemoryPanel.js b/src/ui/MemoryPanel.js index e80166e31c..b48b59d49b 100644 --- a/src/ui/MemoryPanel.js +++ b/src/ui/MemoryPanel.js @@ -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() } diff --git a/src/ui/SolidityLocals.js b/src/ui/SolidityLocals.js index afbca77a78..df2826f950 100644 --- a/src/ui/SolidityLocals.js +++ b/src/ui/SolidityLocals.js @@ -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() } diff --git a/src/ui/SolidityState.js b/src/ui/SolidityState.js index bc4cc24e38..22303f8082 100644 --- a/src/ui/SolidityState.js +++ b/src/ui/SolidityState.js @@ -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() } diff --git a/src/ui/StackPanel.js b/src/ui/StackPanel.js index dbf83dbb4d..0460c8a3ea 100644 --- a/src/ui/StackPanel.js +++ b/src/ui/StackPanel.js @@ -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() } diff --git a/src/ui/StepDetail.js b/src/ui/StepDetail.js index ac752e5a51..88950e4e93 100644 --- a/src/ui/StepDetail.js +++ b/src/ui/StepDetail.js @@ -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 diff --git a/src/ui/StoragePanel.js b/src/ui/StoragePanel.js index f7f0c90a05..e0dd9612c9 100644 --- a/src/ui/StoragePanel.js +++ b/src/ui/StoragePanel.js @@ -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 diff --git a/src/ui/TreeView.js b/src/ui/TreeView.js new file mode 100644 index 0000000000..49df208ce9 --- /dev/null +++ b/src/ui/TreeView.js @@ -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`
${this.renderProperties(json, true)}
` + 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`` + var list = yo`