parent
a47d7e824f
commit
9546b78ffa
@ -0,0 +1,184 @@ |
|||||||
|
'use strict' |
||||||
|
var remixLib = require('remix-lib') |
||||||
|
var EventManager = remixLib.EventManager |
||||||
|
var yo = require('yo-yo') |
||||||
|
|
||||||
|
var csjs = require('csjs-inject') |
||||||
|
var styleGuide = require('../../ui/styles-guide/theme-chooser') |
||||||
|
var styles = styleGuide.chooser() |
||||||
|
|
||||||
|
var css = csjs` |
||||||
|
.buttons { |
||||||
|
display: flex; |
||||||
|
flex-wrap: wrap; |
||||||
|
} |
||||||
|
.stepButtons { |
||||||
|
width: 100%; |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
} |
||||||
|
.stepButton { |
||||||
|
${styles.rightPanel.debuggerTab.button_Debugger} |
||||||
|
} |
||||||
|
.jumpButtons { |
||||||
|
width: 100%; |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
} |
||||||
|
.jumpButton { |
||||||
|
${styles.rightPanel.debuggerTab.button_Debugger} |
||||||
|
} |
||||||
|
.navigator { |
||||||
|
color: ${styles.rightPanel.debuggerTab.text_Primary}; |
||||||
|
} |
||||||
|
.navigator:hover { |
||||||
|
color: ${styles.rightPanel.debuggerTab.button_Debugger_icon_HoverColor}; |
||||||
|
} |
||||||
|
` |
||||||
|
|
||||||
|
function ButtonNavigator (_parent, _traceManager) { |
||||||
|
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.traceManager = _traceManager |
||||||
|
this.currentCall = null |
||||||
|
this.revertionPoint = null |
||||||
|
|
||||||
|
_parent.event.register('indexChanged', this, (index) => { |
||||||
|
if (!this.view) return |
||||||
|
if (index < 0) return |
||||||
|
if (_parent.currentStepIndex !== index) return |
||||||
|
|
||||||
|
this.traceManager.buildCallPath(index, (error, callsPath) => { |
||||||
|
if (error) { |
||||||
|
console.log(error) |
||||||
|
resetWarning(this) |
||||||
|
} else { |
||||||
|
this.currentCall = callsPath[callsPath.length - 1] |
||||||
|
if (this.currentCall.reverted) { |
||||||
|
this.revertionPoint = this.currentCall.return |
||||||
|
this.view.querySelector('#reverted').style.display = 'block' |
||||||
|
this.view.querySelector('#reverted #outofgas').style.display = this.currentCall.outOfGas ? 'inline' : 'none' |
||||||
|
this.view.querySelector('#reverted #parenthasthrown').style.display = 'none' |
||||||
|
} else { |
||||||
|
var k = callsPath.length - 2 |
||||||
|
while (k >= 0) { |
||||||
|
var parent = callsPath[k] |
||||||
|
if (parent.reverted) { |
||||||
|
this.revertionPoint = parent.return |
||||||
|
this.view.querySelector('#reverted').style.display = 'block' |
||||||
|
this.view.querySelector('#reverted #parenthasthrown').style.display = parent ? 'inline' : 'none' |
||||||
|
this.view.querySelector('#reverted #outofgas').style.display = 'none' |
||||||
|
return |
||||||
|
} |
||||||
|
k-- |
||||||
|
} |
||||||
|
resetWarning(this) |
||||||
|
} |
||||||
|
} |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
this.view |
||||||
|
} |
||||||
|
|
||||||
|
module.exports = ButtonNavigator |
||||||
|
|
||||||
|
ButtonNavigator.prototype.render = function () { |
||||||
|
var self = this |
||||||
|
var view = yo`<div class="${css.buttons}">
|
||||||
|
<div class="${css.stepButtons}"> |
||||||
|
<button id='overback' title='Step over back' class='${css.navigator} ${css.stepButton} fa fa-reply' onclick=${function () { self.event.trigger('stepOverBack') }} disabled=${this.overBackDisabled} ></button> |
||||||
|
<button id='intoback' title='Step back' class='${css.navigator} ${css.stepButton} fa fa-level-up' onclick=${function () { self.event.trigger('stepIntoBack') }} disabled=${this.intoBackDisabled} ></button> |
||||||
|
<button id='intoforward' title='Step into' class='${css.navigator} ${css.stepButton} fa fa-level-down' onclick=${function () { self.event.trigger('stepIntoForward') }} disabled=${this.intoForwardDisabled} ></button> |
||||||
|
<button id='overforward' title='Step over forward' class='${css.navigator} ${css.stepButton} fa fa-share' onclick=${function () { self.event.trigger('stepOverForward') }} disabled=${this.overForwardDisabled} ></button> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="${css.jumpButtons}"> |
||||||
|
<button id='jumppreviousbreakpoint' title='Jump to the previous breakpoint' class='${css.navigator} ${css.jumpButton} fa fa-step-backward' onclick=${function () { self.event.trigger('jumpPreviousBreakpoint') }} disabled=${this.jumpPreviousBreakpointDisabled} ></button> |
||||||
|
<button id='jumpout' title='Jump out' class='${css.navigator} ${css.jumpButton} fa fa-eject' onclick=${function () { self.event.trigger('jumpOut') }} disabled=${this.jumpOutDisabled} ></button> |
||||||
|
<button id='jumpnextbreakpoint' title='Jump to the next breakpoint' class='${css.navigator} ${css.jumpButton} fa fa-step-forward' onclick=${function () { self.event.trigger('jumpNextBreakpoint') }} disabled=${this.jumpNextBreakpointDisabled} ></button> |
||||||
|
</div> |
||||||
|
<div id='reverted' style="display:none"> |
||||||
|
<button id='jumptoexception' title='Jump to exception' class='${css.navigator} ${css.button} fa fa-exclamation-triangle' onclick=${function () { self.event.trigger('jumpToException', [self.revertionPoint]) }} 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 |
||||||
|
resetWarning(this) |
||||||
|
} |
||||||
|
|
||||||
|
ButtonNavigator.prototype.stepChanged = function (step) { |
||||||
|
this.intoBackDisabled = step <= 0 |
||||||
|
this.overBackDisabled = step <= 0 |
||||||
|
if (!this.traceManager) { |
||||||
|
this.intoForwardDisabled = true |
||||||
|
this.overForwardDisabled = true |
||||||
|
} else { |
||||||
|
var self = this |
||||||
|
this.traceManager.getLength(function (error, length) { |
||||||
|
if (error) { |
||||||
|
self.reset() |
||||||
|
console.log(error) |
||||||
|
} else { |
||||||
|
self.jumpNextBreakpointDisabled = step >= length - 1 |
||||||
|
self.jumpPreviousBreakpointDisabled = step <= 0 |
||||||
|
self.intoForwardDisabled = step >= length - 1 |
||||||
|
self.overForwardDisabled = step >= length - 1 |
||||||
|
var stepOut = self.traceManager.findStepOut(step) |
||||||
|
self.jumpOutDisabled = stepOut === step |
||||||
|
} |
||||||
|
self.updateAll() |
||||||
|
}) |
||||||
|
} |
||||||
|
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') |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function resetWarning (self) { |
||||||
|
self.view.querySelector('#reverted #outofgas').style.display = 'none' |
||||||
|
self.view.querySelector('#reverted #parenthasthrown').style.display = 'none' |
||||||
|
self.view.querySelector('#reverted').style.display = 'none' |
||||||
|
} |
||||||
|
|
||||||
|
module.exports = ButtonNavigator |
@ -0,0 +1,75 @@ |
|||||||
|
'use strict' |
||||||
|
var remixLib = require('remix-lib') |
||||||
|
var EventManager = remixLib.EventManager |
||||||
|
var yo = require('yo-yo') |
||||||
|
|
||||||
|
class Slider { |
||||||
|
constructor (_traceManager, _stepOverride) { |
||||||
|
this.event = new EventManager() |
||||||
|
this.traceManager = _traceManager |
||||||
|
this.max |
||||||
|
this.disabled = true |
||||||
|
this.view |
||||||
|
this.solidityMode = false |
||||||
|
this.stepOverride = _stepOverride |
||||||
|
|
||||||
|
this.previousValue = null |
||||||
|
} |
||||||
|
|
||||||
|
render () { |
||||||
|
var self = this |
||||||
|
var view = yo`<div>
|
||||||
|
<input |
||||||
|
id='slider' |
||||||
|
style='width: 100%' |
||||||
|
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 |
||||||
|
} |
||||||
|
|
||||||
|
init (length) { |
||||||
|
var slider = this.view.querySelector('#slider') |
||||||
|
slider.setAttribute('max', length - 1) |
||||||
|
this.max = length - 1 |
||||||
|
this.updateDisabled(length === 0) |
||||||
|
this.disabled = length === 0 |
||||||
|
this.setValue(0) |
||||||
|
} |
||||||
|
|
||||||
|
onChange (event) { |
||||||
|
var value = parseInt(this.view.querySelector('#slider').value) |
||||||
|
if (this.stepOverride) { |
||||||
|
var correctedValue = this.stepOverride(value) |
||||||
|
if (correctedValue !== value) { |
||||||
|
this.setValue(correctedValue) |
||||||
|
value = correctedValue |
||||||
|
} |
||||||
|
} |
||||||
|
if (value === this.previousValue) return |
||||||
|
this.previousValue = value |
||||||
|
this.event.trigger('moved', [value]) |
||||||
|
} |
||||||
|
|
||||||
|
setValue (value) { |
||||||
|
this.view.querySelector('#slider').value = value |
||||||
|
} |
||||||
|
|
||||||
|
updateDisabled (disabled) { |
||||||
|
if (disabled) { |
||||||
|
this.view.querySelector('#slider').setAttribute('disabled', true) |
||||||
|
} else { |
||||||
|
this.view.querySelector('#slider').removeAttribute('disabled') |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
module.exports = Slider |
@ -0,0 +1,205 @@ |
|||||||
|
'use strict' |
||||||
|
var ButtonNavigator = require('./ButtonNavigator') |
||||||
|
var Slider = require('./Slider') |
||||||
|
var remixLib = require('remix-lib') |
||||||
|
var EventManager = remixLib.EventManager |
||||||
|
var yo = require('yo-yo') |
||||||
|
var util = remixLib.util |
||||||
|
|
||||||
|
function StepManager (_parent, _traceManager) { |
||||||
|
this.event = new EventManager() |
||||||
|
this.parent = _parent.debugger |
||||||
|
this.traceManager = _traceManager |
||||||
|
this.sourceMapByAddress = {} |
||||||
|
this.solidityMode = false |
||||||
|
|
||||||
|
var self = this |
||||||
|
this.parent.event.register('newTraceLoaded', this, function () { |
||||||
|
if (!this.slider) return |
||||||
|
self.traceManager.getLength(function (error, length) { |
||||||
|
if (error) { |
||||||
|
console.log(error) |
||||||
|
} else { |
||||||
|
self.slider.init(length) |
||||||
|
self.init() |
||||||
|
} |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
this.slider = new Slider(this.traceManager, (step) => { |
||||||
|
return this.solidityMode ? this.resolveToReducedTrace(step, 0) : step |
||||||
|
}) |
||||||
|
this.slider.event.register('moved', this, function (step) { |
||||||
|
self.sliderMoved(step) |
||||||
|
}) |
||||||
|
|
||||||
|
this.parent.callTree.event.register('callTreeReady', () => { |
||||||
|
if (!this.slider) return |
||||||
|
if (this.parent.callTree.functionCallStack.length) { |
||||||
|
this.jumpTo(this.parent.callTree.functionCallStack[0]) |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
this.buttonNavigator = new ButtonNavigator(_parent, this.traceManager) |
||||||
|
this.buttonNavigator.event.register('stepIntoBack', this, function () { |
||||||
|
self.stepIntoBack() |
||||||
|
}) |
||||||
|
this.buttonNavigator.event.register('stepIntoForward', this, function () { |
||||||
|
self.stepIntoForward() |
||||||
|
}) |
||||||
|
this.buttonNavigator.event.register('stepOverBack', this, function () { |
||||||
|
self.stepOverBack() |
||||||
|
}) |
||||||
|
this.buttonNavigator.event.register('stepOverForward', this, function () { |
||||||
|
self.stepOverForward() |
||||||
|
}) |
||||||
|
this.buttonNavigator.event.register('jumpOut', this, function () { |
||||||
|
self.jumpOut() |
||||||
|
}) |
||||||
|
this.buttonNavigator.event.register('jumpToException', this, function (exceptionIndex) { |
||||||
|
self.jumpTo(exceptionIndex) |
||||||
|
}) |
||||||
|
this.buttonNavigator.event.register('jumpNextBreakpoint', (exceptionIndex) => { |
||||||
|
self.parent.breakpointManager.jumpNextBreakpoint(_parent.currentStepIndex, true) |
||||||
|
}) |
||||||
|
this.buttonNavigator.event.register('jumpPreviousBreakpoint', (exceptionIndex) => { |
||||||
|
self.parent.breakpointManager.jumpPreviousBreakpoint(_parent.currentStepIndex, true) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
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.resolveToReducedTrace = function (value, incr) { |
||||||
|
if (this.parent.callTree.reducedTrace.length) { |
||||||
|
var nextSource = util.findClosestIndex(value, this.parent.callTree.reducedTrace) |
||||||
|
nextSource = nextSource + incr |
||||||
|
if (nextSource <= 0) { |
||||||
|
nextSource = 0 |
||||||
|
} else if (nextSource > this.parent.callTree.reducedTrace.length) { |
||||||
|
nextSource = this.parent.callTree.reducedTrace.length - 1 |
||||||
|
} |
||||||
|
return this.parent.callTree.reducedTrace[nextSource] |
||||||
|
} |
||||||
|
return value |
||||||
|
} |
||||||
|
|
||||||
|
StepManager.prototype.render = function () { |
||||||
|
return yo`<div>
|
||||||
|
${this.slider.render()} |
||||||
|
${this.buttonNavigator.render()} |
||||||
|
</div>` |
||||||
|
} |
||||||
|
|
||||||
|
StepManager.prototype.reset = function () { |
||||||
|
this.slider.setValue(0) |
||||||
|
this.currentStepIndex = 0 |
||||||
|
this.buttonNavigator.reset() |
||||||
|
} |
||||||
|
|
||||||
|
StepManager.prototype.init = function () { |
||||||
|
this.slider.setValue(0) |
||||||
|
this.changeState(0) |
||||||
|
} |
||||||
|
|
||||||
|
StepManager.prototype.newTraceAvailable = function () { |
||||||
|
this.init() |
||||||
|
} |
||||||
|
|
||||||
|
StepManager.prototype.jumpTo = function (step) { |
||||||
|
if (!this.traceManager.inRange(step)) { |
||||||
|
return |
||||||
|
} |
||||||
|
this.slider.setValue(step) |
||||||
|
this.changeState(step) |
||||||
|
} |
||||||
|
|
||||||
|
StepManager.prototype.sliderMoved = function (step) { |
||||||
|
if (!this.traceManager.inRange(step)) { |
||||||
|
return |
||||||
|
} |
||||||
|
this.changeState(step) |
||||||
|
} |
||||||
|
|
||||||
|
StepManager.prototype.stepIntoForward = function () { |
||||||
|
if (!this.traceManager.isLoaded()) { |
||||||
|
return |
||||||
|
} |
||||||
|
var step = this.currentStepIndex |
||||||
|
if (this.solidityMode) { |
||||||
|
step = this.resolveToReducedTrace(step, 1) |
||||||
|
} else { |
||||||
|
step += 1 |
||||||
|
} |
||||||
|
if (!this.traceManager.inRange(step)) { |
||||||
|
return |
||||||
|
} |
||||||
|
this.slider.setValue(step) |
||||||
|
this.changeState(step) |
||||||
|
} |
||||||
|
|
||||||
|
StepManager.prototype.stepIntoBack = function () { |
||||||
|
if (!this.traceManager.isLoaded()) { |
||||||
|
return |
||||||
|
} |
||||||
|
var step = this.currentStepIndex |
||||||
|
if (this.solidityMode) { |
||||||
|
step = this.resolveToReducedTrace(step, -1) |
||||||
|
} else { |
||||||
|
step -= 1 |
||||||
|
} |
||||||
|
if (!this.traceManager.inRange(step)) { |
||||||
|
return |
||||||
|
} |
||||||
|
this.slider.setValue(step) |
||||||
|
this.changeState(step) |
||||||
|
} |
||||||
|
|
||||||
|
StepManager.prototype.stepOverForward = function () { |
||||||
|
if (!this.traceManager.isLoaded()) { |
||||||
|
return |
||||||
|
} |
||||||
|
var step = this.traceManager.findStepOverForward(this.currentStepIndex) |
||||||
|
if (this.solidityMode) { |
||||||
|
step = this.resolveToReducedTrace(step, 1) |
||||||
|
} |
||||||
|
this.slider.setValue(step) |
||||||
|
this.changeState(step) |
||||||
|
} |
||||||
|
|
||||||
|
StepManager.prototype.stepOverBack = function () { |
||||||
|
if (!this.traceManager.isLoaded()) { |
||||||
|
return |
||||||
|
} |
||||||
|
var step = this.traceManager.findStepOverBack(this.currentStepIndex) |
||||||
|
if (this.solidityMode) { |
||||||
|
step = this.resolveToReducedTrace(step, -1) |
||||||
|
} |
||||||
|
this.slider.setValue(step) |
||||||
|
this.changeState(step) |
||||||
|
} |
||||||
|
|
||||||
|
StepManager.prototype.jumpOut = function () { |
||||||
|
if (!this.traceManager.isLoaded()) { |
||||||
|
return |
||||||
|
} |
||||||
|
var step = this.traceManager.findStepOut(this.currentStepIndex) |
||||||
|
if (this.solidityMode) { |
||||||
|
step = this.resolveToReducedTrace(step, 0) |
||||||
|
} |
||||||
|
this.slider.setValue(step) |
||||||
|
this.changeState(step) |
||||||
|
} |
||||||
|
|
||||||
|
StepManager.prototype.changeState = function (step) { |
||||||
|
this.currentStepIndex = step |
||||||
|
this.buttonNavigator.stepChanged(step) |
||||||
|
this.event.trigger('stepChanged', [step]) |
||||||
|
} |
||||||
|
|
||||||
|
module.exports = StepManager |
Loading…
Reference in new issue