Merge pull request #2949 from ethereum/custom-tooltips-debugger

Custom Tooltips for Debugger
pull/3040/head^2
Joseph Izang 2 years ago committed by GitHub
commit 6f90bb099d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      apps/remix-ide-e2e/src/tests/debugger.test.ts
  2. 26
      libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.css
  3. 113
      libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.tsx
  4. 12
      libs/remix-ui/debugger-ui/src/lib/debugger-ui.tsx
  5. 20
      libs/remix-ui/debugger-ui/src/lib/tx-browser/tx-browser.tsx
  6. 13
      libs/remix-ui/panel/src/lib/plugins/panel-header.tsx

@ -191,14 +191,14 @@ module.exports = {
.clickFunction('f - transact (not payable)', { types: 'uint256[] ', values: '[]' })
.debugTransaction(0)
.pause(2000)
.click('*[data-id="debuggerTransactionStartButton"]') // stop debugging
.click('*[id="debuggerTransactionStartButtonContainer"]') // stop debugging
.click('*[data-id="debugGeneratedSourcesLabel"]') // select debug with generated sources
.click('*[data-id="debuggerTransactionStartButton"]') // start debugging
.click('*[id="debuggerTransactionStartButtonContainer"]') // start debugging
.pause(2000)
.getEditorValue((content) => {
browser.assert.ok(content.indexOf('if slt(sub(dataEnd, headStart), 32)') !== -1, 'current displayed content is not a generated source')
})
.click('*[data-id="debuggerTransactionStartButton"]')
.click('*[id="debuggerTransactionStartButtonContainer"]')
},
// depends on Should debug using generated sources
'Should call the debugger api: getTrace #group4': function (browser: NightwatchBrowser) {

@ -6,16 +6,42 @@
width: 100%;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
}
.stepButton {
}
.stepButtonDisabled {
background-color: #005573;
border-color: #005573;
}
.stepButton:hover {
color: #fff;
background-color: #005573;
border-color: #005573;
}
.jumpButtons {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
}
.jumpButton {
}
.jumpButtonDisabled {
background-color: #005573;
border-color: #005573;
}
.jumButton:hover {
color: #fff;
background-color: #005573;
border-color: #005573;
}
.navigator {
}
.navigator:hover {

@ -1,4 +1,5 @@
import React, { useState, useEffect } from 'react' // eslint-disable-line
import { OverlayTrigger, Tooltip } from 'react-bootstrap'
import './button-navigator.css'
export const ButtonNavigation = ({ stepOverBack, stepIntoBack, stepIntoForward, stepOverForward, jumpOut, jumpPreviousBreakpoint, jumpNextBreakpoint, jumpToException, revertedReason, stepState, jumpOutDisabled }) => {
@ -50,19 +51,117 @@ export const ButtonNavigation = ({ stepOverBack, stepIntoBack, stepIntoForward,
})
}
const stepBtnStyle = 'd-flex align-items-center justify-content-center btn btn-primary btn-sm stepButton h-75 m-0 p-1'
const disableStepBtnStyle = 'stepButtonDisabled'
const jumpBtnStyle = 'd-flex align-items-center justify-content-center btn btn-primary btn-sm jumpButton h-75 m-0 p-1'
const disableJumpBtnStyle = 'jumpButtonDisabled'
return (
<div className="buttons">
<div className="stepButtons btn-group py-1">
<button id='overback' className='btn btn-primary btn-sm navigator stepButton fas fa-reply' title='Step over back' onClick={() => { stepOverBack && stepOverBack() }} disabled={state.overBackDisabled} ></button>
<button id='intoback' data-id="buttonNavigatorIntoBack" className='btn btn-primary btn-sm navigator stepButton fas fa-level-up-alt' title='Step back' onClick={() => { stepIntoBack && stepIntoBack() }} disabled={state.intoBackDisabled}></button>
<button id='intoforward' data-id="buttonNavigatorIntoForward" className='btn btn-primary btn-sm navigator stepButton fas fa-level-down-alt' title='Step into' onClick={() => { stepIntoForward && stepIntoForward() }} disabled={state.intoForwardDisabled}></button>
<button id='overforward' className='btn btn-primary btn-sm navigator stepButton fas fa-share' title='Step over forward' onClick={() => { stepOverForward && stepOverForward() }} disabled={state.overForwardDisabled}></button>
<OverlayTrigger
placement="top-start"
overlay={
<Tooltip className="text-nowrap" id="overbackTooltip">
<span>Step over back</span>
</Tooltip>
}
>
<div className={state.overBackDisabled ? `${stepBtnStyle} ${disableStepBtnStyle}`: `${stepBtnStyle}`} onClick={() => { stepOverBack && stepOverBack() }}>
<button id='overback' className='btn btn-link btn-sm stepButton m-0 p-0' onClick={() => { stepOverBack && stepOverBack() }} disabled={state.overBackDisabled} style={{ pointerEvents: 'none', color: 'white' }}>
<span className="fas fa-reply"></span>
</button>
</div>
</OverlayTrigger>
<OverlayTrigger
placement="top-start"
overlay={
<Tooltip className="text-nowrap" id="intobackTooltip">
<span>Step back</span>
</Tooltip>
}
>
<div className={state.intoBackDisabled ? `${stepBtnStyle} ${disableStepBtnStyle}`: `${stepBtnStyle}`} onClick={() => { stepIntoBack && stepIntoBack() }} data-id="buttonNavigatorIntoBack" id="buttonNavigatorIntoBackContainer">
<button id='intoback' data-id="buttonNavigatorIntoBack" className='btn btn-link btn-sm stepButton m-0 p-0' onClick={() => { stepIntoBack && stepIntoBack() }} disabled={state.intoBackDisabled} style={{ pointerEvents: 'none', color: 'white' }}>
<span className="fas fa-level-up-alt"></span>
</button>
</div>
</OverlayTrigger>
<OverlayTrigger
placement="top-start"
overlay={
<Tooltip className="text-nowrap" id="intoforwardTooltip">
<span>Step into</span>
</Tooltip>
}
>
<div className={state.intoForwardDisabled ? `${stepBtnStyle} ${disableStepBtnStyle}`: `${stepBtnStyle}`} onClick={() => { stepIntoForward && stepIntoForward() }} data-id="buttonNavigatorIntoForward" id="buttonNavigatorIntoFowardContainer">
<button id='intoforward' data-id="buttonNavigatorIntoForward" className='btn btn-link btn-sm stepButton m-0 p-0' onClick={() => { stepIntoForward && stepIntoForward() }} disabled={state.intoForwardDisabled}
style={{ pointerEvents: 'none', color: 'white' }}
>
<span className="fas fa-level-down-alt"></span>
</button>
</div>
</OverlayTrigger>
<OverlayTrigger
placement="top-end"
overlay={
<Tooltip className="text-nowrap" id="overforwardTooltip">
<span>Step over forward</span>
</Tooltip>
}
>
<div className={state.overForwardDisabled ? `${stepBtnStyle} ${disableStepBtnStyle}`: `${stepBtnStyle}`} onClick={() => { stepOverForward && stepOverForward() }} data-id="buttonNavigatorOverForward" id="buttonNavigatorOverForwardContainer">
<button id='overforward' className='btn btn-link btn-sm stepButton m-0 p-0' onClick={() => { stepOverForward && stepOverForward() }} disabled={state.overForwardDisabled} style={{ pointerEvents: 'none', color: 'white' }}>
<span className="fas fa-share"></span>
</button>
</div>
</OverlayTrigger>
</div>
<div className="jumpButtons btn-group py-1">
<button className='btn btn-primary btn-sm navigator jumpButton fas fa-step-backward' id='jumppreviousbreakpoint' data-id="buttonNavigatorJumpPreviousBreakpoint" title='Jump to the previous breakpoint' onClick={() => { jumpPreviousBreakpoint && jumpPreviousBreakpoint() }} disabled={state.jumpPreviousBreakpointDisabled}></button>
<button className='btn btn-primary btn-sm navigator jumpButton fas fa-eject' id='jumpout' title='Jump out' onClick={() => { jumpOut && jumpOut() }} disabled={state.jumpOutDisabled}></button>
<button className='btn btn-primary btn-sm navigator jumpButton fas fa-step-forward' id='jumpnextbreakpoint' data-id="buttonNavigatorJumpNextBreakpoint" title='Jump to the next breakpoint' onClick={() => { jumpNextBreakpoint && jumpNextBreakpoint() }} disabled={state.jumpNextBreakpointDisabled}></button>
<OverlayTrigger
placement="top-start"
overlay={
<Tooltip id="jumppreviousbreakpointTooltip" className="text-nowrap">
<span>{'Jump to the previous breakpoint'}</span>
</Tooltip>
}
>
<div className={state.jumpPreviousBreakpointDisabled ? `${stepBtnStyle} ${disableJumpBtnStyle}`: `${stepBtnStyle}`} id="buttonNavigatorJumpPreviousBreakpointContainer" onClick={() => { jumpPreviousBreakpoint && jumpPreviousBreakpoint() }} data-id="buttonNavigatorJumpPreviousBreakpoint">
<button className='btn btn-link btn-sm jumpButton m-0 p-0' id='jumppreviousbreakpoint' data-id="buttonNavigatorJumpPreviousBreakpoint" onClick={() => { jumpPreviousBreakpoint && jumpPreviousBreakpoint() }} disabled={state.jumpPreviousBreakpointDisabled} style={{ pointerEvents: 'none', backgroundColor: 'inherit', color: 'white' }}>
<span className="fas fa-step-backward"></span>
</button>
</div>
</OverlayTrigger>
<OverlayTrigger
placement="top-end"
overlay={
<Tooltip id="jumpoutTooltip" className="text-nowrap">
<span>{'Jump out'}</span>
</Tooltip>
}
>
<div className={state.jumpOutDisabled ? `${stepBtnStyle} ${disableStepBtnStyle}`: `${stepBtnStyle}`} onClick={() => { jumpOut && jumpOut() }} data-id="buttonNavigatorJumpOut" id="buttonNavigatorJumpOutContainer">
<button className='btn btn-link btn-sm jumpButton m-0 p-0' id='jumpout' onClick={() => { jumpOut && jumpOut() }} disabled={state.jumpOutDisabled} style={{ pointerEvents: 'none', backgroundColor: 'inherit', color: 'white' }} data-id="buttonNavigatorJumpOut">
<span className="fas fa-eject"></span>
</button>
</div>
</OverlayTrigger>
<OverlayTrigger
placement="top-end"
overlay={
<Tooltip id="jumpnextbreakpointTooltip" className="text-nowrap">
<span>{'Jump to the next breakpoint'}</span>
</Tooltip>
}
>
<div className={state.jumpNextBreakpointDisabled ? `${stepBtnStyle} ${disableStepBtnStyle}`: `${stepBtnStyle}`} onClick={() => { jumpNextBreakpoint && jumpNextBreakpoint() }} data-id="buttonNavigatorJumpNextBreakpoint" id="buttonNavigatorJumpNextBreakpointContainer">
<button className='btn btn-link btn-sm jumpButton m-0 p-0' id='jumpnextbreakpoint' data-id="buttonNavigatorJumpNextBreakpoint" onClick={() => { jumpNextBreakpoint && jumpNextBreakpoint() }} disabled={state.jumpNextBreakpointDisabled} style={{ pointerEvents: 'none', color: 'white' }}>
<span className="fas fa-step-forward"></span>
</button>
</div>
</OverlayTrigger>
</div>
<div id='reverted' style={{ display: revertedReason === '' ? 'none' : 'block' }}>
<span className='text-warning'>This call has reverted, state changes made during the call will be reverted.</span>

@ -9,6 +9,7 @@ import { Toaster } from '@remix-ui/toaster' // eslint-disable-line
import { isValidHash } from '@remix-ui/helper'
/* eslint-disable-next-line */
import './debugger-ui.css'
import { OverlayTrigger, Tooltip } from 'react-bootstrap'
const _paq = (window as any)._paq = (window as any)._paq || []
export const DebuggerUI = (props: DebuggerUIProps) => {
@ -351,12 +352,21 @@ export const DebuggerUI = (props: DebuggerUIProps) => {
<div className="px-2" ref={debuggerTopRef}>
<div>
<div className="mt-2 mb-2 debuggerConfig custom-control custom-checkbox">
<OverlayTrigger overlay={
<Tooltip id="debuggerGenSourceCheckbox">
<span>{"Debug with generated sources"}</span>
</Tooltip>
} placement="top-start"
>
<span className="p-0 m-0">
<input className="custom-control-input" id="debugGeneratedSourcesInput" onChange={({ target: { checked } }) => {
setState(prevState => {
return { ...prevState, opt: { ...prevState.opt, debugWithGeneratedSources: checked } }
})
}} type="checkbox" title="Debug with generated sources" />
}} type="checkbox" />
<label data-id="debugGeneratedSourcesLabel" className="form-check-label custom-control-label" htmlFor="debugGeneratedSourcesInput">Use generated sources (Solidity {'>='} v0.7.2)</label>
</span>
</OverlayTrigger>
</div>
{ state.isLocalNodeUsed && <div className="mb-2 debuggerConfig custom-control custom-checkbox">
<input className="custom-control-input" id="debugWithLocalNodeInput" onChange={({ target: { checked } }) => {

@ -1,4 +1,5 @@
import React, { useState, useEffect, useRef } from 'react' //eslint-disable-line
import { OverlayTrigger, Tooltip } from 'react-bootstrap'
import './tx-browser.css'
export const TxBrowser = ({ requestDebug, updateTxNumberFlag, unloadRequested, transactionNumber, debugging }) => {
@ -64,17 +65,30 @@ export const TxBrowser = ({ requestDebug, updateTxNumberFlag, unloadRequested, t
/>
</div>
<div className='d-flex justify-content-center w-100 btn-group py-1'>
<OverlayTrigger
placement={'bottom'}
overlay={
<Tooltip className={'text-nowrap'} id={'debuggingButtontooltip'}>
<span>
{debugging ? 'Stop debugging' : 'Start debugging'}
</span>
</Tooltip>
}
>
<div id="debuggerTransactionStartButtonContainer" data-id="debuggerTransactionStartButton" onClick={handleSubmit} className="btn btn-primary btn-sm btn-block text-decoration-none">
<button
className='btn btn-primary btn-sm txbutton'
className='btn btn-link btn-sm btn-block h-75 p-0 m-0 text-decoration-none'
id='load'
title={debugging ? 'Stop debugging' : 'Start debugging'}
onClick={handleSubmit}
data-id='debuggerTransactionStartButton'
disabled={!state.txNumber }
style={{ pointerEvents: 'none', color: 'white' }}
>
{ debugging ? 'Stop' : 'Start' } debugging
<span>{ debugging ? 'Stop' : 'Start' } debugging</span>
</button>
</div>
</OverlayTrigger>
</div>
</div>
<span id='error' />
</div>

@ -31,7 +31,18 @@ const RemixUIPanelHeader = (props: RemixPanelProps) => {
<h6 className="mb-3" data-id='sidePanelSwapitTitle'>{plugin?.profile.displayName || plugin?.profile.name}</h6>
<div className="d-flex flex-row">
<div className="d-flex flex-row">
{plugin?.profile?.maintainedBy?.toLowerCase() === "remix" && (<i aria-hidden="true" className="text-success mt-1 px-1 fas fa-check" title="Maintained by Remix"></i>)}
{plugin?.profile?.maintainedBy?.toLowerCase() === "remix" && (
<OverlayTrigger
placement="right"
overlay={
<Tooltip id="maintainedByTooltip" className="text-nowrap">
<span>{"Maintained by Remix"}</span>
</Tooltip>
}
>
<i aria-hidden="true" className="text-success mt-1 px-1 fas fa-check"></i>
</OverlayTrigger>
)}
</div>
<OverlayTrigger overlay={
<Tooltip className="text-nowrap" id="pluginInfoTooltip">

Loading…
Cancel
Save