parent
39537d57ba
commit
7b6abb03ad
@ -1,279 +0,0 @@ |
|||||||
var TxBrowser = require('./debuggerUI/TxBrowser') |
|
||||||
var StepManagerUI = require('./debuggerUI/StepManager') |
|
||||||
var VmDebugger = require('./debuggerUI/VmDebugger') |
|
||||||
var toaster = require('../../ui/tooltip') |
|
||||||
|
|
||||||
var Debugger = require('@remix-project/remix-debug').TransactionDebugger |
|
||||||
|
|
||||||
var SourceHighlighter = require('../../editor/sourceHighlighter') |
|
||||||
|
|
||||||
var EventManager = require('../../../lib/events') |
|
||||||
|
|
||||||
var globalRegistry = require('../../../global/registry') |
|
||||||
|
|
||||||
var remixDebug = require('@remix-project/remix-debug') |
|
||||||
|
|
||||||
var init = remixDebug.init |
|
||||||
|
|
||||||
var yo = require('yo-yo') |
|
||||||
var csjs = require('csjs-inject') |
|
||||||
|
|
||||||
var css = csjs` |
|
||||||
.statusMessage { |
|
||||||
margin-left: 15px; |
|
||||||
} |
|
||||||
|
|
||||||
.debuggerConfig { |
|
||||||
display: flex; |
|
||||||
align-items: center; |
|
||||||
} |
|
||||||
|
|
||||||
.debuggerConfig label { |
|
||||||
margin: 0; |
|
||||||
} |
|
||||||
|
|
||||||
.debuggerSection { |
|
||||||
padding: 12px 24px 16px; |
|
||||||
} |
|
||||||
|
|
||||||
.debuggerLabel { |
|
||||||
margin-bottom: 2px; |
|
||||||
font-size: 11px; |
|
||||||
line-height: 12px; |
|
||||||
text-transform: uppercase; |
|
||||||
} |
|
||||||
` |
|
||||||
|
|
||||||
class DebuggerUI { |
|
||||||
|
|
||||||
constructor (debuggerModule, component, fetchContractAndCompile) { |
|
||||||
this.debuggerModule = debuggerModule |
|
||||||
this.fetchContractAndCompile = fetchContractAndCompile |
|
||||||
this.event = new EventManager() |
|
||||||
|
|
||||||
this.isActive = false |
|
||||||
this.opt = { |
|
||||||
debugWithGeneratedSources: false |
|
||||||
} |
|
||||||
this.sourceHighlighter = new SourceHighlighter() |
|
||||||
|
|
||||||
this.startTxBrowser() |
|
||||||
this.stepManager = null |
|
||||||
|
|
||||||
this.statusMessage = '' |
|
||||||
this.currentReceipt |
|
||||||
|
|
||||||
this.view |
|
||||||
|
|
||||||
component.appendChild(this.render()) |
|
||||||
|
|
||||||
this.setEditor() |
|
||||||
} |
|
||||||
|
|
||||||
setEditor () { |
|
||||||
this.editor = globalRegistry.get('editor').api |
|
||||||
|
|
||||||
this.editor.event.register('breakpointCleared', (fileName, row) => { |
|
||||||
if (this.debugger) this.debugger.breakPointManager.remove({fileName: fileName, row: row}) |
|
||||||
}) |
|
||||||
|
|
||||||
this.editor.event.register('breakpointAdded', (fileName, row) => { |
|
||||||
if (this.debugger) this.debugger.breakPointManager.add({fileName: fileName, row: row}) |
|
||||||
}) |
|
||||||
|
|
||||||
this.editor.event.register('contentChanged', () => { |
|
||||||
if (this.debugger) this.debugger.unload() |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
listenToEvents () { |
|
||||||
if (!this.debugger) return |
|
||||||
|
|
||||||
this.debugger.event.register('debuggerStatus', async (isActive) => { |
|
||||||
await this.debuggerModule.call('editor', 'discardHighlight') |
|
||||||
this.isActive = isActive |
|
||||||
}) |
|
||||||
|
|
||||||
this.debugger.event.register('newSourceLocation', async (lineColumnPos, rawLocation, generatedSources) => { |
|
||||||
if (!lineColumnPos) return |
|
||||||
const contracts = await this.fetchContractAndCompile( |
|
||||||
this.currentReceipt.contractAddress || this.currentReceipt.to, |
|
||||||
this.currentReceipt) |
|
||||||
if (contracts) { |
|
||||||
let path = contracts.getSourceName(rawLocation.file) |
|
||||||
if (!path) { |
|
||||||
// check in generated sources
|
|
||||||
for (const source of generatedSources) { |
|
||||||
if (source.id === rawLocation.file) { |
|
||||||
path = `browser/.debugger/generated-sources/${source.name}` |
|
||||||
let content |
|
||||||
try { |
|
||||||
content = await this.debuggerModule.call('fileManager', 'getFile', path, source.contents) |
|
||||||
} catch (e) { |
|
||||||
console.log('unable to fetch generated sources, the file probably doesn\'t exist yet', e) |
|
||||||
} |
|
||||||
if (content !== source.contents) { |
|
||||||
await this.debuggerModule.call('fileManager', 'setFile', path, source.contents) |
|
||||||
} |
|
||||||
break |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
if (path) { |
|
||||||
await this.debuggerModule.call('editor', 'discardHighlight') |
|
||||||
await this.debuggerModule.call('editor', 'highlight', lineColumnPos, path) |
|
||||||
} |
|
||||||
} |
|
||||||
}) |
|
||||||
|
|
||||||
this.debugger.event.register('debuggerUnloaded', () => this.unLoad()) |
|
||||||
} |
|
||||||
|
|
||||||
startTxBrowser () { |
|
||||||
let txBrowser = new TxBrowser() |
|
||||||
this.txBrowser = txBrowser |
|
||||||
|
|
||||||
txBrowser.event.register('requestDebug', (blockNumber, txNumber, tx) => { |
|
||||||
if (this.debugger) this.debugger.unload() |
|
||||||
this.startDebugging(blockNumber, txNumber, tx) |
|
||||||
}) |
|
||||||
|
|
||||||
txBrowser.event.register('unloadRequested', this, (blockNumber, txIndex, tx) => { |
|
||||||
if (this.debugger) this.debugger.unload() |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
isDebuggerActive () { |
|
||||||
return this.isActive |
|
||||||
} |
|
||||||
|
|
||||||
getDebugWeb3 () { |
|
||||||
return new Promise((resolve, reject) => { |
|
||||||
this.debuggerModule.blockchain.detectNetwork((error, network) => { |
|
||||||
let web3 |
|
||||||
if (error || !network) { |
|
||||||
web3 = init.web3DebugNode(this.debuggerModule.blockchain.web3()) |
|
||||||
} else { |
|
||||||
const webDebugNode = init.web3DebugNode(network.name) |
|
||||||
web3 = !webDebugNode ? this.debuggerModule.blockchain.web3() : webDebugNode |
|
||||||
} |
|
||||||
init.extendWeb3(web3) |
|
||||||
resolve(web3) |
|
||||||
}) |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
async startDebugging (blockNumber, txNumber, tx) { |
|
||||||
if (this.debugger) this.unLoad() |
|
||||||
|
|
||||||
let web3 = await this.getDebugWeb3() |
|
||||||
this.currentReceipt = await web3.eth.getTransactionReceipt(txNumber) |
|
||||||
this.debugger = new Debugger({ |
|
||||||
web3, |
|
||||||
offsetToLineColumnConverter: globalRegistry.get('offsettolinecolumnconverter').api, |
|
||||||
compilationResult: async (address) => { |
|
||||||
try { |
|
||||||
return await this.fetchContractAndCompile(address, this.currentReceipt) |
|
||||||
} catch (e) { |
|
||||||
console.error(e) |
|
||||||
} |
|
||||||
return null |
|
||||||
}, |
|
||||||
debugWithGeneratedSources: this.opt.debugWithGeneratedSources |
|
||||||
}) |
|
||||||
|
|
||||||
this.listenToEvents() |
|
||||||
this.debugger.debug(blockNumber, txNumber, tx, () => { |
|
||||||
this.stepManager = new StepManagerUI(this.debugger.step_manager) |
|
||||||
this.vmDebugger = new VmDebugger(this.debugger.vmDebuggerLogic) |
|
||||||
this.txBrowser.setState({ blockNumber, txNumber, debugging: true }) |
|
||||||
this.renderDebugger() |
|
||||||
}).catch((error) => { |
|
||||||
toaster(error) |
|
||||||
this.unLoad() |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
getTrace (hash) { |
|
||||||
return new Promise(async (resolve, reject) => { |
|
||||||
const web3 = await this.getDebugWeb3() |
|
||||||
|
|
||||||
this.currentReceipt = await web3.eth.getTransactionReceipt(hash) |
|
||||||
const debug = new Debugger({ |
|
||||||
web3, |
|
||||||
offsetToLineColumnConverter: globalRegistry.get('offsettolinecolumnconverter').api, |
|
||||||
compilationResult: async (address) => { |
|
||||||
try { |
|
||||||
return await this.fetchContractAndCompile(address, this.currentReceipt) |
|
||||||
} catch (e) { |
|
||||||
console.error(e) |
|
||||||
} |
|
||||||
return null |
|
||||||
}, |
|
||||||
debugWithGeneratedSources: false |
|
||||||
}) |
|
||||||
debug.debugger.traceManager.traceRetriever.getTrace(hash, (error, trace) => { |
|
||||||
if (error) return reject(error) |
|
||||||
resolve(trace) |
|
||||||
}) |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
debug (txHash) { |
|
||||||
this.startDebugging(null, txHash, null) |
|
||||||
} |
|
||||||
|
|
||||||
render () { |
|
||||||
this.debuggerPanelsView = yo`<div class="px-2"></div>` |
|
||||||
this.debuggerHeadPanelsView = yo`<div class="px-2"></div>` |
|
||||||
this.stepManagerView = yo`<div class="px-2"></div>` |
|
||||||
|
|
||||||
var view = yo` |
|
||||||
<div> |
|
||||||
<div class="px-2"> |
|
||||||
<div class="mt-3"> |
|
||||||
<p class="mt-2 ${css.debuggerLabel}">Debugger Configuration</p> |
|
||||||
<div class="mt-2 ${css.debuggerConfig} custom-control custom-checkbox"> |
|
||||||
<input class="custom-control-input" id="debugGeneratedSourcesInput" onchange=${(event) => { this.opt.debugWithGeneratedSources = event.target.checked }} type="checkbox" title="Debug with generated sources"> |
|
||||||
<label data-id="debugGeneratedSourcesLabel" class="form-check-label custom-control-label" for="debugGeneratedSourcesInput">Use generated sources (from Solidity v0.7.2)</label> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
${this.txBrowser.render()} |
|
||||||
${this.stepManagerView} |
|
||||||
${this.debuggerHeadPanelsView}
|
|
||||||
<div class="${css.statusMessage}">${this.statusMessage}</div> |
|
||||||
${this.debuggerPanelsView} |
|
||||||
</div> |
|
||||||
` |
|
||||||
if (!this.view) { |
|
||||||
this.view = view |
|
||||||
} |
|
||||||
return view |
|
||||||
} |
|
||||||
|
|
||||||
async unLoad () { |
|
||||||
yo.update(this.debuggerHeadPanelsView, yo`<div></div>`) |
|
||||||
yo.update(this.debuggerPanelsView, yo`<div></div>`) |
|
||||||
yo.update(this.stepManagerView, yo`<div></div>`) |
|
||||||
if (this.vmDebugger) this.vmDebugger.remove() |
|
||||||
if (this.stepManager) this.stepManager.remove() |
|
||||||
if (this.txBrowser) this.txBrowser.setState({debugging: false}) |
|
||||||
this.vmDebugger = null |
|
||||||
this.stepManager = null |
|
||||||
if (this.debugger) delete this.debugger |
|
||||||
this.event.trigger('traceUnloaded') |
|
||||||
} |
|
||||||
|
|
||||||
async deleteHighlights () { |
|
||||||
await this.debuggerModule.call('editor', 'discardHighlight') |
|
||||||
} |
|
||||||
|
|
||||||
renderDebugger () { |
|
||||||
yo.update(this.debuggerHeadPanelsView, this.vmDebugger.renderHead()) |
|
||||||
yo.update(this.debuggerPanelsView, this.vmDebugger.render()) |
|
||||||
yo.update(this.stepManagerView, this.stepManager.render()) |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
module.exports = DebuggerUI |
|
@ -1,130 +0,0 @@ |
|||||||
'use strict' |
|
||||||
var EventManager = require('../../../../lib/events') |
|
||||||
var yo = require('yo-yo') |
|
||||||
|
|
||||||
var csjs = require('csjs-inject') |
|
||||||
|
|
||||||
var css = csjs` |
|
||||||
.buttons { |
|
||||||
display: flex; |
|
||||||
flex-wrap: wrap; |
|
||||||
} |
|
||||||
.stepButtons { |
|
||||||
width: 100%; |
|
||||||
display: flex; |
|
||||||
justify-content: center; |
|
||||||
} |
|
||||||
.stepButton { |
|
||||||
} |
|
||||||
.jumpButtons { |
|
||||||
width: 100%; |
|
||||||
display: flex; |
|
||||||
justify-content: center; |
|
||||||
} |
|
||||||
.jumpButton { |
|
||||||
} |
|
||||||
.navigator { |
|
||||||
} |
|
||||||
.navigator:hover { |
|
||||||
} |
|
||||||
` |
|
||||||
|
|
||||||
function ButtonNavigator () { |
|
||||||
this.event = new EventManager() |
|
||||||
this.intoBackDisabled = true |
|
||||||
this.overBackDisabled = true |
|
||||||
this.intoForwardDisabled = true |
|
||||||
this.overForwardDisabled = true |
|
||||||
this.jumpOutDisabled = true |
|
||||||
this.jumpNextBreakpointDisabled = true |
|
||||||
this.jumpPreviousBreakpointDisabled = true |
|
||||||
|
|
||||||
this.view |
|
||||||
} |
|
||||||
|
|
||||||
ButtonNavigator.prototype.render = function () { |
|
||||||
var self = this |
|
||||||
var view = yo`<div class="${css.buttons}">
|
|
||||||
<div class="${css.stepButtons} btn-group py-1"> |
|
||||||
<button id='overback' class='btn btn-primary btn-sm ${css.navigator} ${css.stepButton} fas fa-reply' title='Step over back' onclick=${function () { self.event.trigger('stepOverBack') }} disabled=${this.overBackDisabled} ></button> |
|
||||||
<button id='intoback' data-id="buttonNavigatorIntoBack" class='btn btn-primary btn-sm ${css.navigator} ${css.stepButton} fas fa-level-up-alt' title='Step back' onclick=${function () { self.event.trigger('stepIntoBack') }} disabled=${this.intoBackDisabled} ></button> |
|
||||||
<button id='intoforward' data-id="buttonNavigatorIntoForward" class='btn btn-primary btn-sm ${css.navigator} ${css.stepButton} fas fa-level-down-alt' title='Step into' onclick=${function () { self.event.trigger('stepIntoForward') }} disabled=${this.intoForwardDisabled} ></button> |
|
||||||
<button id='overforward' class='btn btn-primary btn-sm ${css.navigator} ${css.stepButton} fas fa-share' title='Step over forward'onclick=${function () { self.event.trigger('stepOverForward') }} disabled=${this.overForwardDisabled} ></button> |
|
||||||
</div> |
|
||||||
|
|
||||||
<div class="${css.jumpButtons} btn-group py-1"> |
|
||||||
<button class='btn btn-primary btn-sm ${css.navigator} ${css.jumpButton} fas fa-step-backward' id='jumppreviousbreakpoint' data-id="buttonNavigatorJumpPreviousBreakpoint" title='Jump to the previous breakpoint' onclick=${function () { self.event.trigger('jumpPreviousBreakpoint') }} disabled=${this.jumpPreviousBreakpointDisabled} ></button> |
|
||||||
<button class='btn btn-primary btn-sm ${css.navigator} ${css.jumpButton} fas fa-eject' id='jumpout' title='Jump out' onclick=${function () { self.event.trigger('jumpOut') }} disabled=${this.jumpOutDisabled} ></button> |
|
||||||
<button class='btn btn-primary btn-sm ${css.navigator} ${css.jumpButton} fas fa-step-forward' id='jumpnextbreakpoint' data-id="buttonNavigatorJumpNextBreakpoint" title='Jump to the next breakpoint' onclick=${function () { self.event.trigger('jumpNextBreakpoint') }} disabled=${this.jumpNextBreakpointDisabled} ></button> |
|
||||||
</div> |
|
||||||
<div id='reverted' style="display:none"> |
|
||||||
<button class='btn btn-danger btn-sm' id='jumptoexception' title='Jump to exception' class='${css.navigator} ${css.button} fas fa-exclamation-triangle' onclick=${function () { self.event.trigger('jumpToException') }} disabled=${this.jumpOutDisabled} > |
|
||||||
</button> |
|
||||||
<span>State changes made during this call will be reverted.</span> |
|
||||||
<span id='outofgas' style="display:none">This call will run out of gas.</span> |
|
||||||
<span id='parenthasthrown' style="display:none">The parent call will throw an exception</span> |
|
||||||
</div> |
|
||||||
</div>` |
|
||||||
if (!this.view) { |
|
||||||
this.view = view |
|
||||||
} |
|
||||||
return view |
|
||||||
} |
|
||||||
|
|
||||||
ButtonNavigator.prototype.reset = function () { |
|
||||||
this.intoBackDisabled = true |
|
||||||
this.overBackDisabled = true |
|
||||||
this.intoForwardDisabled = true |
|
||||||
this.overForwardDisabled = true |
|
||||||
this.jumpOutDisabled = true |
|
||||||
this.jumpNextBreakpointDisabled = true |
|
||||||
this.jumpPreviousBreakpointDisabled = true |
|
||||||
this.resetWarning('') |
|
||||||
} |
|
||||||
|
|
||||||
ButtonNavigator.prototype.stepChanged = function (stepState, jumpOutDisabled) { |
|
||||||
if (stepState === 'invalid') { |
|
||||||
// TODO: probably not necessary, already implicit done in the next steps
|
|
||||||
this.reset() |
|
||||||
this.updateAll() |
|
||||||
return |
|
||||||
} |
|
||||||
|
|
||||||
this.intoBackDisabled = (stepState === 'initial') |
|
||||||
this.overBackDisabled = (stepState === 'initial') |
|
||||||
this.jumpPreviousBreakpointDisabled = (stepState === 'initial') |
|
||||||
this.jumpNextBreakpointDisabled = (stepState === 'end') |
|
||||||
this.intoForwardDisabled = (stepState === 'end') |
|
||||||
this.overForwardDisabled = (stepState === 'end') |
|
||||||
this.jumpNextBreakpointDisabled = jumpOutDisabled |
|
||||||
|
|
||||||
this.updateAll() |
|
||||||
} |
|
||||||
|
|
||||||
ButtonNavigator.prototype.updateAll = function () { |
|
||||||
this.updateDisabled('intoback', this.intoBackDisabled) |
|
||||||
this.updateDisabled('overback', this.overBackDisabled) |
|
||||||
this.updateDisabled('overforward', this.overForwardDisabled) |
|
||||||
this.updateDisabled('intoforward', this.intoForwardDisabled) |
|
||||||
this.updateDisabled('jumpout', this.jumpOutDisabled) |
|
||||||
this.updateDisabled('jumptoexception', this.jumpOutDisabled) |
|
||||||
this.updateDisabled('jumpnextbreakpoint', this.jumpNextBreakpointDisabled) |
|
||||||
this.updateDisabled('jumppreviousbreakpoint', this.jumpPreviousBreakpointDisabled) |
|
||||||
} |
|
||||||
|
|
||||||
ButtonNavigator.prototype.updateDisabled = function (id, disabled) { |
|
||||||
if (disabled) { |
|
||||||
document.getElementById(id).setAttribute('disabled', true) |
|
||||||
} else { |
|
||||||
document.getElementById(id).removeAttribute('disabled') |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
ButtonNavigator.prototype.resetWarning = function (revertedReason) { |
|
||||||
if (!this.view) return |
|
||||||
this.view.querySelector('#reverted #outofgas').style.display = (revertedReason === 'outofgas') ? 'inline' : 'none' |
|
||||||
this.view.querySelector('#reverted #parenthasthrown').style.display = (revertedReason === 'parenthasthrown') ? 'inline' : 'none' |
|
||||||
this.view.querySelector('#reverted').style.display = (revertedReason === '') ? 'none' : 'block' |
|
||||||
} |
|
||||||
|
|
||||||
module.exports = ButtonNavigator |
|
@ -1,57 +0,0 @@ |
|||||||
'use strict' |
|
||||||
var EventManager = require('../../../../lib/events') |
|
||||||
var yo = require('yo-yo') |
|
||||||
|
|
||||||
class Slider { |
|
||||||
constructor () { |
|
||||||
this.event = new EventManager() |
|
||||||
this.max |
|
||||||
this.disabled = true |
|
||||||
this.view |
|
||||||
this.previousValue = null |
|
||||||
} |
|
||||||
|
|
||||||
setSliderLength (length) { |
|
||||||
if (!this.view) return |
|
||||||
this.view.querySelector('#slider').setAttribute('max', length - 1) |
|
||||||
this.max = length - 1 |
|
||||||
this.disabled = (length === 0) |
|
||||||
|
|
||||||
if (this.disabled) { |
|
||||||
this.view.querySelector('#slider').setAttribute('disabled', true) |
|
||||||
} else { |
|
||||||
this.view.querySelector('#slider').removeAttribute('disabled') |
|
||||||
} |
|
||||||
|
|
||||||
this.setValue(0) |
|
||||||
} |
|
||||||
|
|
||||||
onChange (event) { |
|
||||||
if (!this.view) return |
|
||||||
var value = parseInt(this.view.querySelector('#slider').value) |
|
||||||
if (value === this.previousValue) return |
|
||||||
|
|
||||||
this.previousValue = value |
|
||||||
this.event.trigger('sliderMoved', [value]) |
|
||||||
} |
|
||||||
|
|
||||||
setValue (value) { |
|
||||||
if (!this.view) return |
|
||||||
this.view.querySelector('#slider').value = value |
|
||||||
} |
|
||||||
|
|
||||||
render () { |
|
||||||
var self = this |
|
||||||
var view = yo`<div>
|
|
||||||
<input id='slider' data-id="slider" class='w-100 my-0' type='range' min=0 max=${this.max} value=0 |
|
||||||
onchange=${function () { self.onChange() }} oninput=${function () { self.onChange() }} disabled=${this.disabled} /> |
|
||||||
</div>` |
|
||||||
if (!this.view) { |
|
||||||
this.view = view |
|
||||||
} |
|
||||||
return view |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
module.exports = Slider |
|
@ -1,59 +0,0 @@ |
|||||||
var EventManager = require('../../../../lib/events') |
|
||||||
var yo = require('yo-yo') |
|
||||||
|
|
||||||
var ButtonNavigator = require('./ButtonNavigator') |
|
||||||
var Slider = require('./Slider') |
|
||||||
|
|
||||||
function StepManager (stepManager) { |
|
||||||
this.event = new EventManager() |
|
||||||
this.stepManager = stepManager |
|
||||||
this.startSlider() |
|
||||||
this.startButtonNavigator() |
|
||||||
this.stepManager.event.register('stepChanged', this.updateStep.bind(this)) |
|
||||||
} |
|
||||||
|
|
||||||
StepManager.prototype.startSlider = function () { |
|
||||||
this.slider = new Slider() |
|
||||||
this.slider.event.register('sliderMoved', this.stepManager.jumpTo.bind(this.stepManager)) |
|
||||||
this.stepManager.event.register('traceLengthChanged', this.slider.setSliderLength.bind(this.slider)) |
|
||||||
} |
|
||||||
|
|
||||||
StepManager.prototype.startButtonNavigator = function () { |
|
||||||
this.buttonNavigator = new ButtonNavigator() |
|
||||||
|
|
||||||
this.stepManager.event.register('revertWarning', this.buttonNavigator.resetWarning.bind(this.buttonNavigator)) |
|
||||||
|
|
||||||
this.buttonNavigator.event.register('stepIntoBack', this.stepManager.stepIntoBack.bind(this.stepManager)) |
|
||||||
this.buttonNavigator.event.register('stepIntoForward', this.stepManager.stepIntoForward.bind(this.stepManager)) |
|
||||||
this.buttonNavigator.event.register('stepOverBack', this.stepManager.stepOverBack.bind(this.stepManager)) |
|
||||||
this.buttonNavigator.event.register('stepOverForward', this.stepManager.stepOverForward.bind(this.stepManager)) |
|
||||||
this.buttonNavigator.event.register('jumpOut', this.stepManager.jumpOut.bind(this.stepManager)) |
|
||||||
this.buttonNavigator.event.register('jumpToException', this.stepManager.jumpToException.bind(this.stepManager)) |
|
||||||
this.buttonNavigator.event.register('jumpNextBreakpoint', this.stepManager.jumpNextBreakpoint.bind(this.stepManager)) |
|
||||||
this.buttonNavigator.event.register('jumpPreviousBreakpoint', this.stepManager.jumpPreviousBreakpoint.bind(this.stepManager)) |
|
||||||
} |
|
||||||
|
|
||||||
StepManager.prototype.updateStep = function (step, stepState, jumpOutDisabled) { |
|
||||||
if (!this.slider) return |
|
||||||
this.slider.setValue(step) |
|
||||||
this.buttonNavigator.stepChanged(stepState, jumpOutDisabled) |
|
||||||
this.event.trigger('stepChanged', [step]) |
|
||||||
} |
|
||||||
|
|
||||||
StepManager.prototype.remove = function () { |
|
||||||
// used to stop listenning on event. bad and should be "refactored"
|
|
||||||
this.slider.view = null |
|
||||||
this.slider = null |
|
||||||
this.buttonNavigator.view = null |
|
||||||
this.buttonNavigator = null |
|
||||||
} |
|
||||||
|
|
||||||
StepManager.prototype.render = function () { |
|
||||||
return yo` |
|
||||||
<div class="py-1"> |
|
||||||
${this.slider.render()} |
|
||||||
${this.buttonNavigator.render()} |
|
||||||
</div>` |
|
||||||
} |
|
||||||
|
|
||||||
module.exports = StepManager |
|
@ -1,137 +0,0 @@ |
|||||||
var EventManager = require('../../../../lib/events') |
|
||||||
var yo = require('yo-yo') |
|
||||||
var csjs = require('csjs-inject') |
|
||||||
|
|
||||||
var css = csjs` |
|
||||||
.container { |
|
||||||
display: flex; |
|
||||||
flex-direction: column; |
|
||||||
} |
|
||||||
.txContainer { |
|
||||||
display: flex; |
|
||||||
flex-direction: column; |
|
||||||
} |
|
||||||
.txinput { |
|
||||||
width: inherit; |
|
||||||
font-size: small; |
|
||||||
white-space: nowrap; |
|
||||||
overflow: hidden; |
|
||||||
text-overflow: ellipsis; |
|
||||||
} |
|
||||||
.txbutton { |
|
||||||
width: inherit; |
|
||||||
} |
|
||||||
.txbutton:hover { |
|
||||||
} |
|
||||||
.vmargin { |
|
||||||
margin-top: 10px; |
|
||||||
margin-bottom: 10px; |
|
||||||
} |
|
||||||
` |
|
||||||
|
|
||||||
function TxBrowser () { |
|
||||||
this.event = new EventManager() |
|
||||||
|
|
||||||
this.state = { |
|
||||||
txNumber: undefined, |
|
||||||
debugging: false |
|
||||||
} |
|
||||||
this.view |
|
||||||
} |
|
||||||
|
|
||||||
TxBrowser.prototype.submit = function () { |
|
||||||
if (this.state.debugging) { |
|
||||||
this.unload() |
|
||||||
} else { |
|
||||||
this.event.trigger('requestDebug', [undefined, this.state.txNumber]) |
|
||||||
} |
|
||||||
yo.update(this.view, this.render()) |
|
||||||
} |
|
||||||
|
|
||||||
TxBrowser.prototype.updateTxN = function (ev) { |
|
||||||
this.state.txNumber = ev.target.value |
|
||||||
if (this.view) { |
|
||||||
yo.update(this.view, this.render()) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
TxBrowser.prototype.load = function (txHash, tx) { |
|
||||||
this.state.txNumber = txHash |
|
||||||
} |
|
||||||
|
|
||||||
TxBrowser.prototype.unload = function () { |
|
||||||
this.event.trigger('unloadRequested') |
|
||||||
} |
|
||||||
|
|
||||||
TxBrowser.prototype.setState = function (state) { |
|
||||||
this.state = {...this.state, ...state} |
|
||||||
if (this.view) { |
|
||||||
yo.update(this.view, this.render()) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
TxBrowser.prototype.render = function () { |
|
||||||
var self = this |
|
||||||
this.state.txNumberInput = yo` |
|
||||||
<input |
|
||||||
value="${this.state.txNumber || ''}" |
|
||||||
class="form-control m-0 ${css.txinput}" |
|
||||||
id='txinput' |
|
||||||
onkeyup=${function () { self.updateTxN(arguments[0]) }} |
|
||||||
type='text' |
|
||||||
oninput=${this.txInputChanged.bind(this)} |
|
||||||
placeholder=${'Transaction hash, should start with 0x'} |
|
||||||
data-id="debuggerTransactionInput" |
|
||||||
/> |
|
||||||
` |
|
||||||
let txButton = yo` |
|
||||||
<button |
|
||||||
class='btn btn-primary btn-sm ${css.txbutton}' |
|
||||||
id='load' |
|
||||||
title='${this.state.debugging ? 'Stop' : 'Start'} debugging' |
|
||||||
onclick=${function () { self.submit() }} |
|
||||||
data-id="debuggerTransactionStartButton" |
|
||||||
> |
|
||||||
${this.state.debugging ? 'Stop' : 'Start'} debugging |
|
||||||
</button> |
|
||||||
` |
|
||||||
var view = yo` |
|
||||||
<div class="${css.container}"> |
|
||||||
<div class="${css.txContainer}"> |
|
||||||
<div class=" py-1 d-flex justify-content-center w-100 input-group"> |
|
||||||
${this.state.txNumberInput} |
|
||||||
</div> |
|
||||||
<div class="d-flex justify-content-center w-100 btn-group py-1"> |
|
||||||
${txButton} |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
<span id='error'></span> |
|
||||||
</div> |
|
||||||
` |
|
||||||
if (this.state.debugging) { |
|
||||||
view.querySelectorAll('input').forEach(element => { element.setAttribute('disabled', '') }) |
|
||||||
} |
|
||||||
if (!this.state.txNumber) { |
|
||||||
view.querySelector("button[id='load']").setAttribute('disabled', '') |
|
||||||
} else if (!this.state.debugging) { |
|
||||||
this.state.txNumberInput.removeAttribute('disabled') |
|
||||||
} |
|
||||||
if (!this.view) { |
|
||||||
this.view = view |
|
||||||
} |
|
||||||
|
|
||||||
return view |
|
||||||
} |
|
||||||
|
|
||||||
TxBrowser.prototype.txInputChanged = function (event) { |
|
||||||
// todo check validation of txnumber in the input element, use
|
|
||||||
// required
|
|
||||||
// oninvalid="setCustomValidity('Please provide a valid transaction number, must start with 0x and have length of 22')"
|
|
||||||
// pattern="^0[x,X]+[0-9a-fA-F]{22}"
|
|
||||||
// this.state.txNumberInput.setCustomValidity('')
|
|
||||||
|
|
||||||
this.state.txNumber = event.target.value |
|
||||||
yo.update(this.view, this.render()) |
|
||||||
} |
|
||||||
|
|
||||||
module.exports = TxBrowser |
|
@ -1,179 +0,0 @@ |
|||||||
'use strict' |
|
||||||
var yo = require('yo-yo') |
|
||||||
|
|
||||||
var CodeListView = require('./vmDebugger/CodeListView') |
|
||||||
var CalldataPanel = require('./vmDebugger/CalldataPanel') |
|
||||||
var MemoryPanel = require('./vmDebugger/MemoryPanel') |
|
||||||
var CallstackPanel = require('./vmDebugger/CallstackPanel') |
|
||||||
var FunctionPanel = require('./vmDebugger/FunctionPanel') |
|
||||||
var StackPanel = require('./vmDebugger/StackPanel') |
|
||||||
var StoragePanel = require('./vmDebugger/StoragePanel') |
|
||||||
var StepDetail = require('./vmDebugger/StepDetail') |
|
||||||
var SolidityState = require('./vmDebugger/SolidityState') |
|
||||||
var SolidityLocals = require('./vmDebugger/SolidityLocals') |
|
||||||
var FullStoragesChangesPanel = require('./vmDebugger/FullStoragesChanges') |
|
||||||
var DropdownPanel = require('./vmDebugger/DropdownPanel') |
|
||||||
|
|
||||||
function VmDebugger (vmDebuggerLogic) { |
|
||||||
var self = this |
|
||||||
this.view |
|
||||||
|
|
||||||
this.vmDebuggerLogic = vmDebuggerLogic |
|
||||||
|
|
||||||
this.asmCode = new CodeListView() |
|
||||||
this.vmDebuggerLogic.event.register('codeManagerChanged', this.asmCode.changed.bind(this.asmCode)) |
|
||||||
this.vmDebuggerLogic.event.register('traceUnloaded', this.asmCode.reset.bind(this.asmCode)) |
|
||||||
|
|
||||||
this.calldataPanel = new CalldataPanel() |
|
||||||
this.vmDebuggerLogic.event.register('traceManagerCallDataUpdate', this.calldataPanel.update.bind(this.calldataPanel)) |
|
||||||
|
|
||||||
this.memoryPanel = new MemoryPanel() |
|
||||||
this.vmDebuggerLogic.event.register('traceManagerMemoryUpdate', this.memoryPanel.update.bind(this.memoryPanel)) |
|
||||||
|
|
||||||
this.callstackPanel = new CallstackPanel() |
|
||||||
this.vmDebuggerLogic.event.register('traceManagerCallStackUpdate', this.callstackPanel.update.bind(this.callstackPanel)) |
|
||||||
|
|
||||||
this.stackPanel = new StackPanel() |
|
||||||
this.vmDebuggerLogic.event.register('traceManagerStackUpdate', this.stackPanel.update.bind(this.stackPanel)) |
|
||||||
|
|
||||||
this.functionPanel = new FunctionPanel() |
|
||||||
this.vmDebuggerLogic.event.register('functionsStackUpdate', (stack) => { |
|
||||||
if (stack === null || stack.length === 0) return |
|
||||||
let functions = [] |
|
||||||
for (let func of stack) { |
|
||||||
functions.push(func.functionDefinition.name + '(' + func.inputs.join(', ') + ')') |
|
||||||
} |
|
||||||
this.functionPanel.update(functions) |
|
||||||
}) |
|
||||||
|
|
||||||
this.storagePanel = new StoragePanel() |
|
||||||
this.vmDebuggerLogic.event.register('traceManagerStorageUpdate', this.storagePanel.update.bind(this.storagePanel)) |
|
||||||
|
|
||||||
this.stepDetail = new StepDetail() |
|
||||||
this.vmDebuggerLogic.event.register('traceUnloaded', this.stepDetail.reset.bind(this.stepDetail)) |
|
||||||
this.vmDebuggerLogic.event.register('newTraceLoaded', this.stepDetail.reset.bind(this.stepDetail)) |
|
||||||
|
|
||||||
this.vmDebuggerLogic.event.register('traceCurrentStepUpdate', function (error, step) { |
|
||||||
self.stepDetail.updateField('execution step', (error ? '-' : step)) |
|
||||||
}) |
|
||||||
|
|
||||||
this.vmDebuggerLogic.event.register('traceMemExpandUpdate', function (error, addmem) { |
|
||||||
self.stepDetail.updateField('add memory', (error ? '-' : addmem)) |
|
||||||
}) |
|
||||||
|
|
||||||
this.vmDebuggerLogic.event.register('traceStepCostUpdate', function (error, gas) { |
|
||||||
self.stepDetail.updateField('gas', (error ? '-' : gas)) |
|
||||||
}) |
|
||||||
|
|
||||||
this.vmDebuggerLogic.event.register('traceCurrentCalledAddressAtUpdate', function (error, address) { |
|
||||||
self.stepDetail.updateField('loaded address', (error ? '-' : address)) |
|
||||||
}) |
|
||||||
|
|
||||||
this.vmDebuggerLogic.event.register('traceRemainingGasUpdate', function (error, remainingGas) { |
|
||||||
self.stepDetail.updateField('remaining gas', (error ? '-' : remainingGas)) |
|
||||||
}) |
|
||||||
|
|
||||||
this.vmDebuggerLogic.event.register('indexUpdate', function (index) { |
|
||||||
self.stepDetail.updateField('vm trace step', index) |
|
||||||
}) |
|
||||||
|
|
||||||
this.solidityState = new SolidityState() |
|
||||||
this.vmDebuggerLogic.event.register('solidityState', this.solidityState.update.bind(this.solidityState)) |
|
||||||
this.vmDebuggerLogic.event.register('solidityStateMessage', this.solidityState.setMessage.bind(this.solidityState)) |
|
||||||
this.vmDebuggerLogic.event.register('solidityStateUpdating', this.solidityState.setUpdating.bind(this.solidityState)) |
|
||||||
|
|
||||||
this.solidityLocals = new SolidityLocals() |
|
||||||
this.solidityLocals.event.register('solidityLocalsLoadMore', (cursor) => { |
|
||||||
this.vmDebuggerLogic.event.trigger('solidityLocalsLoadMore', [cursor]) |
|
||||||
}) |
|
||||||
this.vmDebuggerLogic.event.register('solidityLocals', this.solidityLocals.update.bind(this.solidityLocals)) |
|
||||||
this.vmDebuggerLogic.event.register('solidityLocalsMessage', this.solidityLocals.setMessage.bind(this.solidityLocals)) |
|
||||||
this.vmDebuggerLogic.event.register('solidityLocalsUpdating', this.solidityLocals.setUpdating.bind(this.solidityLocals)) |
|
||||||
this.vmDebuggerLogic.event.register('solidityLocalsLoadMoreCompleted', this.solidityLocals.loadMore.bind(this.solidityLocals)) |
|
||||||
|
|
||||||
this.returnValuesPanel = new DropdownPanel('Return Value', {json: true}) |
|
||||||
this.returnValuesPanel.data = {} |
|
||||||
this.vmDebuggerLogic.event.register('traceReturnValueUpdate', this.returnValuesPanel.update.bind(this.returnValuesPanel)) |
|
||||||
|
|
||||||
this.fullStoragesChangesPanel = new FullStoragesChangesPanel() |
|
||||||
this.addresses = [] |
|
||||||
|
|
||||||
this.vmDebuggerLogic.event.register('traceAddressesUpdate', function (_addresses) { |
|
||||||
self.fullStoragesChangesPanel.update({}) |
|
||||||
}) |
|
||||||
|
|
||||||
this.vmDebuggerLogic.event.register('traceStorageUpdate', this.fullStoragesChangesPanel.update.bind(this.fullStoragesChangesPanel)) |
|
||||||
|
|
||||||
this.vmDebuggerLogic.event.register('newTrace', () => { |
|
||||||
if (!self.view) return |
|
||||||
|
|
||||||
self.asmCode.basicPanel.show() |
|
||||||
self.stackPanel.basicPanel.show() |
|
||||||
self.functionPanel.basicPanel.show() |
|
||||||
self.storagePanel.basicPanel.show() |
|
||||||
self.memoryPanel.basicPanel.show() |
|
||||||
self.stepDetail.basicPanel.show() |
|
||||||
self.calldataPanel.basicPanel.show() |
|
||||||
self.callstackPanel.basicPanel.show() |
|
||||||
}) |
|
||||||
|
|
||||||
this.vmDebuggerLogic.event.register('newCallTree', () => { |
|
||||||
if (!self.view) return |
|
||||||
self.functionPanel.basicPanel.show() |
|
||||||
self.solidityLocals.basicPanel.show() |
|
||||||
self.solidityState.basicPanel.show() |
|
||||||
self.solidityPanel.hidden = false |
|
||||||
}) |
|
||||||
|
|
||||||
this.vmDebuggerLogic.start() |
|
||||||
} |
|
||||||
|
|
||||||
VmDebugger.prototype.renderHead = function () { |
|
||||||
this.solidityPanel = yo` |
|
||||||
<div class="w-100" hidden> |
|
||||||
${this.functionPanel.render()} |
|
||||||
${this.solidityLocals.render()} |
|
||||||
${this.solidityState.render()} |
|
||||||
</div> |
|
||||||
` |
|
||||||
const headView = yo` |
|
||||||
<div id="vmheadView" class="mt-1 px-0"> |
|
||||||
<div class="d-flex flex-column"> |
|
||||||
${this.solidityPanel} |
|
||||||
<div class="w-100">${this.asmCode.render()}</div> |
|
||||||
<div class="w-100">${this.stepDetail.render()}</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
` |
|
||||||
if (!this.headView) { |
|
||||||
this.headView = headView |
|
||||||
} |
|
||||||
return headView |
|
||||||
} |
|
||||||
|
|
||||||
VmDebugger.prototype.remove = function () { |
|
||||||
// used to stop listenning on event. bad and should be "refactored"
|
|
||||||
this.view = null |
|
||||||
} |
|
||||||
|
|
||||||
VmDebugger.prototype.render = function () { |
|
||||||
const view = yo` |
|
||||||
<div id="vmdebugger" class="px-2"> |
|
||||||
<div> |
|
||||||
${this.stackPanel.render()} |
|
||||||
${this.memoryPanel.render()} |
|
||||||
${this.storagePanel.render()} |
|
||||||
${this.callstackPanel.render()} |
|
||||||
${this.calldataPanel.render()} |
|
||||||
${this.returnValuesPanel.render()} |
|
||||||
${this.fullStoragesChangesPanel.render()} |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
` |
|
||||||
if (!this.view) { |
|
||||||
this.view = view |
|
||||||
} |
|
||||||
return view |
|
||||||
} |
|
||||||
|
|
||||||
module.exports = VmDebugger |
|
@ -1,76 +0,0 @@ |
|||||||
'use strict' |
|
||||||
module.exports = { |
|
||||||
truncate: { |
|
||||||
'white-space': 'nowrap', |
|
||||||
'overflow': 'hidden', |
|
||||||
'text-overflow': 'ellipsis', |
|
||||||
'margin-right': '5px' |
|
||||||
}, |
|
||||||
font: { |
|
||||||
'font-family': 'arial,sans-serif' |
|
||||||
}, |
|
||||||
statusMessage: { |
|
||||||
'margin-left': '15px' |
|
||||||
}, |
|
||||||
address: { |
|
||||||
'font-style': 'italic' |
|
||||||
}, |
|
||||||
instructionsList: { |
|
||||||
'width': '52%', |
|
||||||
'overflow-y': 'scroll', |
|
||||||
'max-height': '250px', |
|
||||||
'margin': '0', |
|
||||||
'margin-left': '10px', |
|
||||||
'padding': '2px' |
|
||||||
}, |
|
||||||
transactionInfo: { |
|
||||||
'margin-top': '5px' |
|
||||||
}, |
|
||||||
panel: { |
|
||||||
container: { |
|
||||||
'border': '1px solid', |
|
||||||
'width': '70%' |
|
||||||
}, |
|
||||||
tableContainer: { |
|
||||||
'height': '50%', |
|
||||||
'overflow-y': 'auto' |
|
||||||
}, |
|
||||||
table: { |
|
||||||
'padding': '5px' |
|
||||||
}, |
|
||||||
title: { |
|
||||||
'padding': '5px', |
|
||||||
'font-style': 'italic' |
|
||||||
} |
|
||||||
}, |
|
||||||
hidden: { |
|
||||||
'display': 'none' |
|
||||||
}, |
|
||||||
display: { |
|
||||||
'display': 'block' |
|
||||||
}, |
|
||||||
inline: { |
|
||||||
'display': 'inline-block' |
|
||||||
}, |
|
||||||
vmargin: { |
|
||||||
'margin-top': '10px', |
|
||||||
'margin-bottom': '10px' |
|
||||||
}, |
|
||||||
button: { |
|
||||||
'border-color': 'transparent', |
|
||||||
'border-radius': '3px', |
|
||||||
'border': '.3px solid hsla(0, 0%, 40%, 1)', |
|
||||||
'cursor': 'pointer', |
|
||||||
'min-height': '25px', |
|
||||||
'max-height': '25px', |
|
||||||
'padding': '3px', |
|
||||||
'min-width': '100px', |
|
||||||
'font-size': '12px', |
|
||||||
'overflow': 'hidden', |
|
||||||
'word-break': 'normal', |
|
||||||
'background-color': 'hsla(0, 0%, 40%, .2)', |
|
||||||
'color': 'hsla(0, 0%, 40%, 1)', |
|
||||||
'margin': '3px', |
|
||||||
'text-decoration': 'none' |
|
||||||
} |
|
||||||
} |
|
@ -1,31 +0,0 @@ |
|||||||
'use strict' |
|
||||||
module.exports = { |
|
||||||
title: { |
|
||||||
'border': '1px solid #dadada', |
|
||||||
'background-color': 'white', |
|
||||||
'width': '100%', |
|
||||||
'color': '#363f47', |
|
||||||
'margin-top': '5px', |
|
||||||
'cursor': 'pointer' |
|
||||||
}, |
|
||||||
titleInner: { |
|
||||||
'display': 'inline-block' |
|
||||||
}, |
|
||||||
content: { |
|
||||||
'color': '#111111', |
|
||||||
'width': '100%', |
|
||||||
'min-height': '20px' |
|
||||||
}, |
|
||||||
inner: { |
|
||||||
'padding': '2px', |
|
||||||
'word-break': 'break-all' |
|
||||||
}, |
|
||||||
copyBtn: { |
|
||||||
'float': 'right', |
|
||||||
'margin-top': '3px' |
|
||||||
}, |
|
||||||
caret: { |
|
||||||
'margin-left': '10px', |
|
||||||
'margin-right': '10px' |
|
||||||
} |
|
||||||
} |
|
@ -1,6 +0,0 @@ |
|||||||
'use strict' |
|
||||||
module.exports = { |
|
||||||
rule: { |
|
||||||
'width': '100%' |
|
||||||
} |
|
||||||
} |
|
@ -1,30 +0,0 @@ |
|||||||
'use strict' |
|
||||||
module.exports = { |
|
||||||
cssUl: { |
|
||||||
'list-style-type': 'none', |
|
||||||
'-webkit-margin-before': '0px', |
|
||||||
'-webkit-margin-after': '0px', |
|
||||||
'-webkit-margin-start': '0px', |
|
||||||
'-webkit-margin-end': '0px', |
|
||||||
'-webkit-padding-start': '0px' |
|
||||||
}, |
|
||||||
cssLi: { |
|
||||||
'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' |
|
||||||
}, |
|
||||||
caret: { |
|
||||||
'margin-top': '3px', |
|
||||||
'width': '10px' |
|
||||||
}, |
|
||||||
data: { |
|
||||||
} |
|
||||||
} |
|
@ -1,17 +0,0 @@ |
|||||||
'use strict' |
|
||||||
var DropdownPanel = require('./DropdownPanel') |
|
||||||
var yo = require('yo-yo') |
|
||||||
|
|
||||||
function CalldataPanel () { |
|
||||||
this.basicPanel = new DropdownPanel('Call Data', {json: true}) |
|
||||||
} |
|
||||||
|
|
||||||
CalldataPanel.prototype.update = function (calldata) { |
|
||||||
this.basicPanel.update(calldata) |
|
||||||
} |
|
||||||
|
|
||||||
CalldataPanel.prototype.render = function () { |
|
||||||
return yo`<div id='calldatapanel' >${this.basicPanel.render()}</div>` |
|
||||||
} |
|
||||||
|
|
||||||
module.exports = CalldataPanel |
|
@ -1,18 +0,0 @@ |
|||||||
'use strict' |
|
||||||
var DropdownPanel = require('./DropdownPanel') |
|
||||||
var yo = require('yo-yo') |
|
||||||
|
|
||||||
function CallstackPanel () { |
|
||||||
this.basicPanel = new DropdownPanel('Call Stack', {json: true}) |
|
||||||
} |
|
||||||
|
|
||||||
CallstackPanel.prototype.update = function (calldata) { |
|
||||||
this.basicPanel.update(calldata) |
|
||||||
} |
|
||||||
|
|
||||||
CallstackPanel.prototype.render = function () { |
|
||||||
return yo`<div id='callstackpanel' >${this.basicPanel.render()}</div>` |
|
||||||
} |
|
||||||
|
|
||||||
module.exports = CallstackPanel |
|
||||||
|
|
@ -1,75 +0,0 @@ |
|||||||
'use strict' |
|
||||||
var style = require('../styles/basicStyles') |
|
||||||
var yo = require('yo-yo') |
|
||||||
var DropdownPanel = require('./DropdownPanel') |
|
||||||
var EventManager = require('../../../../../lib/events') |
|
||||||
var csjs = require('csjs-inject') |
|
||||||
|
|
||||||
var css = csjs` |
|
||||||
.instructions { |
|
||||||
overflow-y: scroll; |
|
||||||
max-height: 130px; |
|
||||||
} |
|
||||||
` |
|
||||||
function CodeListView () { |
|
||||||
this.event = new EventManager() |
|
||||||
this.code |
|
||||||
this.address |
|
||||||
this.itemSelected |
|
||||||
this.basicPanel = new DropdownPanel('Instructions', {json: false, displayContentOnly: true}) |
|
||||||
this.basicPanel.event.register('hide', () => { |
|
||||||
this.event.trigger('hide', []) |
|
||||||
}) |
|
||||||
this.basicPanel.event.register('show', () => { |
|
||||||
this.event.trigger('show', []) |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
CodeListView.prototype.render = function () { |
|
||||||
this.view = yo`<div id='asmcodes' >${this.basicPanel.render({height: style.instructionsList.height})}</div>` |
|
||||||
return this.view |
|
||||||
} |
|
||||||
|
|
||||||
CodeListView.prototype.indexChanged = function (index) { |
|
||||||
if (index < 0) return |
|
||||||
if (this.itemSelected) { |
|
||||||
this.itemSelected.removeAttribute('selected') |
|
||||||
this.itemSelected.removeAttribute('style') |
|
||||||
if (this.itemSelected.firstChild) { |
|
||||||
this.itemSelected.firstChild.removeAttribute('style') |
|
||||||
} |
|
||||||
} |
|
||||||
let codeView = this.view.querySelector('#asmitems') |
|
||||||
this.itemSelected = codeView.children[index] |
|
||||||
this.itemSelected.style.setProperty('border-color', 'var(--primary)') |
|
||||||
this.itemSelected.style.setProperty('border-style', 'solid') |
|
||||||
this.itemSelected.setAttribute('selected', 'selected') |
|
||||||
codeView.scrollTop = this.itemSelected.offsetTop - parseInt(codeView.offsetTop) |
|
||||||
} |
|
||||||
|
|
||||||
CodeListView.prototype.reset = function () { |
|
||||||
this.changed([], '', -1) |
|
||||||
} |
|
||||||
|
|
||||||
CodeListView.prototype.changed = function (code, address, index) { |
|
||||||
if (this.address === address) { |
|
||||||
return this.indexChanged(index) |
|
||||||
} |
|
||||||
this.code = code |
|
||||||
this.address = address |
|
||||||
this.basicPanel.setContent(this.renderAssemblyItems()) |
|
||||||
this.indexChanged(index) |
|
||||||
} |
|
||||||
|
|
||||||
CodeListView.prototype.renderAssemblyItems = function () { |
|
||||||
if (this.code) { |
|
||||||
var codeView = this.code.map(function (item, i) { |
|
||||||
return yo`<div class="px-1" key=${i} value=${i}><span>${item}</span></div>` |
|
||||||
}) |
|
||||||
return yo`<div class="pl-2 my-1 small ${css.instructions}" id='asmitems' ref='itemsList'>
|
|
||||||
${codeView} |
|
||||||
</div>` |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
module.exports = CodeListView |
|
@ -1,189 +0,0 @@ |
|||||||
'use strict' |
|
||||||
const yo = require('yo-yo') |
|
||||||
const copyToClipboard = require('../../../../ui/copy-to-clipboard') |
|
||||||
const EventManager = require('../../../../../lib/events') |
|
||||||
const TreeView = require('../../../../ui/TreeView') // TODO setup a direct reference to the UI components
|
|
||||||
|
|
||||||
const csjs = require('csjs-inject') |
|
||||||
|
|
||||||
const css = csjs` |
|
||||||
.title { |
|
||||||
display: flex; |
|
||||||
align-items: center; |
|
||||||
} |
|
||||||
.name { |
|
||||||
font-weight: bold; |
|
||||||
} |
|
||||||
.nameDetail { |
|
||||||
font-weight: bold; |
|
||||||
margin-left: 3px; |
|
||||||
} |
|
||||||
.icon { |
|
||||||
margin-right: 5%; |
|
||||||
} |
|
||||||
.eyeButton { |
|
||||||
margin: 3px; |
|
||||||
} |
|
||||||
.dropdownpanel { |
|
||||||
width: 100%; |
|
||||||
word-break: break-word; |
|
||||||
} |
|
||||||
.dropdownrawcontent { |
|
||||||
padding: 2px; |
|
||||||
word-break: break-word; |
|
||||||
} |
|
||||||
.message { |
|
||||||
padding: 2px; |
|
||||||
word-break: break-word; |
|
||||||
} |
|
||||||
.refresh { |
|
||||||
display: none; |
|
||||||
margin-left: 4px; |
|
||||||
margin-top: 4px;
|
|
||||||
animation: spin 2s linear infinite; |
|
||||||
} |
|
||||||
` |
|
||||||
|
|
||||||
function DropdownPanel (_name, _opts) { |
|
||||||
this.event = new EventManager() |
|
||||||
if (!_opts) { |
|
||||||
_opts = {} |
|
||||||
} |
|
||||||
this.name = _name |
|
||||||
this.header = '' |
|
||||||
this.json = _opts.json |
|
||||||
this.displayContentOnly = _opts.displayContentOnly |
|
||||||
if (this.json) { |
|
||||||
this.treeView = new TreeView(_opts) |
|
||||||
} |
|
||||||
this.view |
|
||||||
} |
|
||||||
|
|
||||||
DropdownPanel.prototype.setMessage = function (message) { |
|
||||||
if (!this.view) return |
|
||||||
this.view.querySelector('.dropdownpanel .dropdownrawcontent').style.display = 'none' |
|
||||||
this.view.querySelector('.dropdownpanel .dropdowncontent').style.display = 'none' |
|
||||||
this.view.querySelector('.dropdownpanel > i').style.display = 'none' |
|
||||||
this.message(message) |
|
||||||
} |
|
||||||
|
|
||||||
DropdownPanel.prototype.setLoading = function () { |
|
||||||
if (!this.view) return |
|
||||||
this.view.querySelector('.dropdownpanel .dropdownrawcontent').style.display = 'none' |
|
||||||
this.view.querySelector('.dropdownpanel .dropdowncontent').style.display = 'none' |
|
||||||
this.view.querySelector('.dropdownpanel > i').style.display = 'inline-block' |
|
||||||
this.message('') |
|
||||||
} |
|
||||||
|
|
||||||
DropdownPanel.prototype.setUpdating = function () { |
|
||||||
if (!this.view) return |
|
||||||
} |
|
||||||
|
|
||||||
DropdownPanel.prototype.update = function (_data, _header) { |
|
||||||
if (!this.view) return |
|
||||||
this.view.querySelector('.dropdownpanel > i').style.display = 'none' |
|
||||||
this.view.querySelector('.dropdownpanel .dropdowncontent').style.display = 'block' |
|
||||||
this.view.querySelector('.dropdownpanel .dropdownrawcontent').innerText = JSON.stringify(_data, null, '\t') |
|
||||||
if (!this.displayContentOnly) { |
|
||||||
this.view.querySelector('.title i.fa-copy').style.display = 'block' |
|
||||||
this.view.querySelector('.title span').innerText = _header || ' ' |
|
||||||
} |
|
||||||
this.message('') |
|
||||||
if (this.json) { |
|
||||||
this.treeView.update(_data) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
DropdownPanel.prototype.setContent = function (node) { |
|
||||||
if (!this.view) return |
|
||||||
yo.update(this.view, this.render(null, node)) |
|
||||||
} |
|
||||||
|
|
||||||
DropdownPanel.prototype.copyClipboard = function () { |
|
||||||
const content = this.view.querySelector('.dropdownpanel .dropdownrawcontent') |
|
||||||
return content.innerText ? content.innerText : content.textContent |
|
||||||
} |
|
||||||
|
|
||||||
DropdownPanel.prototype.render = function (overridestyle, node) { |
|
||||||
var content = yo`<div>Empty</div>` |
|
||||||
if (this.json) { |
|
||||||
content = this.treeView.render({}) |
|
||||||
} |
|
||||||
overridestyle === undefined ? {} : overridestyle |
|
||||||
var self = this |
|
||||||
var contentNode = yo` |
|
||||||
<div class='dropdownpanel ${css.dropdownpanel}' style='display:none'> |
|
||||||
<i class="${css.refresh} fas fa-sync" aria-hidden="true"></i> |
|
||||||
<div class='dropdowncontent'>${node || content}</div> |
|
||||||
<div class='dropdownrawcontent' style='display:none'></div> |
|
||||||
<div class='message' style='display:none'></div> |
|
||||||
</div>` |
|
||||||
var title = !self.displayContentOnly ? yo`<div class="${css.title} py-0 px-1 title">
|
|
||||||
<div class="${css.icon} fas fa-caret-right" onclick=${function () { self.toggle() }} ></div> |
|
||||||
<div class="${css.name}" onclick=${function () { self.toggle() }} >${this.name}</div><span class="${css.nameDetail}" onclick=${function () { self.toggle() }} ></span> |
|
||||||
${copyToClipboard(() => this.copyClipboard())} |
|
||||||
</div>` : yo`<div></div>` |
|
||||||
|
|
||||||
var view = yo` |
|
||||||
<div class="border rounded px-1 mt-1 bg-light"> |
|
||||||
<style> |
|
||||||
@-moz-keyframes spin { |
|
||||||
to { -moz-transform: rotate(359deg); } |
|
||||||
} |
|
||||||
@-webkit-keyframes spin { |
|
||||||
to { -webkit-transform: rotate(359deg); } |
|
||||||
} |
|
||||||
@keyframes spin { |
|
||||||
to {transform:rotate(359deg);} |
|
||||||
} |
|
||||||
</style> |
|
||||||
${title} |
|
||||||
${contentNode} |
|
||||||
</div>` |
|
||||||
if (!this.view) { |
|
||||||
this.view = view |
|
||||||
} |
|
||||||
if (self.displayContentOnly) contentNode.style.display = 'block' |
|
||||||
return view |
|
||||||
} |
|
||||||
|
|
||||||
DropdownPanel.prototype.toggle = function () { |
|
||||||
var el = this.view.querySelector('.dropdownpanel') |
|
||||||
var caret = this.view.querySelector('.title').firstElementChild |
|
||||||
if (el.style.display === '') { |
|
||||||
el.style.display = 'none' |
|
||||||
caret.className = `${css.icon} fas fa-caret-right` |
|
||||||
this.event.trigger('hide', []) |
|
||||||
} else { |
|
||||||
el.style.display = '' |
|
||||||
caret.className = `${css.icon} fas fa-caret-down` |
|
||||||
this.event.trigger('show', []) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
DropdownPanel.prototype.hide = function () { |
|
||||||
if (!(this.view && !this.displayContentOnly)) return |
|
||||||
var caret = this.view.querySelector('.title').firstElementChild |
|
||||||
var el = this.view.querySelector('.dropdownpanel') |
|
||||||
el.style.display = 'none' |
|
||||||
caret.className = `${css.icon} fas fa-caret-right` |
|
||||||
this.event.trigger('hide', []) |
|
||||||
} |
|
||||||
|
|
||||||
DropdownPanel.prototype.show = function () { |
|
||||||
if (!(this.view && !this.displayContentOnly)) return |
|
||||||
var caret = this.view.querySelector('.title').firstElementChild |
|
||||||
var el = this.view.querySelector('.dropdownpanel') |
|
||||||
el.style.display = '' |
|
||||||
caret.className = `${css.icon} fas fa-caret-down` |
|
||||||
this.event.trigger('show', []) |
|
||||||
} |
|
||||||
|
|
||||||
DropdownPanel.prototype.message = function (message) { |
|
||||||
if (!this.view) return |
|
||||||
var mes = this.view.querySelector('.dropdownpanel .message') |
|
||||||
mes.innerText = message |
|
||||||
mes.style.display = (message === '') ? 'none' : 'block' |
|
||||||
} |
|
||||||
|
|
||||||
module.exports = DropdownPanel |
|
@ -1,21 +0,0 @@ |
|||||||
var DropdownPanel = require('./DropdownPanel') |
|
||||||
var yo = require('yo-yo') |
|
||||||
|
|
||||||
function FullStoragesChanges () { |
|
||||||
this.view |
|
||||||
this.basicPanel = new DropdownPanel('Full Storages Changes', {json: true}) |
|
||||||
} |
|
||||||
|
|
||||||
FullStoragesChanges.prototype.update = function (storageData) { |
|
||||||
this.basicPanel.update(storageData) |
|
||||||
} |
|
||||||
|
|
||||||
FullStoragesChanges.prototype.render = function () { |
|
||||||
var view = yo`<div id='fullstorageschangespanel' >${this.basicPanel.render()}</div>` |
|
||||||
if (!this.view) { |
|
||||||
this.view = view |
|
||||||
} |
|
||||||
return view |
|
||||||
} |
|
||||||
|
|
||||||
module.exports = FullStoragesChanges |
|
@ -1,17 +0,0 @@ |
|||||||
'use strict' |
|
||||||
var DropdownPanel = require('./DropdownPanel') |
|
||||||
var yo = require('yo-yo') |
|
||||||
|
|
||||||
function FunctionPanel () { |
|
||||||
this.basicPanel = new DropdownPanel('Function Stack', {json: true, displayContentOnly: false}) |
|
||||||
} |
|
||||||
|
|
||||||
FunctionPanel.prototype.update = function (calldata) { |
|
||||||
this.basicPanel.update(calldata) |
|
||||||
} |
|
||||||
|
|
||||||
FunctionPanel.prototype.render = function () { |
|
||||||
return yo`<div id="FunctionPanel">${this.basicPanel.render()}</div>` |
|
||||||
} |
|
||||||
|
|
||||||
module.exports = FunctionPanel |
|
@ -1,21 +0,0 @@ |
|||||||
'use strict' |
|
||||||
var DropdownPanel = require('./DropdownPanel') |
|
||||||
var yo = require('yo-yo') |
|
||||||
|
|
||||||
function MemoryPanel () { |
|
||||||
this.basicPanel = new DropdownPanel('Memory', { |
|
||||||
json: true, |
|
||||||
css: { |
|
||||||
'font-family': 'monospace' |
|
||||||
}}) |
|
||||||
} |
|
||||||
|
|
||||||
MemoryPanel.prototype.update = function (calldata) { |
|
||||||
this.basicPanel.update(calldata) |
|
||||||
} |
|
||||||
|
|
||||||
MemoryPanel.prototype.render = function () { |
|
||||||
return yo`<div id="memorypanel">${this.basicPanel.render()}</div>` |
|
||||||
} |
|
||||||
|
|
||||||
module.exports = MemoryPanel |
|
@ -1,59 +0,0 @@ |
|||||||
'use strict' |
|
||||||
var EventManager = require('../../../../../lib/events') |
|
||||||
var DropdownPanel = require('./DropdownPanel') |
|
||||||
var solidityTypeFormatter = require('./utils/SolidityTypeFormatter') |
|
||||||
var yo = require('yo-yo') |
|
||||||
|
|
||||||
class SolidityLocals { |
|
||||||
|
|
||||||
constructor () { |
|
||||||
this.event = new EventManager() |
|
||||||
this.basicPanel = new DropdownPanel('Solidity Locals', { |
|
||||||
json: true, |
|
||||||
formatSelf: solidityTypeFormatter.formatSelf, |
|
||||||
extractData: solidityTypeFormatter.extractData, |
|
||||||
loadMore: (cursor) => { |
|
||||||
this.event.trigger('solidityLocalsLoadMore', [cursor]) |
|
||||||
} |
|
||||||
}) |
|
||||||
this.view |
|
||||||
this._data = null |
|
||||||
} |
|
||||||
|
|
||||||
update (data) { |
|
||||||
this._data = data |
|
||||||
this.basicPanel.update(this._data) |
|
||||||
} |
|
||||||
|
|
||||||
loadMore (data) { |
|
||||||
this._data = this.mergeLocals(data, this._data) |
|
||||||
this.basicPanel.update(this._data) |
|
||||||
} |
|
||||||
|
|
||||||
setMessage (message) { |
|
||||||
this.basicPanel.setMessage(message) |
|
||||||
} |
|
||||||
|
|
||||||
setUpdating () { |
|
||||||
this.basicPanel.setUpdating() |
|
||||||
} |
|
||||||
|
|
||||||
mergeLocals (locals1, locals2) { |
|
||||||
Object.keys(locals2).map(item => { |
|
||||||
if (locals2[item].cursor && (parseInt(locals2[item].cursor) < parseInt(locals1[item].cursor))) { |
|
||||||
locals2[item] = { |
|
||||||
...locals1[item], |
|
||||||
value: [...locals2[item].value, ...locals1[item].value] |
|
||||||
} |
|
||||||
} |
|
||||||
}) |
|
||||||
return locals2 |
|
||||||
} |
|
||||||
|
|
||||||
render () { |
|
||||||
this.view = yo`<div id='soliditylocals' data-id="solidityLocals">${this.basicPanel.render()}</div>` |
|
||||||
return this.view |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
module.exports = SolidityLocals |
|
@ -1,36 +0,0 @@ |
|||||||
var DropdownPanel = require('./DropdownPanel') |
|
||||||
var solidityTypeFormatter = require('./utils/SolidityTypeFormatter') |
|
||||||
var yo = require('yo-yo') |
|
||||||
|
|
||||||
function SolidityState () { |
|
||||||
this.basicPanel = new DropdownPanel('Solidity State', { |
|
||||||
json: true, |
|
||||||
// TODO: used by TreeView ui
|
|
||||||
formatSelf: solidityTypeFormatter.formatSelf, |
|
||||||
extractData: solidityTypeFormatter.extractData |
|
||||||
}) |
|
||||||
this.view |
|
||||||
} |
|
||||||
|
|
||||||
SolidityState.prototype.update = function (data) { |
|
||||||
this.basicPanel.update(data) |
|
||||||
} |
|
||||||
|
|
||||||
SolidityState.prototype.setMessage = function (message) { |
|
||||||
this.basicPanel.setMessage(message) |
|
||||||
} |
|
||||||
|
|
||||||
SolidityState.prototype.setUpdating = function () { |
|
||||||
this.basicPanel.setUpdating() |
|
||||||
} |
|
||||||
|
|
||||||
SolidityState.prototype.render = function () { |
|
||||||
if (this.view) return |
|
||||||
this.view = yo` |
|
||||||
<div id='soliditystate' > |
|
||||||
${this.basicPanel.render()} |
|
||||||
</div>` |
|
||||||
return this.view |
|
||||||
} |
|
||||||
|
|
||||||
module.exports = SolidityState |
|
@ -1,17 +0,0 @@ |
|||||||
'use strict' |
|
||||||
var DropdownPanel = require('./DropdownPanel') |
|
||||||
var yo = require('yo-yo') |
|
||||||
|
|
||||||
function StackPanel () { |
|
||||||
this.basicPanel = new DropdownPanel('Stack', {json: true, displayContentOnly: false}) |
|
||||||
} |
|
||||||
|
|
||||||
StackPanel.prototype.update = function (calldata) { |
|
||||||
this.basicPanel.update(calldata) |
|
||||||
} |
|
||||||
|
|
||||||
StackPanel.prototype.render = function () { |
|
||||||
return yo`<div id="stackpanel">${this.basicPanel.render()}</div>` |
|
||||||
} |
|
||||||
|
|
||||||
module.exports = StackPanel |
|
@ -1,23 +0,0 @@ |
|||||||
var yo = require('yo-yo') |
|
||||||
var DropdownPanel = require('./DropdownPanel') |
|
||||||
|
|
||||||
function StepDetail () { |
|
||||||
this.basicPanel = new DropdownPanel('Step details', {json: true, displayContentOnly: false}) |
|
||||||
this.detail = { 'vm trace step': '-', 'execution step': '-', 'add memory': '', 'gas': '', 'remaining gas': '-', 'loaded address': '-' } |
|
||||||
} |
|
||||||
|
|
||||||
StepDetail.prototype.reset = function () { |
|
||||||
this.detail = { 'vm trace step': '-', 'execution step': '-', 'add memory': '', 'gas': '', 'remaining gas': '-', 'loaded address': '-' } |
|
||||||
this.basicPanel.update(this.detail) |
|
||||||
} |
|
||||||
|
|
||||||
StepDetail.prototype.updateField = function (key, value) { |
|
||||||
this.detail[key] = value |
|
||||||
this.basicPanel.update(this.detail) |
|
||||||
} |
|
||||||
|
|
||||||
StepDetail.prototype.render = function () { |
|
||||||
return yo`<div id='stepdetail' data-id="stepdetail">${this.basicPanel.render()}</div>` |
|
||||||
} |
|
||||||
|
|
||||||
module.exports = StepDetail |
|
@ -1,17 +0,0 @@ |
|||||||
'use strict' |
|
||||||
var DropdownPanel = require('./DropdownPanel') |
|
||||||
var yo = require('yo-yo') |
|
||||||
|
|
||||||
function StoragePanel (_parent, _traceManager) { |
|
||||||
this.basicPanel = new DropdownPanel('Storage', {json: true}) |
|
||||||
} |
|
||||||
|
|
||||||
StoragePanel.prototype.update = function (storage, header) { |
|
||||||
this.basicPanel.update(storage, header) |
|
||||||
} |
|
||||||
|
|
||||||
StoragePanel.prototype.render = function () { |
|
||||||
return yo`<div id='storagepanel' >${this.basicPanel.render()}</div>` |
|
||||||
} |
|
||||||
|
|
||||||
module.exports = StoragePanel |
|
@ -1,77 +0,0 @@ |
|||||||
var yo = require('yo-yo') |
|
||||||
var BN = require('ethereumjs-util').BN |
|
||||||
|
|
||||||
module.exports = { |
|
||||||
formatSelf: formatSelf, |
|
||||||
extractData: extractData |
|
||||||
} |
|
||||||
|
|
||||||
function formatSelf (key, data) { |
|
||||||
const style = fontColor(data) |
|
||||||
const keyStyle = data.isProperty ? 'color: var(--info)' : '' |
|
||||||
if (data.type === 'string') { |
|
||||||
data.self = JSON.stringify(data.self) |
|
||||||
} |
|
||||||
return yo `<label class="mb-0" style='${keyStyle};white-space:pre-wrap;'> ${' ' + key}:<label class="mb-0" style=${style}>${' ' + data.self}</label><label style='font-style:italic'> ${data.isProperty || !data.type ? '' : ' ' + data.type}</label></label>` |
|
||||||
} |
|
||||||
|
|
||||||
function extractData (item, parent, key) { |
|
||||||
var ret = {} |
|
||||||
if (item.isProperty) { |
|
||||||
return item |
|
||||||
} |
|
||||||
if (item.type.lastIndexOf(']') === item.type.length - 1) { |
|
||||||
ret.children = (item.value || []).map(function (item, index) { |
|
||||||
return {key: index, value: item} |
|
||||||
}) |
|
||||||
ret.children.unshift({ |
|
||||||
key: 'length', |
|
||||||
value: { |
|
||||||
self: (new BN(item.length.replace('0x', ''), 16)).toString(10), |
|
||||||
type: 'uint', |
|
||||||
isProperty: true |
|
||||||
} |
|
||||||
}) |
|
||||||
ret.isArray = true |
|
||||||
ret.self = parent.isArray ? '' : item.type |
|
||||||
ret.cursor = item.cursor |
|
||||||
ret.hasNext = item.hasNext |
|
||||||
} else if (item.type.indexOf('struct') === 0) { |
|
||||||
ret.children = Object.keys((item.value || {})).map(function (key) { |
|
||||||
return {key: key, value: item.value[key]} |
|
||||||
}) |
|
||||||
ret.self = item.type |
|
||||||
ret.isStruct = true |
|
||||||
} else if (item.type.indexOf('mapping') === 0) { |
|
||||||
ret.children = Object.keys((item.value || {})).map(function (key) { |
|
||||||
return {key: key, value: item.value[key]} |
|
||||||
}) |
|
||||||
ret.isMapping = true |
|
||||||
ret.self = item.type |
|
||||||
} else { |
|
||||||
ret.children = null |
|
||||||
ret.self = item.value |
|
||||||
ret.type = item.type |
|
||||||
} |
|
||||||
return ret |
|
||||||
} |
|
||||||
|
|
||||||
function fontColor (data) { |
|
||||||
let color = 'var(--primary)' |
|
||||||
if (data.isArray || data.isStruct || data.isMapping) { |
|
||||||
color = 'var(--info)' |
|
||||||
} else if ( |
|
||||||
data.type.indexOf('uint') === 0 || |
|
||||||
data.type.indexOf('int') === 0 || |
|
||||||
data.type.indexOf('bool') === 0 || |
|
||||||
data.type.indexOf('enum') === 0 |
|
||||||
) { |
|
||||||
color = 'var(--green)' |
|
||||||
} else if (data.type === 'string') { |
|
||||||
color = 'var(--teal)' |
|
||||||
} else if (data.self == 0x0) { // eslint-disable-line
|
|
||||||
color = 'var(--gray)' |
|
||||||
} |
|
||||||
return 'color:' + color |
|
||||||
} |
|
||||||
|
|
Loading…
Reference in new issue