Merge branch 'master' into intl

pull/5370/head
drafish 2 years ago
commit 435f4a2547
  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. 115
      libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.tsx
  4. 16
      libs/remix-ui/debugger-ui/src/lib/debugger-ui.tsx
  5. 36
      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,22 +51,120 @@ 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>
<span className='text-warning'>This call has reverted, state changes made during the call will be reverted.</span>
<span className='text-warning' id='outofgas' style={{ display: revertedReason === 'outofgas' ? 'inline' : 'none' }}>This call will run out of gas.</span>
<span className='text-warning' id='parenthasthrown' style={{ display: revertedReason === 'parenthasthrown' ? 'inline' : 'none' }}>The parent call will throw an exception</span>
<div className='text-warning'>Click <u data-id="debugGoToRevert" className="cursorPointerRemixDebugger" role="button" onClick={() => { jumpToException && jumpToException() }}>here</u> to jump where the call reverted.</div>

@ -10,6 +10,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) => {
@ -352,12 +353,21 @@ export const DebuggerUI = (props: DebuggerUIProps) => {
<div className="px-2" ref={debuggerTopRef}>
<div>
<div className="mt-2 mb-2 debuggerConfig custom-control custom-checkbox">
<input className="custom-control-input" id="debugGeneratedSourcesInput" onChange={({ target: { checked } }) => {
<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 } }) => {
@ -378,7 +388,7 @@ export const DebuggerUI = (props: DebuggerUIProps) => {
<span>
<FormattedMessage id='debugger.introduction' defaultMessage='When Debugging with a transaction hash,
if the contract is verified, Remix will try to fetch the source code from Sourcify or Etherscan. Put in your Etherscan API key in the Remix settings.
For supported networks, please see' />: <a href="https://sourcify.dev" target="__blank" >https://sourcify.dev</a> & <a href="https://sourcify.dev" target="__blank">https://etherscan.io/contractsVerified</a>
For supported networks, please see' />: <a href="https://sourcify.dev" target="__blank" >https://sourcify.dev</a> & <a href="https://etherscan.io/contractsVerified" target="__blank">https://etherscan.io/contractsVerified</a>
</span>
</div> }
{ state.debugging && <StepManager stepManager={ stepManager } /> }

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

@ -34,7 +34,18 @@ const RemixUIPanelHeader = (props: RemixPanelProps) => {
</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