diff --git a/.circleci/config.yml b/.circleci/config.yml
index acc9a0ffb8..e7580743ae 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -72,6 +72,8 @@ jobs:
parallelism: 12
steps:
- checkout
+ - run: git submodule sync --recursive
+ - run: git submodule update --recursive --init
- run: npm install
- run: npx nx build remix-ide --with-deps
- run:
@@ -105,6 +107,8 @@ jobs:
parallelism: 12
steps:
- checkout
+ - run: git submodule sync --recursive
+ - run: git submodule update --recursive --init
- run: npm install
- run: npm run downloadsolc_assets
- run: npx nx build remix-ide --with-deps
@@ -139,6 +143,8 @@ jobs:
parallelism: 12
steps:
- checkout
+ - run: git submodule sync --recursive
+ - run: git submodule update --recursive --init
- run: npm install
- run: npx nx build remix-ide --with-deps
- run:
@@ -172,6 +178,8 @@ jobs:
parallelism: 12
steps:
- checkout
+ - run: git submodule sync --recursive
+ - run: git submodule update --recursive --init
- run: npm install
- run: npm run downloadsolc_assets
- run: npx nx build remix-ide --with-deps
@@ -206,6 +214,8 @@ jobs:
steps:
- checkout
+ - run: git submodule sync --recursive
+ - run: git submodule update --recursive --init
- run: npm install
- run: npx nx build remix-ide --with-deps
- run:
@@ -239,6 +249,8 @@ jobs:
steps:
- checkout
+ - run: git submodule sync --recursive
+ - run: git submodule update --recursive --init
- run: npm install
- run: npx nx build remix-ide --with-deps
- run: npx nx build remix-ide-e2e-src-local-plugin
@@ -254,6 +266,7 @@ jobs:
path: ./reports/tests
- store_artifacts:
path: ./reports/screenshots
+
deploy-remix-live:
docker:
# specify the version you desire here
@@ -272,6 +285,8 @@ jobs:
steps:
- checkout
+ - run: git submodule sync --recursive
+ - run: git submodule update --recursive --init
- run: npm install
- run: npm run downloadsolc_assets
- run: npm run build:production
@@ -300,6 +315,8 @@ jobs:
steps:
- checkout
+ - run: git submodule sync --recursive
+ - run: git submodule update --recursive --init
- setup_remote_docker
- run: npm install
- run: npm run downloadsolc_assets
@@ -326,6 +343,8 @@ jobs:
steps:
- checkout
+ - run: git submodule sync --recursive
+ - run: git submodule update --recursive --init
- run: npm install
- run: npm run downloadsolc_assets
- run: npm run build:production
@@ -354,6 +373,8 @@ jobs:
steps:
- checkout
+ - run: git submodule sync --recursive
+ - run: git submodule update --recursive --init
- run: npm install
- run: npm run build:libs
- run: npm run downloadsolc_assets
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000000..f3b7f8e547
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "libs/remix-ui/tabs/react-tabs"]
+ path = libs/remix-ui/tabs/react-tabs
+ url = https://github.com/reactjs/react-tabs
diff --git a/apps/remix-ide-e2e/src/commands/journalChildIncludes.ts b/apps/remix-ide-e2e/src/commands/journalChildIncludes.ts
index af9a061136..689be3bf34 100644
--- a/apps/remix-ide-e2e/src/commands/journalChildIncludes.ts
+++ b/apps/remix-ide-e2e/src/commands/journalChildIncludes.ts
@@ -5,10 +5,10 @@ import EventEmitter from 'events'
Checks if any child elements of journal (console) contains a matching value.
*/
class JournalChildIncludes extends EventEmitter {
- command (this: NightwatchBrowser, val: string): NightwatchBrowser {
+ command (this: NightwatchBrowser, val: string, opts = { shouldHaveOnlyOneOccurence: false }): NightwatchBrowser {
let isTextFound = false
const browser = this.api
-
+ let occurence = 0
this.api.elements('css selector', '*[data-id="terminalJournal"]', (res) => {
Array.isArray(res.value) && res.value.forEach(function (jsonWebElement) {
const jsonWebElementId = jsonWebElement.ELEMENT || jsonWebElement[Object.keys(jsonWebElement)[0]]
@@ -16,12 +16,16 @@ class JournalChildIncludes extends EventEmitter {
browser.elementIdText(jsonWebElementId, (jsonElement) => {
const text = jsonElement.value
- if (typeof text === 'string' && text.indexOf(val) !== -1) isTextFound = true
+ if (typeof text === 'string' && text.indexOf(val) !== -1) {
+ isTextFound = true
+ occurence++
+ }
})
})
})
browser.perform(() => {
browser.assert.ok(isTextFound, isTextFound ? `<*[data-id="terminalJournal"]> contains ${val}.` : `${val} not found in <*[data-id="terminalJournal"]> div:last-child>`)
+ if (opts.shouldHaveOnlyOneOccurence) browser.assert.ok(occurence === 1, `${occurence} occurence found of "${val}"`)
this.emit('complete')
})
return this
diff --git a/apps/remix-ide-e2e/src/tests/remixd.test.ts b/apps/remix-ide-e2e/src/tests/remixd.test.ts
index 293bdb16c0..970a4f556a 100644
--- a/apps/remix-ide-e2e/src/tests/remixd.test.ts
+++ b/apps/remix-ide-e2e/src/tests/remixd.test.ts
@@ -152,7 +152,6 @@ function runTests (browser: NightwatchBrowser) {
})
.clickLaunchIcon('filePanel')
.waitForElementVisible('[data-path="folder1"]')
- .click('[data-path="folder1"]')
.waitForElementVisible('[data-path="folder1/contract1.sol"]')
.waitForElementVisible('[data-path="folder1/renamed_contract_' + browserName + '.sol"]') // check if renamed file is preset
.waitForElementNotPresent('[data-path="folder1/contract_' + browserName + '.sol"]') // check if renamed (old) file is not present
diff --git a/apps/remix-ide-e2e/src/tests/solidityUnittests.spec.ts b/apps/remix-ide-e2e/src/tests/solidityUnittests.spec.ts
index 36eb781ac7..e5a4136eb5 100644
--- a/apps/remix-ide-e2e/src/tests/solidityUnittests.spec.ts
+++ b/apps/remix-ide-e2e/src/tests/solidityUnittests.spec.ts
@@ -13,7 +13,7 @@ module.exports = {
return sources
},
- 'Should launch solidity unit test plugin': function (browser: NightwatchBrowser) {
+ 'Should launch solidity unit test plugin and create test files in FE': function (browser: NightwatchBrowser) {
browser.waitForElementPresent('*[data-id="verticalIconsKindfilePanel"]')
.clickLaunchIcon('filePanel')
.addFile('simple_storage.sol', sources[0]['simple_storage.sol'])
@@ -23,6 +23,15 @@ module.exports = {
.click('*[data-id="verticalIconsKindsolidityUnitTesting"]')
.waitForElementPresent('*[data-id="sidePanelSwapitTitle"]')
.assert.containsText('*[data-id="sidePanelSwapitTitle"]', 'SOLIDITY UNIT TESTING')
+ .clickLaunchIcon('filePanel')
+ .waitForElementVisible('li[data-id="treeViewLitreeViewItem.deps/remix-tests/remix_tests.sol"]')
+ .waitForElementVisible('li[data-id="treeViewLitreeViewItem.deps/remix-tests/remix_accounts.sol"]')
+ .openFile('.deps/remix-tests/remix_tests.sol')
+ // remix_test.sol should be opened in editor
+ .getEditorValue((content) => browser.assert.ok(content.indexOf('library Assert {') !== -1))
+ .openFile('.deps/remix-tests/remix_accounts.sol')
+ // remix_accounts.sol should be opened in editor
+ .getEditorValue((content) => browser.assert.ok(content.indexOf('library TestsAccounts {') !== -1))
},
'Should generate test file': function (browser: NightwatchBrowser) {
@@ -150,7 +159,7 @@ module.exports = {
.click('*[data-id="testTabGenerateTestFolder"]')
},
- 'Changing current path when workspace changed': function (browser: NightwatchBrowser) {
+ 'Changing current path when workspace changed and checking test files creation': function (browser: NightwatchBrowser) {
browser
.waitForElementPresent('*[data-id="verticalIconsKindfilePanel"]')
.clickLaunchIcon('settings')
@@ -168,6 +177,14 @@ module.exports = {
.waitForElementVisible('*[data-id="fileSystem-modal-footer-ok-react"]')
.execute(function () { (document.querySelector('[data-id="fileSystem-modal-footer-ok-react"]') as HTMLElement).click() })
.waitForElementPresent('*[data-id="workspacesSelect"] option[value="workspace_new"]')
+ .waitForElementVisible('li[data-id="treeViewLitreeViewItem.deps/remix-tests/remix_tests.sol"]')
+ .waitForElementVisible('li[data-id="treeViewLitreeViewItem.deps/remix-tests/remix_accounts.sol"]')
+ .openFile('.deps/remix-tests/remix_tests.sol')
+ // remix_test.sol should be opened in editor
+ .getEditorValue((content) => browser.assert.ok(content.indexOf('library Assert {') !== -1))
+ .openFile('.deps/remix-tests/remix_accounts.sol')
+ // remix_accounts.sol should be opened in editor
+ .getEditorValue((content) => browser.assert.ok(content.indexOf('library TestsAccounts {') !== -1))
// end of creating
.clickLaunchIcon('solidityUnitTesting')
.pause(2000)
@@ -276,6 +293,8 @@ module.exports = {
.setValue('*[data-id="slider"]', new Array(1).fill(browser.Keys.RIGHT_ARROW))
.waitForElementContainsText('*[data-id="functionPanel"]', 'equal(a, b, message)', 60000)
.waitForElementContainsText('*[data-id="functionPanel"]', 'checkWinningProposalPassed()', 60000)
+ // remix_test.sol should be opened in editor
+ .getEditorValue((content) => browser.assert.ok(content.indexOf('library Assert {') !== -1))
.pause(1000)
.clickLaunchIcon('solidityUnitTesting')
.scrollAndClick('#Check_winning_proposal_again')
diff --git a/apps/remix-ide-e2e/src/tests/terminal.test.ts b/apps/remix-ide-e2e/src/tests/terminal.test.ts
index 7e176b362a..54bfae0cf7 100644
--- a/apps/remix-ide-e2e/src/tests/terminal.test.ts
+++ b/apps/remix-ide-e2e/src/tests/terminal.test.ts
@@ -128,6 +128,31 @@ module.exports = {
.waitForElementContainsText('*[data-id="terminalJournal"]', '0x5B38Da6a701c568545dCfcB03FcB875f56beddC4', 60000) // check that the script is logging the event
.waitForElementContainsText('*[data-id="terminalJournal"]', 'newOwner', 60000)
.waitForElementContainsText('*[data-id="terminalJournal"]', '0xd9145CCE52D386f254917e481eB44e9943F39138', 60000)
+ },
+
+ 'Should print hardhat logs': function (browser: NightwatchBrowser) {
+ browser
+ .click('*[data-id="terminalClearConsole"]') // clear the terminal
+ .addFile('printHardhatlog.sol', { content: hardhatLog })
+ .clickLaunchIcon('solidity')
+ .waitForElementVisible('[for="autoCompile"]')
+ .click('[for="autoCompile"]')
+ .testContracts('printHardhatlog.sol', { content: hardhatLog }, ['OwnerTest'])
+ .clickLaunchIcon('udapp')
+ .click('*[data-id="deployAndRunClearInstances"]')
+ .selectContract('OwnerTest')
+ .createContract('')
+ .pause(1000)
+ .journalChildIncludes('constructor', { shouldHaveOnlyOneOccurence: true })
+ .pause(5000)
+ .click('*[data-id="terminalClearConsole"]') // clear the terminal
+ .clickInstance(0)
+ .clickFunction('changeOwner - transact (not payable)', { types: 'address newOwner', values: '0xd9145CCE52D386f254917e481eB44e9943F39138' })
+ .pause(1000)
+ .journalChildIncludes('inside changeOwner', { shouldHaveOnlyOneOccurence: true })
+ .clickFunction('getOwner - call')
+ .pause(1000)
+ .journalChildIncludes('inside getOwner', { shouldHaveOnlyOneOccurence: true })
.end()
}
}
@@ -238,3 +263,61 @@ const deployWithEthersJs = `
console.log(e.message)
}
})()`
+
+const hardhatLog = `
+// SPDX-License-Identifier: GPL-3.0
+
+pragma solidity >=0.7.0 <0.9.0;
+
+import "hardhat/console.sol";
+
+/**
+ * @title Owner
+ * @dev Set & change owner
+ */
+contract OwnerTest {
+
+ address private owner;
+
+ // event for EVM logging
+ event OwnerSet(address indexed oldOwner, address indexed newOwner);
+
+ // modifier to check if caller is owner
+ modifier isOwner() {
+ // If the first argument of 'require' evaluates to 'false', execution terminates and all
+ // changes to the state and to Ether balances are reverted.
+ // This used to consume all gas in old EVM versions, but not anymore.
+ // It is often a good idea to use 'require' to check if functions are called correctly.
+ // As a second argument, you can also provide an explanation about what went wrong.
+ require(msg.sender == owner, "Caller is not owner");
+ _;
+ }
+
+ /**
+ * @dev Set contract deployer as owner
+ */
+ constructor() {
+ console.log("constructor");
+ owner = msg.sender; // 'msg.sender' is sender of current call, contract deployer for a constructor
+ emit OwnerSet(address(0), owner);
+ }
+
+ /**
+ * @dev Change owner
+ * @param newOwner address of new owner
+ */
+ function changeOwner(address newOwner) public isOwner {
+ console.log("inside changeOwner");
+ emit OwnerSet(owner, newOwner);
+ owner = newOwner;
+ }
+
+ /**
+ * @dev Return owner address
+ * @return address of owner
+ */
+ function getOwner() external view returns (address) {
+ console.log("inside getOwner");
+ return owner;
+ }
+}`
diff --git a/apps/remix-ide-e2e/src/types/index.d.ts b/apps/remix-ide-e2e/src/types/index.d.ts
index 7033bf2057..f5f9287065 100644
--- a/apps/remix-ide-e2e/src/types/index.d.ts
+++ b/apps/remix-ide-e2e/src/types/index.d.ts
@@ -23,7 +23,7 @@ declare module 'nightwatch' {
journalLastChildIncludes(val: string): NightwatchBrowser,
executeScript(script: string): NightwatchBrowser,
clearEditableContent(cssSelector: string): NightwatchBrowser,
- journalChildIncludes(val: string): NightwatchBrowser,
+ journalChildIncludes(val: string, opts = { shouldHaveOnlyOneOccurence: boolean }): NightwatchBrowser,
debugTransaction(index: number): NightwatchBrowser,
checkElementStyle(cssSelector: string, styleProperty: string, expectedResult: string): NightwatchBrowser,
openFile(name: string): NightwatchBrowser,
diff --git a/apps/remix-ide/.babelrc b/apps/remix-ide/.babelrc
index 2b7bafa5fa..e60d3036a3 100644
--- a/apps/remix-ide/.babelrc
+++ b/apps/remix-ide/.babelrc
@@ -1,3 +1,4 @@
{
- "presets": ["@babel/preset-env", "@babel/preset-react"]
+ "presets": ["@babel/preset-env", "@babel/preset-react"],
+ "plugins": ["@babel/plugin-proposal-class-properties"]
}
diff --git a/apps/remix-ide/src/app/editor/editor.js b/apps/remix-ide/src/app/editor/editor.js
index a6ea53ca9b..3adf7911db 100644
--- a/apps/remix-ide/src/app/editor/editor.js
+++ b/apps/remix-ide/src/app/editor/editor.js
@@ -97,7 +97,7 @@ class Editor extends Plugin {
this.emit(name, ...params) // plugin stack
}
- onActivation () {
+ async onActivation () {
this.activated = true
this.on('sidePanel', 'focusChanged', (name) => {
this.keepDecorationsFor(name, 'sourceAnnotationsPerFile')
@@ -108,14 +108,15 @@ class Editor extends Plugin {
})
const translateTheme = (theme) => this._themes[theme.name === 'Dark' ? 'remixDark' : theme.quality]
- this.on('theme', 'themeChanged', (theme) => {
- this.currentTheme = translateTheme(theme)
- this.renderComponent()
- })
- this.call('theme', 'currentTheme', (theme) => {
+ this.on('theme', 'themeLoaded', (theme) => {
this.currentTheme = translateTheme(theme)
this.renderComponent()
})
+ try {
+ this.currentTheme = translateTheme(await this.call('theme', 'currentTheme'))
+ } catch (e) {
+ console.log('unable to select the theme ' + e.message)
+ }
this.renderComponent()
}
diff --git a/apps/remix-ide/src/app/files/fileProvider.js b/apps/remix-ide/src/app/files/fileProvider.js
index ea46dd8b72..d5873e43ef 100644
--- a/apps/remix-ide/src/app/files/fileProvider.js
+++ b/apps/remix-ide/src/app/files/fileProvider.js
@@ -17,8 +17,9 @@ class FileProvider {
}
addNormalizedName (path, url) {
- this.providerExternalsStorage.set(this.type + '/' + path, url)
- this.providerExternalsStorage.set(this.reverseKey + url, this.type + '/' + path)
+ if (this.type) path = this.type + '/' + path
+ this.providerExternalsStorage.set(path, url)
+ this.providerExternalsStorage.set(this.reverseKey + url, path)
}
removeNormalizedName (path) {
diff --git a/apps/remix-ide/src/app/panels/tab-proxy.js b/apps/remix-ide/src/app/panels/tab-proxy.js
index 7c652ab78b..5b65254830 100644
--- a/apps/remix-ide/src/app/panels/tab-proxy.js
+++ b/apps/remix-ide/src/app/panels/tab-proxy.js
@@ -191,13 +191,6 @@ export class TabProxy extends Plugin {
}
}
- switchToActiveTab () {
- const active = this.tabsApi.active()
- if (active && this._handlers[active]) {
- this.switchTab(active)
- }
- }
-
renameTab (oldName, newName) {
this.addTab(newName, '', () => {
this.fileManager.open(newName)
@@ -236,19 +229,21 @@ export class TabProxy extends Plugin {
})
formatPath.shift()
if (formatPath.length > 0) {
- const duplicateTabName = this.loadedTabs.find(({ title }) => title === formatPath.join('/')).name
- const duplicateTabPath = duplicateTabName.split('/')
- const duplicateTabFormatPath = [...duplicateTabPath].reverse()
- const duplicateTabTitle = duplicateTabFormatPath.slice(0, titleLength).reverse().join('/')
-
- this.loadedTabs.push({
- id: duplicateTabName,
- name: duplicateTabName,
- title: duplicateTabTitle,
- icon,
- tooltip: duplicateTabName,
- iconClass: helper.getPathIcon(duplicateTabName)
- })
+ const index = this.loadedTabs.findIndex(({ title }) => title === formatPath.join('/'))
+ if (index > -1) {
+ const duplicateTabName = this.loadedTabs[index].name
+ const duplicateTabPath = duplicateTabName.split('/')
+ const duplicateTabFormatPath = [...duplicateTabPath].reverse()
+ const duplicateTabTitle = duplicateTabFormatPath.slice(0, titleLength).reverse().join('/')
+ this.loadedTabs[index] = {
+ id: duplicateTabName,
+ name: duplicateTabName,
+ title: duplicateTabTitle,
+ icon,
+ tooltip: duplicateTabName,
+ iconClass: helper.getPathIcon(duplicateTabName)
+ }
+ }
}
break
}
@@ -271,10 +266,14 @@ export class TabProxy extends Plugin {
removeTab (name) {
delete this._handlers[name]
- this.switchToActiveTab()
- this.loadedTabs = this.loadedTabs.filter(tab => tab.name !== name)
+ let previous = null
+ this.loadedTabs = this.loadedTabs.filter((tab, index) => {
+ if (tab.name === name) previous = this.loadedTabs[index - 1]
+ return tab.name !== name
+ })
this.renderComponent()
this.updateImgStyles()
+ if (previous) this.switchTab(previous.name)
}
addHandler (type, fn) {
diff --git a/apps/remix-ide/src/app/panels/terminal.js b/apps/remix-ide/src/app/panels/terminal.js
index 0f358b2611..df0510b150 100644
--- a/apps/remix-ide/src/app/panels/terminal.js
+++ b/apps/remix-ide/src/app/panels/terminal.js
@@ -86,8 +86,6 @@ class Terminal extends Plugin {
this.call('menuicons', 'select', 'debugger')
this.call('debugger', 'debug', hash)
})
- this.logHtmlResponse = []
- this.logResponse = []
}
onActivation () {
@@ -102,23 +100,11 @@ class Terminal extends Plugin {
}
logHtml (html) {
- this.logHtmlResponse.push(html.innerText)
- this.renderComponent()
- this.resetLogHtml()
- }
-
- resetLogHtml () {
- this.logHtmlResponse = []
+ this.terminalApi.logHtml(html)
}
log (message) {
- this.logResponse.push(message)
- this.renderComponent()
- this.resetLog()
- }
-
- resetLog () {
- this.logResponse = []
+ this.terminalApi.log(message)
}
render () {
@@ -126,9 +112,11 @@ class Terminal extends Plugin {
}
renderComponent () {
+ const onReady = (api) => { this.terminalApi = api }
ReactDOM.render(
,
this.element
)
diff --git a/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js b/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js
index a111147672..650b35b8c1 100644
--- a/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js
+++ b/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js
@@ -56,6 +56,7 @@ class ContractDropdownUI {
}
this.exEnvironment = this.blockchain.getProvider()
this.networkName = network.name
+ this.networkId = network.id
const savedConfig = window.localStorage.getItem(`ipfs/${this.exEnvironment}/${this.networkName}`)
@@ -309,10 +310,10 @@ class ContractDropdownUI {
const data = self.runView.compilersArtefacts.getCompilerAbstract(contractObject.contract.file)
self.runView.compilersArtefacts.addResolvedContract(helper.addressToString(address), data)
if (self.ipfsCheckedState) {
- _paq.push(['trackEvent', 'udapp', 'DeployAndPublish', this.networkName])
+ _paq.push(['trackEvent', 'udapp', 'DeployAndPublish', this.networkName, this.networkId])
publishToStorage('ipfs', self.runView.fileProvider, self.runView.fileManager, selectedContract)
} else {
- _paq.push(['trackEvent', 'udapp', 'DeployOnly', this.networkName])
+ _paq.push(['trackEvent', 'udapp', 'DeployOnly', this.networkName, this.networkId])
}
}
@@ -346,7 +347,7 @@ class ContractDropdownUI {
}
deployContract (selectedContract, args, contractMetadata, compilerContracts, callbacks, confirmationCb) {
- _paq.push(['trackEvent', 'udapp', 'DeployContractTo', this.networkName])
+ _paq.push(['trackEvent', 'udapp', 'DeployContractTo', this.networkName, this.networkId])
const { statusCb } = callbacks
if (!contractMetadata || (contractMetadata && contractMetadata.autoDeployLib)) {
return this.blockchain.deployContractAndLibraries(selectedContract, args, contractMetadata, compilerContracts, callbacks, confirmationCb)
diff --git a/apps/remix-ide/src/app/tabs/test-tab.js b/apps/remix-ide/src/app/tabs/test-tab.js
index 1995abe1f6..c82a2bcc1d 100644
--- a/apps/remix-ide/src/app/tabs/test-tab.js
+++ b/apps/remix-ide/src/app/tabs/test-tab.js
@@ -7,7 +7,7 @@ var async = require('async')
var tooltip = require('../ui/tooltip')
var Renderer = require('../ui/renderer')
var css = require('./styles/test-tab-styles')
-var { UnitTestRunner } = require('@remix-project/remix-tests')
+var { UnitTestRunner, assertLibCode } = require('@remix-project/remix-tests')
const _paq = window._paq = window._paq || []
@@ -16,7 +16,7 @@ const TestTabLogic = require('./testTab/testTab')
const profile = {
name: 'solidityUnitTesting',
displayName: 'Solidity unit testing',
- methods: ['testFromPath', 'testFromSource', 'setTestFolderPath'],
+ methods: ['testFromPath', 'testFromSource', 'setTestFolderPath', 'getTestlibs'],
events: [],
icon: 'assets/img/unitTesting.webp',
description: 'Fast tool to generate unit tests for your contracts',
@@ -42,7 +42,7 @@ module.exports = class TestTab extends ViewPlugin {
this.areTestsRunning = false
this.defaultPath = 'tests'
this.offsetToLineColumnConverter = offsetToLineColumnConverter
- this.allFilesInvolved = []
+ this.allFilesInvolved = ['.deps/remix-tests/remix_tests.sol', '.deps/remix-tests/remix_accounts.sol']
this.isDebugging = false
this.currentErrors = []
@@ -74,11 +74,25 @@ module.exports = class TestTab extends ViewPlugin {
}
}
+ getTestlibs () {
+ return { assertLibCode, accountsLibCode: this.testRunner.accountsLibCode }
+ }
+
+ async createTestLibs () {
+ const provider = await this.fileManager.currentFileProvider()
+ if (provider) {
+ provider.addExternal('.deps/remix-tests/remix_tests.sol', assertLibCode, 'remix_tests.sol')
+ provider.addExternal('.deps/remix-tests/remix_accounts.sol', this.testRunner.accountsLibCode, 'remix_accounts.sol')
+ }
+ }
+
async onActivation () {
const isSolidityActive = await this.call('manager', 'isActive', 'solidity')
if (!isSolidityActive) {
await this.call('manager', 'activatePlugin', 'solidity')
}
+ await this.testRunner.init()
+ await this.createTestLibs()
this.updateRunAction()
}
@@ -110,9 +124,13 @@ module.exports = class TestTab extends ViewPlugin {
this.setCurrentPath(this.defaultPath)
})
+ this.on('filePanel', 'workspaceCreated', async () => {
+ this.createTestLibs()
+ })
+
this.testRunner.event.on('compilationFinished', (success, data, source) => {
if (success) {
- this.allFilesInvolved = Object.keys(data.sources)
+ this.allFilesInvolved.push(...Object.keys(data.sources))
// forwarding the event to the appManager infra
// This is listened by compilerArtefacts to show data while debugging
this.emit('compilationFinished', source.target, source, 'soljson', data)
@@ -526,8 +544,8 @@ module.exports = class TestTab extends ViewPlugin {
this.fileManager.readFile(testFilePath).then((content) => {
const runningTests = {}
runningTests[testFilePath] = { content }
- const { currentVersion, evmVersion, optimize, runs } = this.compileTab.getCurrentCompilerConfig()
- const currentCompilerUrl = urlFromVersion(currentVersion)
+ const { currentVersion, evmVersion, optimize, runs, isUrl } = this.compileTab.getCurrentCompilerConfig()
+ const currentCompilerUrl = isUrl ? currentVersion : urlFromVersion(currentVersion)
const compilerConfig = {
currentCompilerUrl,
evmVersion,
diff --git a/apps/remix-ide/src/app/tabs/theme-module.js b/apps/remix-ide/src/app/tabs/theme-module.js
index b3f62cd905..1aaadda952 100644
--- a/apps/remix-ide/src/app/tabs/theme-module.js
+++ b/apps/remix-ide/src/app/tabs/theme-module.js
@@ -79,10 +79,17 @@ export class ThemeModule extends Plugin {
throw new Error(`Theme ${themeName} doesn't exist`)
}
const next = themeName || this.active // Name
+ if (next === this.active) return
_paq.push(['trackEvent', 'themeModule', 'switchTo', next])
const nextTheme = this.themes[next] // Theme
if (!this.forced) this._deps.config.set('settings/theme', next)
- document.getElementById('theme-link').setAttribute('href', nextTheme.url)
+ document.getElementById('theme-link').remove()
+ const theme = yo``
+ theme.addEventListener('load', () => {
+ this.emit('themeLoaded', nextTheme)
+ this.events.emit('themeLoaded', nextTheme)
+ })
+ document.head.insertBefore(theme, document.head.firstChild)
document.documentElement.style.setProperty('--theme', nextTheme.quality)
if (themeName) this.active = themeName
// TODO: Only keep `this.emit` (issue#2210)
diff --git a/apps/remix-ide/webpack.config.js b/apps/remix-ide/webpack.config.js
index 02143af15b..4af33b4f3a 100644
--- a/apps/remix-ide/webpack.config.js
+++ b/apps/remix-ide/webpack.config.js
@@ -21,7 +21,7 @@ module.exports = config => {
mode: 'production',
devtool: 'source-map',
optimization: {
- minimize: true,
+ minimize: false,
minimizer: [new TerserPlugin()]
}
}
diff --git a/apps/solidity-compiler/src/app/compiler-api.ts b/apps/solidity-compiler/src/app/compiler-api.ts
index 8082002ff4..733ee0026f 100644
--- a/apps/solidity-compiler/src/app/compiler-api.ts
+++ b/apps/solidity-compiler/src/app/compiler-api.ts
@@ -143,12 +143,17 @@ export const CompilerApiMixin = (Base) => class extends Base {
// This function is used for passing the compiler configuration to 'remix-tests'
getCurrentCompilerConfig () {
const compilerState = this.getCompilerState()
- return {
+ let compilerDetails: any = {
currentVersion: compilerState.currentVersion,
evmVersion: compilerState.evmVersion,
optimize: compilerState.optimize,
runs: compilerState.runs
}
+ if (this.data.loading) {
+ compilerDetails.currentVersion = this.data.loadingUrl
+ compilerDetails.isUrl = true
+ }
+ return compilerDetails
}
/**
@@ -193,8 +198,9 @@ export const CompilerApiMixin = (Base) => class extends Base {
if (this.onContentChanged) this.onContentChanged()
})
- this.data.eventHandlers.onLoadingCompiler = () => {
+ this.data.eventHandlers.onLoadingCompiler = (url) => {
this.data.loading = true
+ this.data.loadingUrl = url
this.emit('statusChanged', { key: 'loading', title: 'loading compiler...', type: 'info' })
}
this.compiler.event.register('loadingCompiler', this.data.eventHandlers.onLoadingCompiler)
diff --git a/babel.config.js b/babel.config.js
index 41068f8f4f..6196b51b81 100644
--- a/babel.config.js
+++ b/babel.config.js
@@ -1,4 +1,4 @@
module.exports = {
"presets": ["@babel/preset-react", "@babel/preset-typescript"],
- "plugins": ["@babel/plugin-transform-modules-commonjs"]
+ "plugins": ["@babel/plugin-transform-modules-commonjs", "@babel/plugin-proposal-class-properties"]
}
\ No newline at end of file
diff --git a/libs/remix-core-plugin/src/lib/compiler-content-imports.ts b/libs/remix-core-plugin/src/lib/compiler-content-imports.ts
index 2e20d5ebb7..8c243e37a8 100644
--- a/libs/remix-core-plugin/src/lib/compiler-content-imports.ts
+++ b/libs/remix-core-plugin/src/lib/compiler-content-imports.ts
@@ -1,7 +1,6 @@
'use strict'
import { Plugin } from '@remixproject/engine'
import { RemixURLResolver } from '@remix-project/remix-url-resolver'
-const remixTests = require('@remix-project/remix-tests')
const profile = {
name: 'contentImport',
@@ -117,7 +116,6 @@ export class CompilerImports extends Plugin {
* @returns {Promise} - string content
*/
async resolveAndSave (url, targetPath) {
- if (url.indexOf('remix_tests.sol') !== -1) return remixTests.assertLibCode
try {
const provider = await this.call('fileManager', 'getProviderOf', url)
if (provider) {
diff --git a/libs/remix-lib/src/execution/txRunnerVM.ts b/libs/remix-lib/src/execution/txRunnerVM.ts
index 901652da0d..428f377b39 100644
--- a/libs/remix-lib/src/execution/txRunnerVM.ts
+++ b/libs/remix-lib/src/execution/txRunnerVM.ts
@@ -15,6 +15,7 @@ export class TxRunnerVM {
blocks
logsManager
commonContext
+ nextNonceForCall: number
getVMObject: () => any
constructor (vmaccounts, api, getVMObject) {
@@ -31,6 +32,13 @@ export class TxRunnerVM {
this.vmaccounts = vmaccounts
this.queusTxs = []
this.blocks = []
+ /*
+ txHash is generated using the nonce,
+ in order to have unique transaction hash, we need to keep using different nonce (in case of a call)
+ so we increment this value after each call.
+ For this to function we also need to skip nonce validation, in the vm: `{ skipNonce: true }`
+ */
+ this.nextNonceForCall = 0
}
execute (args, confirmationCb, gasEstimationForceSend, promptCb, callback) {
@@ -75,7 +83,7 @@ export class TxRunnerVM {
let tx
if (!EIP1559) {
tx = Transaction.fromTxData({
- nonce: new BN(res.nonce),
+ nonce: useCall ? this.nextNonceForCall : new BN(res.nonce),
gasPrice: '0x1',
gasLimit: gasLimit,
to: to,
@@ -84,7 +92,7 @@ export class TxRunnerVM {
}, { common: this.commonContext }).sign(account.privateKey)
} else {
tx = FeeMarketEIP1559Transaction.fromTxData({
- nonce: new BN(res.nonce),
+ nonce: useCall ? this.nextNonceForCall : new BN(res.nonce),
maxPriorityFeePerGas: '0x01',
maxFeePerGas: '0x1',
gasLimit: gasLimit,
@@ -93,6 +101,7 @@ export class TxRunnerVM {
data: Buffer.from(data.slice(2), 'hex')
}).sign(account.privateKey)
}
+ if (useCall) this.nextNonceForCall++
const coinbases = ['0x0e9281e9c6a0808672eaba6bd1220e144c9bb07a', '0x8945a1288dc78a6d8952a92c77aee6730b414778', '0x94d76e24f818426ae84aa404140e8d5f60e10e7e']
const difficulties = [new BN('69762765929000', 10), new BN('70762765929000', 10), new BN('71762765929000', 10)]
@@ -127,7 +136,7 @@ export class TxRunnerVM {
}
runBlockInVm (tx, block, callback) {
- this.getVMObject().vm.runBlock({ block: block, generate: true, skipBlockValidation: true, skipBalance: false }).then((results) => {
+ this.getVMObject().vm.runBlock({ block: block, generate: true, skipBlockValidation: true, skipBalance: false, skipNonce: true }).then((results) => {
const result = results.results[0]
if (result) {
const status = result.execResult.exceptionError ? 0 : 1
diff --git a/libs/remix-lib/src/web3Provider/web3VmProvider.ts b/libs/remix-lib/src/web3Provider/web3VmProvider.ts
index f29e225e5a..49fa4d80a9 100644
--- a/libs/remix-lib/src/web3Provider/web3VmProvider.ts
+++ b/libs/remix-lib/src/web3Provider/web3VmProvider.ts
@@ -304,7 +304,9 @@ export class Web3VmProvider {
nextKey: null
})
}
- cb('unable to retrieve storage ' + txIndex + ' ' + address)
+ // Before https://github.com/ethereum/remix-project/pull/1703, it used to throw error as
+ // 'unable to retrieve storage ' + txIndex + ' ' + address
+ cb(null, { storage: {} })
}
getBlockNumber (cb) { cb(null, 'vm provider') }
diff --git a/libs/remix-tests/sol/tests_accounts.sol.ts b/libs/remix-tests/sol/tests_accounts.sol.ts
index d97aae8f34..847e37f083 100644
--- a/libs/remix-tests/sol/tests_accounts.sol.ts
+++ b/libs/remix-tests/sol/tests_accounts.sol.ts
@@ -3,7 +3,7 @@ module.exports = `// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.22 <0.9.0;
library TestsAccounts {
- function getAccount(uint index) public returns (address) {
+ function getAccount(uint index) pure public returns (address) {
>accounts<
return accounts[index];
}
diff --git a/libs/remix-tests/src/compiler.ts b/libs/remix-tests/src/compiler.ts
index e15bb656e4..f4b9250ecf 100644
--- a/libs/remix-tests/src/compiler.ts
+++ b/libs/remix-tests/src/compiler.ts
@@ -12,13 +12,13 @@ function regexIndexOf (inputString: string, regex: RegExp, startpos = 0) {
return (indexOf >= 0) ? (indexOf + (startpos)) : indexOf
}
-function writeTestAccountsContract (accounts: string[]) {
+export function writeTestAccountsContract (accounts: string[]) {
const testAccountContract = require('../sol/tests_accounts.sol')
let body = `address[${accounts.length}] memory accounts;`
if (!accounts.length) body += ';'
else {
accounts.map((address, index) => {
- body += `\naccounts[${index}] = ${address};\n`
+ body += `\n\t\taccounts[${index}] = ${address};\n`
})
}
return testAccountContract.replace('>accounts<', body)
@@ -172,14 +172,7 @@ export function compileFileOrFiles (filename: string, isDirectory: boolean, opts
*/
export function compileContractSources (sources: SrcIfc, compilerConfig: CompilerConfiguration, importFileCb: any, opts: any, cb): void {
let compiler
- const accounts: string[] = opts.accounts || []
const filepath = opts.testFilePath || ''
- // Iterate over sources keys. Inject test libraries. Inject test library import statements.
- if (!('remix_tests.sol' in sources) && !('tests.sol' in sources)) {
- sources['tests.sol'] = { content: require('../sol/tests.sol.js') }
- sources['remix_tests.sol'] = { content: require('../sol/tests.sol.js') }
- sources['remix_accounts.sol'] = { content: writeTestAccountsContract(accounts) }
- }
const testFileImportRegEx = /^(import)\s['"](remix_tests.sol|tests.sol)['"];/gm
const includeTestLibs = '\nimport \'remix_tests.sol\';\n'
diff --git a/libs/remix-tests/src/deployer.ts b/libs/remix-tests/src/deployer.ts
index d700b08de5..505281fe00 100644
--- a/libs/remix-tests/src/deployer.ts
+++ b/libs/remix-tests/src/deployer.ts
@@ -11,18 +11,12 @@ import { compilationInterface } from './types'
* @param callback Callback
*/
-export function deployAll (compileResult: compilationInterface, web3: Web3, withDoubleGas: boolean, deployCb, callback) {
+export function deployAll (compileResult: compilationInterface, web3: Web3, testsAccounts, withDoubleGas: boolean, deployCb, callback) {
const compiledObject = {}
const contracts = {}
- let accounts: string[] = []
+ const accounts: string[] = testsAccounts
async.waterfall([
- function getAccountList (next) {
- web3.eth.getAccounts((_err, _accounts) => {
- accounts = _accounts
- next()
- })
- },
function getContractData (next) {
for (const contractFile in compileResult) {
for (const contractName in compileResult[contractFile]) {
diff --git a/libs/remix-tests/src/index.ts b/libs/remix-tests/src/index.ts
index 9552d5b5ee..37862a47c6 100644
--- a/libs/remix-tests/src/index.ts
+++ b/libs/remix-tests/src/index.ts
@@ -3,3 +3,4 @@ export { UnitTestRunner } from './runTestSources'
export { runTest } from './testRunner'
export * from './types'
export const assertLibCode = require('../sol/tests.sol')
+export { writeTestAccountsContract } from './compiler'
diff --git a/libs/remix-tests/src/runTestFiles.ts b/libs/remix-tests/src/runTestFiles.ts
index d9ed0c2b6e..dbf2b16e46 100644
--- a/libs/remix-tests/src/runTestFiles.ts
+++ b/libs/remix-tests/src/runTestFiles.ts
@@ -61,13 +61,13 @@ export function runTestFiles (filepath: string, isDirectory: boolean, web3: Web3
for (const filename in asts) {
if (filename.endsWith('_test.sol')) { sourceASTs[filename] = asts[filename].ast }
}
- deployAll(compilationResult, web3, false, null, (err, contracts) => {
+ deployAll(compilationResult, web3, accounts, false, null, (err, contracts) => {
if (err) {
// If contract deployment fails because of 'Out of Gas' error, try again with double gas
// This is temporary, should be removed when remix-tests will have a dedicated UI to
// accept deployment params from UI
if (err.message.includes('The contract code couldn\'t be stored, please check your gas limit')) {
- deployAll(compilationResult, web3, true, null, (error, contracts) => {
+ deployAll(compilationResult, web3, accounts, true, null, (error, contracts) => {
if (error) next([{ message: 'contract deployment failed after trying twice: ' + error.message, severity: 'error' }]) // IDE expects errors in array
else next(null, compilationResult, contracts)
})
diff --git a/libs/remix-tests/src/runTestSources.ts b/libs/remix-tests/src/runTestSources.ts
index ecc35aa3f2..9d8b8ba400 100644
--- a/libs/remix-tests/src/runTestSources.ts
+++ b/libs/remix-tests/src/runTestSources.ts
@@ -1,9 +1,7 @@
import async, { ErrorCallback } from 'async'
-
-import { compileContractSources } from './compiler'
+import { compileContractSources, writeTestAccountsContract } from './compiler'
import { deployAll } from './deployer'
import { runTest } from './testRunner'
-
import Web3 from 'web3'
import { EventEmitter } from 'events'
import { Provider, extend } from '@remix-project/remix-simulator'
@@ -15,13 +13,22 @@ require('colors')
export class UnitTestRunner {
event
+ accountsLibCode
+ testsAccounts: string[] | null
+ web3
constructor () {
this.event = new EventEmitter()
}
- async createWeb3Provider () {
- const web3 = new Web3()
+ async init (web3 = null, accounts = null) {
+ this.web3 = await this.createWeb3Provider(web3)
+ this.testsAccounts = accounts || await this.web3.eth.getAccounts()
+ this.accountsLibCode = writeTestAccountsContract(this.testsAccounts)
+ }
+
+ async createWeb3Provider (optWeb3) {
+ const web3 = optWeb3 || new Web3()
const provider: any = new Provider()
await provider.init()
web3.setProvider(provider)
@@ -42,30 +49,23 @@ export class UnitTestRunner {
async runTestSources (contractSources: SrcIfc, compilerConfig: CompilerConfiguration, testCallback, resultCallback, deployCb:any, finalCallback: any, importFileCb, opts: Options) {
opts = opts || {}
const sourceASTs: any = {}
- const web3 = opts.web3 || await this.createWeb3Provider()
- let accounts: string[] | null = opts.accounts || null
+ if (opts.web3 || opts.accounts) this.init(opts.web3, opts.accounts)
+
async.waterfall([
- function getAccountList (next) {
- if (accounts) return next()
- web3.eth.getAccounts((_err, _accounts) => {
- accounts = _accounts
- next()
- })
- },
(next) => {
- compileContractSources(contractSources, compilerConfig, importFileCb, { accounts, testFilePath: opts.testFilePath, event: this.event }, next)
+ compileContractSources(contractSources, compilerConfig, importFileCb, { accounts: this.testsAccounts, testFilePath: opts.testFilePath, event: this.event }, next)
},
- function deployAllContracts (compilationResult: compilationInterface, asts: ASTInterface, next) {
+ (compilationResult: compilationInterface, asts: ASTInterface, next) => {
for (const filename in asts) {
if (filename.endsWith('_test.sol')) { sourceASTs[filename] = asts[filename].ast }
}
- deployAll(compilationResult, web3, false, deployCb, (err, contracts) => {
+ deployAll(compilationResult, this.web3, this.testsAccounts, false, deployCb, (err, contracts) => {
if (err) {
// If contract deployment fails because of 'Out of Gas' error, try again with double gas
// This is temporary, should be removed when remix-tests will have a dedicated UI to
// accept deployment params from UI
if (err.message.includes('The contract code couldn\'t be stored, please check your gas limit')) {
- deployAll(compilationResult, web3, true, deployCb, (error, contracts) => {
+ deployAll(compilationResult, this.web3, this.testsAccounts, true, deployCb, (error, contracts) => {
if (error) next([{ message: 'contract deployment failed after trying twice: ' + error.message, severity: 'error' }]) // IDE expects errors in array
else next(null, compilationResult, contracts)
})
@@ -88,7 +88,7 @@ export class UnitTestRunner {
}
next(null, contractsToTest, contractsToTestDetails, contracts)
},
- function runTests (contractsToTest: string[], contractsToTestDetails: any[], contracts: any, next) {
+ (contractsToTest: string[], contractsToTestDetails: any[], contracts: any, next) => {
let totalPassing = 0
let totalFailing = 0
let totalTime = 0
@@ -111,7 +111,7 @@ export class UnitTestRunner {
async.eachOfLimit(contractsToTest, 1, (contractName: string, index: string | number, cb: ErrorCallback) => {
const fileAST: AstNode = sourceASTs[contracts[contractName]['filename']]
- runTest(contractName, contracts[contractName], contractsToTestDetails[index], fileAST, { accounts, web3 }, _testCallback, (err, result) => {
+ runTest(contractName, contracts[contractName], contractsToTestDetails[index], fileAST, { accounts: this.testsAccounts, web3: this.web3 }, _testCallback, (err, result) => {
if (err) {
return cb(err)
}
diff --git a/libs/remix-tests/tests/testRunner.spec.ts b/libs/remix-tests/tests/testRunner.spec.ts
index 928491faa5..2f6d363a31 100644
--- a/libs/remix-tests/tests/testRunner.spec.ts
+++ b/libs/remix-tests/tests/testRunner.spec.ts
@@ -67,7 +67,7 @@ async function compileAndDeploy(filename: string, callback: Function) {
}
try {
compilationData = compilationResult
- deployAll(compilationResult, web3, false, null, next)
+ deployAll(compilationResult, web3, accounts, false, null, next)
} catch (e) {
throw e
}
diff --git a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx
index fceb98d971..a9124bb866 100644
--- a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx
+++ b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx
@@ -1,6 +1,7 @@
import React, { useState, useRef, useEffect, useReducer } from 'react' // eslint-disable-line
import Editor from '@monaco-editor/react'
import { reducerActions, reducerListener, initialState } from './actions/editor'
+import { language } from './syntax'
import './remix-ui-editor.css'
@@ -77,13 +78,39 @@ export const EditorUI = (props: EditorUIProps) => {
const [editorModelsState, dispatch] = useReducer(reducerActions, initialState)
+ const defineAndSetDarkTheme = (monaco) => {
+ // see https://microsoft.github.io/monaco-editor/playground.html#customizing-the-appearence-exposed-colors
+ const lightColor = window.getComputedStyle(document.documentElement).getPropertyValue('--light').trim()
+ const infoColor = window.getComputedStyle(document.documentElement).getPropertyValue('--info').trim()
+ const darkColor = window.getComputedStyle(document.documentElement).getPropertyValue('--dark').trim()
+ const grayColor = window.getComputedStyle(document.documentElement).getPropertyValue('--gray-dark').trim()
+ monaco.editor.defineTheme('remix-dark', {
+ base: 'vs-dark',
+ inherit: true, // can also be false to completely replace the builtin rules
+ rules: [
+ { background: darkColor.replace('#', '') },
+ { token: 'keyword.external', foreground: infoColor }
+ ],
+ colors: {
+ 'editor.background': darkColor,
+ 'editorSuggestWidget.background': lightColor,
+ 'editorSuggestWidget.selectedBackground': lightColor,
+ 'editorSuggestWidget.highlightForeground': infoColor,
+ 'editor.lineHighlightBorder': lightColor,
+ 'editor.lineHighlightBackground': grayColor,
+ 'editorGutter.background': lightColor
+ }
+ })
+ monacoRef.current.editor.setTheme('remix-dark')
+ }
+
useEffect(() => {
if (!monacoRef.current) return
- monacoRef.current.editor.setTheme(props.theme)
+ if (props.theme === 'remix-dark') {
+ defineAndSetDarkTheme(monacoRef.current)
+ } else monacoRef.current.editor.setTheme(props.theme)
}, [props.theme])
- if (monacoRef.current) monacoRef.current.editor.setTheme(props.theme)
-
const setAnnotationsbyFile = (uri) => {
if (props.sourceAnnotationsPerFile[uri]) {
const model = editorModelsState[uri]?.model
@@ -137,8 +164,10 @@ export const EditorUI = (props: EditorUIProps) => {
useEffect(() => {
if (!editorRef.current) return
currentFileRef.current = props.currentFile
- editorRef.current.setModel(editorModelsState[props.currentFile].model)
+ const file = editorModelsState[props.currentFile]
+ editorRef.current.setModel(file.model)
editorRef.current.updateOptions({ readOnly: editorModelsState[props.currentFile].readOnly })
+ if (file.language === 'sol') monacoRef.current.editor.setModelLanguage(file.model, 'remix-solidity')
setAnnotationsbyFile(props.currentFile)
setMarkerbyFile(props.currentFile)
}, [props.currentFile])
@@ -207,7 +236,9 @@ export const EditorUI = (props: EditorUIProps) => {
function handleEditorDidMount (editor) {
editorRef.current = editor
- monacoRef.current.editor.setTheme(props.theme)
+ if (props.theme === 'remix-dark') {
+ defineAndSetDarkTheme(monacoRef.current)
+ } else monacoRef.current.editor.setTheme(props.theme)
reducerListener(props.plugin, dispatch, monacoRef.current, editorRef.current, props.events)
props.events.onEditorMounted()
editor.onMouseUp((e) => {
@@ -215,29 +246,20 @@ export const EditorUI = (props: EditorUIProps) => {
(window as any).addRemixBreakpoint(e.target.position)
}
})
+ editor.addCommand(monacoRef.current.KeyMod.CtrlCmd | monacoRef.current.KeyCode.US_EQUAL, () => {
+ editor.updateOptions({ fontSize: editor.getOption(42).fontSize + 1 })
+ })
+ editor.addCommand(monacoRef.current.KeyMod.CtrlCmd | monacoRef.current.KeyCode.US_MINUS, () => {
+ editor.updateOptions({ fontSize: editor.getOption(42).fontSize - 1 })
+ })
}
function handleEditorWillMount (monaco) {
monacoRef.current = monaco
- // see https://microsoft.github.io/monaco-editor/playground.html#customizing-the-appearence-exposed-colors
- const lightColor = window.getComputedStyle(document.documentElement).getPropertyValue('--light').trim()
- const infoColor = window.getComputedStyle(document.documentElement).getPropertyValue('--info').trim()
- const darkColor = window.getComputedStyle(document.documentElement).getPropertyValue('--dark').trim()
- const grayColor = window.getComputedStyle(document.documentElement).getPropertyValue('--gray-dark').trim()
- monaco.editor.defineTheme('remix-dark', {
- base: 'vs-dark',
- inherit: true, // can also be false to completely replace the builtin rules
- rules: [{ background: darkColor.replace('#', '') }],
- colors: {
- 'editor.background': darkColor,
- 'editorSuggestWidget.background': lightColor,
- 'editorSuggestWidget.selectedBackground': lightColor,
- 'editorSuggestWidget.highlightForeground': infoColor,
- 'editor.lineHighlightBorder': lightColor,
- 'editor.lineHighlightBackground': grayColor,
- 'editorGutter.background': lightColor
- }
- })
+ // Register a new language
+ monacoRef.current.languages.register({ id: 'remix-solidity' })
+ // Register a tokens provider for the language
+ monacoRef.current.languages.setMonarchTokensProvider('remix-solidity', language)
}
return (
diff --git a/libs/remix-ui/editor/src/lib/syntax.ts b/libs/remix-ui/editor/src/lib/syntax.ts
new file mode 100644
index 0000000000..ccc53716d6
--- /dev/null
+++ b/libs/remix-ui/editor/src/lib/syntax.ts
@@ -0,0 +1,1384 @@
+/* eslint-disable */
+export const conf = {
+ comments: {
+ lineComment: '//',
+ blockComment: ['/*', '*/']
+ },
+ brackets: [
+ ['{', '}'],
+ ['[', ']'],
+ ['(', ')'],
+ ['<', '>']
+ ],
+ autoClosingPairs: [
+ { open: '"', close: '"', notIn: ['string', 'comment'] },
+ { open: '{', close: '}', notIn: ['string', 'comment'] },
+ { open: '[', close: ']', notIn: ['string', 'comment'] },
+ { open: '(', close: ')', notIn: ['string', 'comment'] }
+ ]
+}
+
+export const language = {
+ defaultToken: '',
+ tokenPostfix: '.sol',
+
+ brackets: [
+ { token: 'delimiter.curly', open: '{', close: '}' },
+ { token: 'delimiter.parenthesis', open: '(', close: ')' },
+ { token: 'delimiter.square', open: '[', close: ']' },
+ { token: 'delimiter.angle', open: '<', close: '>' }
+ ],
+
+ keywords: [
+ // Main keywords
+ 'pragma',
+ 'solidity',
+ 'contract',
+ 'library',
+ 'using',
+ 'struct',
+ 'function',
+ 'modifier',
+ 'constructor',
+ // Built-in types
+ 'address',
+ 'string',
+ 'bool',
+ // Other types
+ 'Int',
+ 'Uint',
+ 'Byte',
+ 'Fixed',
+ 'Ufixed',
+ // All int
+ 'int',
+ 'int8',
+ 'int16',
+ 'int24',
+ 'int32',
+ 'int40',
+ 'int48',
+ 'int56',
+ 'int64',
+ 'int72',
+ 'int80',
+ 'int88',
+ 'int96',
+ 'int104',
+ 'int112',
+ 'int120',
+ 'int128',
+ 'int136',
+ 'int144',
+ 'int152',
+ 'int160',
+ 'int168',
+ 'int176',
+ 'int184',
+ 'int192',
+ 'int200',
+ 'int208',
+ 'int216',
+ 'int224',
+ 'int232',
+ 'int240',
+ 'int248',
+ 'int256',
+ // All uint
+ 'uint',
+ 'uint8',
+ 'uint16',
+ 'uint24',
+ 'uint32',
+ 'uint40',
+ 'uint48',
+ 'uint56',
+ 'uint64',
+ 'uint72',
+ 'uint80',
+ 'uint88',
+ 'uint96',
+ 'uint104',
+ 'uint112',
+ 'uint120',
+ 'uint128',
+ 'uint136',
+ 'uint144',
+ 'uint152',
+ 'uint160',
+ 'uint168',
+ 'uint176',
+ 'uint184',
+ 'uint192',
+ 'uint200',
+ 'uint208',
+ 'uint216',
+ 'uint224',
+ 'uint232',
+ 'uint240',
+ 'uint248',
+ 'uint256',
+ // All Byte
+ 'byte',
+ 'bytes',
+ 'bytes1',
+ 'bytes2',
+ 'bytes3',
+ 'bytes4',
+ 'bytes5',
+ 'bytes6',
+ 'bytes7',
+ 'bytes8',
+ 'bytes9',
+ 'bytes10',
+ 'bytes11',
+ 'bytes12',
+ 'bytes13',
+ 'bytes14',
+ 'bytes15',
+ 'bytes16',
+ 'bytes17',
+ 'bytes18',
+ 'bytes19',
+ 'bytes20',
+ 'bytes21',
+ 'bytes22',
+ 'bytes23',
+ 'bytes24',
+ 'bytes25',
+ 'bytes26',
+ 'bytes27',
+ 'bytes28',
+ 'bytes29',
+ 'bytes30',
+ 'bytes31',
+ 'bytes32',
+ // All fixed
+ 'fixed',
+ 'fixed0x8',
+ 'fixed0x16',
+ 'fixed0x24',
+ 'fixed0x32',
+ 'fixed0x40',
+ 'fixed0x48',
+ 'fixed0x56',
+ 'fixed0x64',
+ 'fixed0x72',
+ 'fixed0x80',
+ 'fixed0x88',
+ 'fixed0x96',
+ 'fixed0x104',
+ 'fixed0x112',
+ 'fixed0x120',
+ 'fixed0x128',
+ 'fixed0x136',
+ 'fixed0x144',
+ 'fixed0x152',
+ 'fixed0x160',
+ 'fixed0x168',
+ 'fixed0x176',
+ 'fixed0x184',
+ 'fixed0x192',
+ 'fixed0x200',
+ 'fixed0x208',
+ 'fixed0x216',
+ 'fixed0x224',
+ 'fixed0x232',
+ 'fixed0x240',
+ 'fixed0x248',
+ 'fixed0x256',
+ 'fixed8x8',
+ 'fixed8x16',
+ 'fixed8x24',
+ 'fixed8x32',
+ 'fixed8x40',
+ 'fixed8x48',
+ 'fixed8x56',
+ 'fixed8x64',
+ 'fixed8x72',
+ 'fixed8x80',
+ 'fixed8x88',
+ 'fixed8x96',
+ 'fixed8x104',
+ 'fixed8x112',
+ 'fixed8x120',
+ 'fixed8x128',
+ 'fixed8x136',
+ 'fixed8x144',
+ 'fixed8x152',
+ 'fixed8x160',
+ 'fixed8x168',
+ 'fixed8x176',
+ 'fixed8x184',
+ 'fixed8x192',
+ 'fixed8x200',
+ 'fixed8x208',
+ 'fixed8x216',
+ 'fixed8x224',
+ 'fixed8x232',
+ 'fixed8x240',
+ 'fixed8x248',
+ 'fixed16x8',
+ 'fixed16x16',
+ 'fixed16x24',
+ 'fixed16x32',
+ 'fixed16x40',
+ 'fixed16x48',
+ 'fixed16x56',
+ 'fixed16x64',
+ 'fixed16x72',
+ 'fixed16x80',
+ 'fixed16x88',
+ 'fixed16x96',
+ 'fixed16x104',
+ 'fixed16x112',
+ 'fixed16x120',
+ 'fixed16x128',
+ 'fixed16x136',
+ 'fixed16x144',
+ 'fixed16x152',
+ 'fixed16x160',
+ 'fixed16x168',
+ 'fixed16x176',
+ 'fixed16x184',
+ 'fixed16x192',
+ 'fixed16x200',
+ 'fixed16x208',
+ 'fixed16x216',
+ 'fixed16x224',
+ 'fixed16x232',
+ 'fixed16x240',
+ 'fixed24x8',
+ 'fixed24x16',
+ 'fixed24x24',
+ 'fixed24x32',
+ 'fixed24x40',
+ 'fixed24x48',
+ 'fixed24x56',
+ 'fixed24x64',
+ 'fixed24x72',
+ 'fixed24x80',
+ 'fixed24x88',
+ 'fixed24x96',
+ 'fixed24x104',
+ 'fixed24x112',
+ 'fixed24x120',
+ 'fixed24x128',
+ 'fixed24x136',
+ 'fixed24x144',
+ 'fixed24x152',
+ 'fixed24x160',
+ 'fixed24x168',
+ 'fixed24x176',
+ 'fixed24x184',
+ 'fixed24x192',
+ 'fixed24x200',
+ 'fixed24x208',
+ 'fixed24x216',
+ 'fixed24x224',
+ 'fixed24x232',
+ 'fixed32x8',
+ 'fixed32x16',
+ 'fixed32x24',
+ 'fixed32x32',
+ 'fixed32x40',
+ 'fixed32x48',
+ 'fixed32x56',
+ 'fixed32x64',
+ 'fixed32x72',
+ 'fixed32x80',
+ 'fixed32x88',
+ 'fixed32x96',
+ 'fixed32x104',
+ 'fixed32x112',
+ 'fixed32x120',
+ 'fixed32x128',
+ 'fixed32x136',
+ 'fixed32x144',
+ 'fixed32x152',
+ 'fixed32x160',
+ 'fixed32x168',
+ 'fixed32x176',
+ 'fixed32x184',
+ 'fixed32x192',
+ 'fixed32x200',
+ 'fixed32x208',
+ 'fixed32x216',
+ 'fixed32x224',
+ 'fixed40x8',
+ 'fixed40x16',
+ 'fixed40x24',
+ 'fixed40x32',
+ 'fixed40x40',
+ 'fixed40x48',
+ 'fixed40x56',
+ 'fixed40x64',
+ 'fixed40x72',
+ 'fixed40x80',
+ 'fixed40x88',
+ 'fixed40x96',
+ 'fixed40x104',
+ 'fixed40x112',
+ 'fixed40x120',
+ 'fixed40x128',
+ 'fixed40x136',
+ 'fixed40x144',
+ 'fixed40x152',
+ 'fixed40x160',
+ 'fixed40x168',
+ 'fixed40x176',
+ 'fixed40x184',
+ 'fixed40x192',
+ 'fixed40x200',
+ 'fixed40x208',
+ 'fixed40x216',
+ 'fixed48x8',
+ 'fixed48x16',
+ 'fixed48x24',
+ 'fixed48x32',
+ 'fixed48x40',
+ 'fixed48x48',
+ 'fixed48x56',
+ 'fixed48x64',
+ 'fixed48x72',
+ 'fixed48x80',
+ 'fixed48x88',
+ 'fixed48x96',
+ 'fixed48x104',
+ 'fixed48x112',
+ 'fixed48x120',
+ 'fixed48x128',
+ 'fixed48x136',
+ 'fixed48x144',
+ 'fixed48x152',
+ 'fixed48x160',
+ 'fixed48x168',
+ 'fixed48x176',
+ 'fixed48x184',
+ 'fixed48x192',
+ 'fixed48x200',
+ 'fixed48x208',
+ 'fixed56x8',
+ 'fixed56x16',
+ 'fixed56x24',
+ 'fixed56x32',
+ 'fixed56x40',
+ 'fixed56x48',
+ 'fixed56x56',
+ 'fixed56x64',
+ 'fixed56x72',
+ 'fixed56x80',
+ 'fixed56x88',
+ 'fixed56x96',
+ 'fixed56x104',
+ 'fixed56x112',
+ 'fixed56x120',
+ 'fixed56x128',
+ 'fixed56x136',
+ 'fixed56x144',
+ 'fixed56x152',
+ 'fixed56x160',
+ 'fixed56x168',
+ 'fixed56x176',
+ 'fixed56x184',
+ 'fixed56x192',
+ 'fixed56x200',
+ 'fixed64x8',
+ 'fixed64x16',
+ 'fixed64x24',
+ 'fixed64x32',
+ 'fixed64x40',
+ 'fixed64x48',
+ 'fixed64x56',
+ 'fixed64x64',
+ 'fixed64x72',
+ 'fixed64x80',
+ 'fixed64x88',
+ 'fixed64x96',
+ 'fixed64x104',
+ 'fixed64x112',
+ 'fixed64x120',
+ 'fixed64x128',
+ 'fixed64x136',
+ 'fixed64x144',
+ 'fixed64x152',
+ 'fixed64x160',
+ 'fixed64x168',
+ 'fixed64x176',
+ 'fixed64x184',
+ 'fixed64x192',
+ 'fixed72x8',
+ 'fixed72x16',
+ 'fixed72x24',
+ 'fixed72x32',
+ 'fixed72x40',
+ 'fixed72x48',
+ 'fixed72x56',
+ 'fixed72x64',
+ 'fixed72x72',
+ 'fixed72x80',
+ 'fixed72x88',
+ 'fixed72x96',
+ 'fixed72x104',
+ 'fixed72x112',
+ 'fixed72x120',
+ 'fixed72x128',
+ 'fixed72x136',
+ 'fixed72x144',
+ 'fixed72x152',
+ 'fixed72x160',
+ 'fixed72x168',
+ 'fixed72x176',
+ 'fixed72x184',
+ 'fixed80x8',
+ 'fixed80x16',
+ 'fixed80x24',
+ 'fixed80x32',
+ 'fixed80x40',
+ 'fixed80x48',
+ 'fixed80x56',
+ 'fixed80x64',
+ 'fixed80x72',
+ 'fixed80x80',
+ 'fixed80x88',
+ 'fixed80x96',
+ 'fixed80x104',
+ 'fixed80x112',
+ 'fixed80x120',
+ 'fixed80x128',
+ 'fixed80x136',
+ 'fixed80x144',
+ 'fixed80x152',
+ 'fixed80x160',
+ 'fixed80x168',
+ 'fixed80x176',
+ 'fixed88x8',
+ 'fixed88x16',
+ 'fixed88x24',
+ 'fixed88x32',
+ 'fixed88x40',
+ 'fixed88x48',
+ 'fixed88x56',
+ 'fixed88x64',
+ 'fixed88x72',
+ 'fixed88x80',
+ 'fixed88x88',
+ 'fixed88x96',
+ 'fixed88x104',
+ 'fixed88x112',
+ 'fixed88x120',
+ 'fixed88x128',
+ 'fixed88x136',
+ 'fixed88x144',
+ 'fixed88x152',
+ 'fixed88x160',
+ 'fixed88x168',
+ 'fixed96x8',
+ 'fixed96x16',
+ 'fixed96x24',
+ 'fixed96x32',
+ 'fixed96x40',
+ 'fixed96x48',
+ 'fixed96x56',
+ 'fixed96x64',
+ 'fixed96x72',
+ 'fixed96x80',
+ 'fixed96x88',
+ 'fixed96x96',
+ 'fixed96x104',
+ 'fixed96x112',
+ 'fixed96x120',
+ 'fixed96x128',
+ 'fixed96x136',
+ 'fixed96x144',
+ 'fixed96x152',
+ 'fixed96x160',
+ 'fixed104x8',
+ 'fixed104x16',
+ 'fixed104x24',
+ 'fixed104x32',
+ 'fixed104x40',
+ 'fixed104x48',
+ 'fixed104x56',
+ 'fixed104x64',
+ 'fixed104x72',
+ 'fixed104x80',
+ 'fixed104x88',
+ 'fixed104x96',
+ 'fixed104x104',
+ 'fixed104x112',
+ 'fixed104x120',
+ 'fixed104x128',
+ 'fixed104x136',
+ 'fixed104x144',
+ 'fixed104x152',
+ 'fixed112x8',
+ 'fixed112x16',
+ 'fixed112x24',
+ 'fixed112x32',
+ 'fixed112x40',
+ 'fixed112x48',
+ 'fixed112x56',
+ 'fixed112x64',
+ 'fixed112x72',
+ 'fixed112x80',
+ 'fixed112x88',
+ 'fixed112x96',
+ 'fixed112x104',
+ 'fixed112x112',
+ 'fixed112x120',
+ 'fixed112x128',
+ 'fixed112x136',
+ 'fixed112x144',
+ 'fixed120x8',
+ 'fixed120x16',
+ 'fixed120x24',
+ 'fixed120x32',
+ 'fixed120x40',
+ 'fixed120x48',
+ 'fixed120x56',
+ 'fixed120x64',
+ 'fixed120x72',
+ 'fixed120x80',
+ 'fixed120x88',
+ 'fixed120x96',
+ 'fixed120x104',
+ 'fixed120x112',
+ 'fixed120x120',
+ 'fixed120x128',
+ 'fixed120x136',
+ 'fixed128x8',
+ 'fixed128x16',
+ 'fixed128x24',
+ 'fixed128x32',
+ 'fixed128x40',
+ 'fixed128x48',
+ 'fixed128x56',
+ 'fixed128x64',
+ 'fixed128x72',
+ 'fixed128x80',
+ 'fixed128x88',
+ 'fixed128x96',
+ 'fixed128x104',
+ 'fixed128x112',
+ 'fixed128x120',
+ 'fixed128x128',
+ 'fixed136x8',
+ 'fixed136x16',
+ 'fixed136x24',
+ 'fixed136x32',
+ 'fixed136x40',
+ 'fixed136x48',
+ 'fixed136x56',
+ 'fixed136x64',
+ 'fixed136x72',
+ 'fixed136x80',
+ 'fixed136x88',
+ 'fixed136x96',
+ 'fixed136x104',
+ 'fixed136x112',
+ 'fixed136x120',
+ 'fixed144x8',
+ 'fixed144x16',
+ 'fixed144x24',
+ 'fixed144x32',
+ 'fixed144x40',
+ 'fixed144x48',
+ 'fixed144x56',
+ 'fixed144x64',
+ 'fixed144x72',
+ 'fixed144x80',
+ 'fixed144x88',
+ 'fixed144x96',
+ 'fixed144x104',
+ 'fixed144x112',
+ 'fixed152x8',
+ 'fixed152x16',
+ 'fixed152x24',
+ 'fixed152x32',
+ 'fixed152x40',
+ 'fixed152x48',
+ 'fixed152x56',
+ 'fixed152x64',
+ 'fixed152x72',
+ 'fixed152x80',
+ 'fixed152x88',
+ 'fixed152x96',
+ 'fixed152x104',
+ 'fixed160x8',
+ 'fixed160x16',
+ 'fixed160x24',
+ 'fixed160x32',
+ 'fixed160x40',
+ 'fixed160x48',
+ 'fixed160x56',
+ 'fixed160x64',
+ 'fixed160x72',
+ 'fixed160x80',
+ 'fixed160x88',
+ 'fixed160x96',
+ 'fixed168x8',
+ 'fixed168x16',
+ 'fixed168x24',
+ 'fixed168x32',
+ 'fixed168x40',
+ 'fixed168x48',
+ 'fixed168x56',
+ 'fixed168x64',
+ 'fixed168x72',
+ 'fixed168x80',
+ 'fixed168x88',
+ 'fixed176x8',
+ 'fixed176x16',
+ 'fixed176x24',
+ 'fixed176x32',
+ 'fixed176x40',
+ 'fixed176x48',
+ 'fixed176x56',
+ 'fixed176x64',
+ 'fixed176x72',
+ 'fixed176x80',
+ 'fixed184x8',
+ 'fixed184x16',
+ 'fixed184x24',
+ 'fixed184x32',
+ 'fixed184x40',
+ 'fixed184x48',
+ 'fixed184x56',
+ 'fixed184x64',
+ 'fixed184x72',
+ 'fixed192x8',
+ 'fixed192x16',
+ 'fixed192x24',
+ 'fixed192x32',
+ 'fixed192x40',
+ 'fixed192x48',
+ 'fixed192x56',
+ 'fixed192x64',
+ 'fixed200x8',
+ 'fixed200x16',
+ 'fixed200x24',
+ 'fixed200x32',
+ 'fixed200x40',
+ 'fixed200x48',
+ 'fixed200x56',
+ 'fixed208x8',
+ 'fixed208x16',
+ 'fixed208x24',
+ 'fixed208x32',
+ 'fixed208x40',
+ 'fixed208x48',
+ 'fixed216x8',
+ 'fixed216x16',
+ 'fixed216x24',
+ 'fixed216x32',
+ 'fixed216x40',
+ 'fixed224x8',
+ 'fixed224x16',
+ 'fixed224x24',
+ 'fixed224x32',
+ 'fixed232x8',
+ 'fixed232x16',
+ 'fixed232x24',
+ 'fixed240x8',
+ 'fixed240x16',
+ 'fixed248x8',
+ // All ufixed
+ 'ufixed',
+ 'ufixed0x8',
+ 'ufixed0x16',
+ 'ufixed0x24',
+ 'ufixed0x32',
+ 'ufixed0x40',
+ 'ufixed0x48',
+ 'ufixed0x56',
+ 'ufixed0x64',
+ 'ufixed0x72',
+ 'ufixed0x80',
+ 'ufixed0x88',
+ 'ufixed0x96',
+ 'ufixed0x104',
+ 'ufixed0x112',
+ 'ufixed0x120',
+ 'ufixed0x128',
+ 'ufixed0x136',
+ 'ufixed0x144',
+ 'ufixed0x152',
+ 'ufixed0x160',
+ 'ufixed0x168',
+ 'ufixed0x176',
+ 'ufixed0x184',
+ 'ufixed0x192',
+ 'ufixed0x200',
+ 'ufixed0x208',
+ 'ufixed0x216',
+ 'ufixed0x224',
+ 'ufixed0x232',
+ 'ufixed0x240',
+ 'ufixed0x248',
+ 'ufixed0x256',
+ 'ufixed8x8',
+ 'ufixed8x16',
+ 'ufixed8x24',
+ 'ufixed8x32',
+ 'ufixed8x40',
+ 'ufixed8x48',
+ 'ufixed8x56',
+ 'ufixed8x64',
+ 'ufixed8x72',
+ 'ufixed8x80',
+ 'ufixed8x88',
+ 'ufixed8x96',
+ 'ufixed8x104',
+ 'ufixed8x112',
+ 'ufixed8x120',
+ 'ufixed8x128',
+ 'ufixed8x136',
+ 'ufixed8x144',
+ 'ufixed8x152',
+ 'ufixed8x160',
+ 'ufixed8x168',
+ 'ufixed8x176',
+ 'ufixed8x184',
+ 'ufixed8x192',
+ 'ufixed8x200',
+ 'ufixed8x208',
+ 'ufixed8x216',
+ 'ufixed8x224',
+ 'ufixed8x232',
+ 'ufixed8x240',
+ 'ufixed8x248',
+ 'ufixed16x8',
+ 'ufixed16x16',
+ 'ufixed16x24',
+ 'ufixed16x32',
+ 'ufixed16x40',
+ 'ufixed16x48',
+ 'ufixed16x56',
+ 'ufixed16x64',
+ 'ufixed16x72',
+ 'ufixed16x80',
+ 'ufixed16x88',
+ 'ufixed16x96',
+ 'ufixed16x104',
+ 'ufixed16x112',
+ 'ufixed16x120',
+ 'ufixed16x128',
+ 'ufixed16x136',
+ 'ufixed16x144',
+ 'ufixed16x152',
+ 'ufixed16x160',
+ 'ufixed16x168',
+ 'ufixed16x176',
+ 'ufixed16x184',
+ 'ufixed16x192',
+ 'ufixed16x200',
+ 'ufixed16x208',
+ 'ufixed16x216',
+ 'ufixed16x224',
+ 'ufixed16x232',
+ 'ufixed16x240',
+ 'ufixed24x8',
+ 'ufixed24x16',
+ 'ufixed24x24',
+ 'ufixed24x32',
+ 'ufixed24x40',
+ 'ufixed24x48',
+ 'ufixed24x56',
+ 'ufixed24x64',
+ 'ufixed24x72',
+ 'ufixed24x80',
+ 'ufixed24x88',
+ 'ufixed24x96',
+ 'ufixed24x104',
+ 'ufixed24x112',
+ 'ufixed24x120',
+ 'ufixed24x128',
+ 'ufixed24x136',
+ 'ufixed24x144',
+ 'ufixed24x152',
+ 'ufixed24x160',
+ 'ufixed24x168',
+ 'ufixed24x176',
+ 'ufixed24x184',
+ 'ufixed24x192',
+ 'ufixed24x200',
+ 'ufixed24x208',
+ 'ufixed24x216',
+ 'ufixed24x224',
+ 'ufixed24x232',
+ 'ufixed32x8',
+ 'ufixed32x16',
+ 'ufixed32x24',
+ 'ufixed32x32',
+ 'ufixed32x40',
+ 'ufixed32x48',
+ 'ufixed32x56',
+ 'ufixed32x64',
+ 'ufixed32x72',
+ 'ufixed32x80',
+ 'ufixed32x88',
+ 'ufixed32x96',
+ 'ufixed32x104',
+ 'ufixed32x112',
+ 'ufixed32x120',
+ 'ufixed32x128',
+ 'ufixed32x136',
+ 'ufixed32x144',
+ 'ufixed32x152',
+ 'ufixed32x160',
+ 'ufixed32x168',
+ 'ufixed32x176',
+ 'ufixed32x184',
+ 'ufixed32x192',
+ 'ufixed32x200',
+ 'ufixed32x208',
+ 'ufixed32x216',
+ 'ufixed32x224',
+ 'ufixed40x8',
+ 'ufixed40x16',
+ 'ufixed40x24',
+ 'ufixed40x32',
+ 'ufixed40x40',
+ 'ufixed40x48',
+ 'ufixed40x56',
+ 'ufixed40x64',
+ 'ufixed40x72',
+ 'ufixed40x80',
+ 'ufixed40x88',
+ 'ufixed40x96',
+ 'ufixed40x104',
+ 'ufixed40x112',
+ 'ufixed40x120',
+ 'ufixed40x128',
+ 'ufixed40x136',
+ 'ufixed40x144',
+ 'ufixed40x152',
+ 'ufixed40x160',
+ 'ufixed40x168',
+ 'ufixed40x176',
+ 'ufixed40x184',
+ 'ufixed40x192',
+ 'ufixed40x200',
+ 'ufixed40x208',
+ 'ufixed40x216',
+ 'ufixed48x8',
+ 'ufixed48x16',
+ 'ufixed48x24',
+ 'ufixed48x32',
+ 'ufixed48x40',
+ 'ufixed48x48',
+ 'ufixed48x56',
+ 'ufixed48x64',
+ 'ufixed48x72',
+ 'ufixed48x80',
+ 'ufixed48x88',
+ 'ufixed48x96',
+ 'ufixed48x104',
+ 'ufixed48x112',
+ 'ufixed48x120',
+ 'ufixed48x128',
+ 'ufixed48x136',
+ 'ufixed48x144',
+ 'ufixed48x152',
+ 'ufixed48x160',
+ 'ufixed48x168',
+ 'ufixed48x176',
+ 'ufixed48x184',
+ 'ufixed48x192',
+ 'ufixed48x200',
+ 'ufixed48x208',
+ 'ufixed56x8',
+ 'ufixed56x16',
+ 'ufixed56x24',
+ 'ufixed56x32',
+ 'ufixed56x40',
+ 'ufixed56x48',
+ 'ufixed56x56',
+ 'ufixed56x64',
+ 'ufixed56x72',
+ 'ufixed56x80',
+ 'ufixed56x88',
+ 'ufixed56x96',
+ 'ufixed56x104',
+ 'ufixed56x112',
+ 'ufixed56x120',
+ 'ufixed56x128',
+ 'ufixed56x136',
+ 'ufixed56x144',
+ 'ufixed56x152',
+ 'ufixed56x160',
+ 'ufixed56x168',
+ 'ufixed56x176',
+ 'ufixed56x184',
+ 'ufixed56x192',
+ 'ufixed56x200',
+ 'ufixed64x8',
+ 'ufixed64x16',
+ 'ufixed64x24',
+ 'ufixed64x32',
+ 'ufixed64x40',
+ 'ufixed64x48',
+ 'ufixed64x56',
+ 'ufixed64x64',
+ 'ufixed64x72',
+ 'ufixed64x80',
+ 'ufixed64x88',
+ 'ufixed64x96',
+ 'ufixed64x104',
+ 'ufixed64x112',
+ 'ufixed64x120',
+ 'ufixed64x128',
+ 'ufixed64x136',
+ 'ufixed64x144',
+ 'ufixed64x152',
+ 'ufixed64x160',
+ 'ufixed64x168',
+ 'ufixed64x176',
+ 'ufixed64x184',
+ 'ufixed64x192',
+ 'ufixed72x8',
+ 'ufixed72x16',
+ 'ufixed72x24',
+ 'ufixed72x32',
+ 'ufixed72x40',
+ 'ufixed72x48',
+ 'ufixed72x56',
+ 'ufixed72x64',
+ 'ufixed72x72',
+ 'ufixed72x80',
+ 'ufixed72x88',
+ 'ufixed72x96',
+ 'ufixed72x104',
+ 'ufixed72x112',
+ 'ufixed72x120',
+ 'ufixed72x128',
+ 'ufixed72x136',
+ 'ufixed72x144',
+ 'ufixed72x152',
+ 'ufixed72x160',
+ 'ufixed72x168',
+ 'ufixed72x176',
+ 'ufixed72x184',
+ 'ufixed80x8',
+ 'ufixed80x16',
+ 'ufixed80x24',
+ 'ufixed80x32',
+ 'ufixed80x40',
+ 'ufixed80x48',
+ 'ufixed80x56',
+ 'ufixed80x64',
+ 'ufixed80x72',
+ 'ufixed80x80',
+ 'ufixed80x88',
+ 'ufixed80x96',
+ 'ufixed80x104',
+ 'ufixed80x112',
+ 'ufixed80x120',
+ 'ufixed80x128',
+ 'ufixed80x136',
+ 'ufixed80x144',
+ 'ufixed80x152',
+ 'ufixed80x160',
+ 'ufixed80x168',
+ 'ufixed80x176',
+ 'ufixed88x8',
+ 'ufixed88x16',
+ 'ufixed88x24',
+ 'ufixed88x32',
+ 'ufixed88x40',
+ 'ufixed88x48',
+ 'ufixed88x56',
+ 'ufixed88x64',
+ 'ufixed88x72',
+ 'ufixed88x80',
+ 'ufixed88x88',
+ 'ufixed88x96',
+ 'ufixed88x104',
+ 'ufixed88x112',
+ 'ufixed88x120',
+ 'ufixed88x128',
+ 'ufixed88x136',
+ 'ufixed88x144',
+ 'ufixed88x152',
+ 'ufixed88x160',
+ 'ufixed88x168',
+ 'ufixed96x8',
+ 'ufixed96x16',
+ 'ufixed96x24',
+ 'ufixed96x32',
+ 'ufixed96x40',
+ 'ufixed96x48',
+ 'ufixed96x56',
+ 'ufixed96x64',
+ 'ufixed96x72',
+ 'ufixed96x80',
+ 'ufixed96x88',
+ 'ufixed96x96',
+ 'ufixed96x104',
+ 'ufixed96x112',
+ 'ufixed96x120',
+ 'ufixed96x128',
+ 'ufixed96x136',
+ 'ufixed96x144',
+ 'ufixed96x152',
+ 'ufixed96x160',
+ 'ufixed104x8',
+ 'ufixed104x16',
+ 'ufixed104x24',
+ 'ufixed104x32',
+ 'ufixed104x40',
+ 'ufixed104x48',
+ 'ufixed104x56',
+ 'ufixed104x64',
+ 'ufixed104x72',
+ 'ufixed104x80',
+ 'ufixed104x88',
+ 'ufixed104x96',
+ 'ufixed104x104',
+ 'ufixed104x112',
+ 'ufixed104x120',
+ 'ufixed104x128',
+ 'ufixed104x136',
+ 'ufixed104x144',
+ 'ufixed104x152',
+ 'ufixed112x8',
+ 'ufixed112x16',
+ 'ufixed112x24',
+ 'ufixed112x32',
+ 'ufixed112x40',
+ 'ufixed112x48',
+ 'ufixed112x56',
+ 'ufixed112x64',
+ 'ufixed112x72',
+ 'ufixed112x80',
+ 'ufixed112x88',
+ 'ufixed112x96',
+ 'ufixed112x104',
+ 'ufixed112x112',
+ 'ufixed112x120',
+ 'ufixed112x128',
+ 'ufixed112x136',
+ 'ufixed112x144',
+ 'ufixed120x8',
+ 'ufixed120x16',
+ 'ufixed120x24',
+ 'ufixed120x32',
+ 'ufixed120x40',
+ 'ufixed120x48',
+ 'ufixed120x56',
+ 'ufixed120x64',
+ 'ufixed120x72',
+ 'ufixed120x80',
+ 'ufixed120x88',
+ 'ufixed120x96',
+ 'ufixed120x104',
+ 'ufixed120x112',
+ 'ufixed120x120',
+ 'ufixed120x128',
+ 'ufixed120x136',
+ 'ufixed128x8',
+ 'ufixed128x16',
+ 'ufixed128x24',
+ 'ufixed128x32',
+ 'ufixed128x40',
+ 'ufixed128x48',
+ 'ufixed128x56',
+ 'ufixed128x64',
+ 'ufixed128x72',
+ 'ufixed128x80',
+ 'ufixed128x88',
+ 'ufixed128x96',
+ 'ufixed128x104',
+ 'ufixed128x112',
+ 'ufixed128x120',
+ 'ufixed128x128',
+ 'ufixed136x8',
+ 'ufixed136x16',
+ 'ufixed136x24',
+ 'ufixed136x32',
+ 'ufixed136x40',
+ 'ufixed136x48',
+ 'ufixed136x56',
+ 'ufixed136x64',
+ 'ufixed136x72',
+ 'ufixed136x80',
+ 'ufixed136x88',
+ 'ufixed136x96',
+ 'ufixed136x104',
+ 'ufixed136x112',
+ 'ufixed136x120',
+ 'ufixed144x8',
+ 'ufixed144x16',
+ 'ufixed144x24',
+ 'ufixed144x32',
+ 'ufixed144x40',
+ 'ufixed144x48',
+ 'ufixed144x56',
+ 'ufixed144x64',
+ 'ufixed144x72',
+ 'ufixed144x80',
+ 'ufixed144x88',
+ 'ufixed144x96',
+ 'ufixed144x104',
+ 'ufixed144x112',
+ 'ufixed152x8',
+ 'ufixed152x16',
+ 'ufixed152x24',
+ 'ufixed152x32',
+ 'ufixed152x40',
+ 'ufixed152x48',
+ 'ufixed152x56',
+ 'ufixed152x64',
+ 'ufixed152x72',
+ 'ufixed152x80',
+ 'ufixed152x88',
+ 'ufixed152x96',
+ 'ufixed152x104',
+ 'ufixed160x8',
+ 'ufixed160x16',
+ 'ufixed160x24',
+ 'ufixed160x32',
+ 'ufixed160x40',
+ 'ufixed160x48',
+ 'ufixed160x56',
+ 'ufixed160x64',
+ 'ufixed160x72',
+ 'ufixed160x80',
+ 'ufixed160x88',
+ 'ufixed160x96',
+ 'ufixed168x8',
+ 'ufixed168x16',
+ 'ufixed168x24',
+ 'ufixed168x32',
+ 'ufixed168x40',
+ 'ufixed168x48',
+ 'ufixed168x56',
+ 'ufixed168x64',
+ 'ufixed168x72',
+ 'ufixed168x80',
+ 'ufixed168x88',
+ 'ufixed176x8',
+ 'ufixed176x16',
+ 'ufixed176x24',
+ 'ufixed176x32',
+ 'ufixed176x40',
+ 'ufixed176x48',
+ 'ufixed176x56',
+ 'ufixed176x64',
+ 'ufixed176x72',
+ 'ufixed176x80',
+ 'ufixed184x8',
+ 'ufixed184x16',
+ 'ufixed184x24',
+ 'ufixed184x32',
+ 'ufixed184x40',
+ 'ufixed184x48',
+ 'ufixed184x56',
+ 'ufixed184x64',
+ 'ufixed184x72',
+ 'ufixed192x8',
+ 'ufixed192x16',
+ 'ufixed192x24',
+ 'ufixed192x32',
+ 'ufixed192x40',
+ 'ufixed192x48',
+ 'ufixed192x56',
+ 'ufixed192x64',
+ 'ufixed200x8',
+ 'ufixed200x16',
+ 'ufixed200x24',
+ 'ufixed200x32',
+ 'ufixed200x40',
+ 'ufixed200x48',
+ 'ufixed200x56',
+ 'ufixed208x8',
+ 'ufixed208x16',
+ 'ufixed208x24',
+ 'ufixed208x32',
+ 'ufixed208x40',
+ 'ufixed208x48',
+ 'ufixed216x8',
+ 'ufixed216x16',
+ 'ufixed216x24',
+ 'ufixed216x32',
+ 'ufixed216x40',
+ 'ufixed224x8',
+ 'ufixed224x16',
+ 'ufixed224x24',
+ 'ufixed224x32',
+ 'ufixed232x8',
+ 'ufixed232x16',
+ 'ufixed232x24',
+ 'ufixed240x8',
+ 'ufixed240x16',
+ 'ufixed248x8',
+ 'event',
+ 'enum',
+ 'let',
+ 'mapping',
+ 'private',
+ 'public',
+ 'external',
+ 'view',
+ 'pure',
+ 'inherited',
+ 'payable',
+ 'true',
+ 'false',
+ 'var',
+ 'import',
+ 'constant',
+ 'if',
+ 'else',
+ 'for',
+ 'else',
+ 'for',
+ 'while',
+ 'do',
+ 'break',
+ 'continue',
+ 'throw',
+ 'returns',
+ 'return',
+ 'suicide',
+ 'new',
+ 'is',
+ 'this',
+ 'super'
+ ],
+
+ operators: [
+ '=',
+ '>',
+ '<',
+ '!',
+ '~',
+ '?',
+ ':',
+ '==',
+ '<=',
+ '>=',
+ '!=',
+ '&&',
+ '||',
+ '++',
+ '--',
+ '+',
+ '-',
+ '*',
+ '/',
+ '&',
+ '|',
+ '^',
+ '%',
+ '<<',
+ '>>',
+ '>>>',
+ '+=',
+ '-=',
+ '*=',
+ '/=',
+ '&=',
+ '|=',
+ '^=',
+ '%=',
+ '<<=',
+ '>>=',
+ '>>>='
+ ],
+
+ // we include these common regular expressions
+ symbols: /[=>](?!@symbols)/, '@brackets'],
+ [
+ /@symbols/,
+ {
+ cases: {
+ '@operators': 'delimiter',
+ '@default': ''
+ }
+ }
+ ],
+
+ // numbers
+ [/\d*\d+[eE]([\-+]?\d+)?(@floatsuffix)/, 'number.float'],
+ [/\d*\.\d+([eE][\-+]?\d+)?(@floatsuffix)/, 'number.float'],
+ [/0[xX][0-9a-fA-F']*[0-9a-fA-F](@integersuffix)/, 'number.hex'],
+ [/0[0-7']*[0-7](@integersuffix)/, 'number.octal'],
+ [/0[bB][0-1']*[0-1](@integersuffix)/, 'number.binary'],
+ [/\d[\d']*\d(@integersuffix)/, 'number'],
+ [/\d(@integersuffix)/, 'number'],
+
+ // delimiter: after number because of .\d floats
+ [/[;,.]/, 'delimiter'],
+
+ // strings
+ [/"([^"\\]|\\.)*$/, 'string.invalid'], // non-teminated string
+ [/"/, 'string', '@string'],
+
+ // characters
+ [/'[^\\']'/, 'string'],
+ [/(')(@escapes)(')/, ['string', 'string.escape', 'string']],
+ [/'/, 'string.invalid']
+ ],
+
+ whitespace: [
+ [/[ \t\r\n]+/, ''],
+ [/\/\*\*(?!\/)/, 'comment.doc', '@doccomment'],
+ [/\/\*/, 'comment', '@comment'],
+ [/\/\/.*$/, 'comment']
+ ],
+
+ comment: [
+ [/[^\/*]+/, 'comment'],
+ [/\*\//, 'comment', '@pop'],
+ [/[\/*]/, 'comment']
+ ],
+ // Identical copy of comment above, except for the addition of .doc
+ doccomment: [
+ [/[^\/*]+/, 'comment.doc'],
+ [/\*\//, 'comment.doc', '@pop'],
+ [/[\/*]/, 'comment.doc']
+ ],
+
+ string: [
+ [/[^\\"]+/, 'string'],
+ [/@escapes/, 'string.escape'],
+ [/\\./, 'string.escape.invalid'],
+ [/"/, 'string', '@pop']
+ ]
+ }
+}
diff --git a/libs/remix-ui/tabs/.babelrc b/libs/remix-ui/tabs/.babelrc
index cf7ddd99c6..adc03892c3 100644
--- a/libs/remix-ui/tabs/.babelrc
+++ b/libs/remix-ui/tabs/.babelrc
@@ -1,3 +1,4 @@
{
- "presets": [["@nrwl/web/babel", { "useBuiltIns": "usage" }]]
+ "presets": [["@nrwl/web/babel", { "useBuiltIns": "usage" }]],
+ "plugins": ["@babel/plugin-proposal-class-properties"]
}
diff --git a/libs/remix-ui/tabs/react-tabs b/libs/remix-ui/tabs/react-tabs
new file mode 160000
index 0000000000..5a1fb0dc4b
--- /dev/null
+++ b/libs/remix-ui/tabs/react-tabs
@@ -0,0 +1 @@
+Subproject commit 5a1fb0dc4b79f811e63e2f029786ff36b68bcbf4
diff --git a/libs/remix-ui/tabs/src/lib/remix-ui-tabs.css b/libs/remix-ui/tabs/src/lib/remix-ui-tabs.css
index ba745eed46..7df5e07993 100644
--- a/libs/remix-ui/tabs/src/lib/remix-ui-tabs.css
+++ b/libs/remix-ui/tabs/src/lib/remix-ui-tabs.css
@@ -1,6 +1,6 @@
.remix-ui-tabs {
display: -webkit-box;
- max-height: 42px
+ max-height: 2.15rem;
}
.remix-ui-tabs li {
display: inline-block;
@@ -28,12 +28,11 @@
}
.close-tabs {
visibility: hidden;
- padding-top: 4px;
font-size: medium;
}
.iconImage {
- width: 16px;
- height: 16px;
+ width: 1rem;
+ height: 1rem;
}
.active {
border: 1px solid transparent;
@@ -44,11 +43,6 @@
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
- max-width: 1000px;
-}
-.left-icon {
- width: 70px;
- height: 49px;
}
/* Hide scrollbar for Chrome, Safari and Opera */
diff --git a/libs/remix-ui/tabs/src/lib/remix-ui-tabs.tsx b/libs/remix-ui/tabs/src/lib/remix-ui-tabs.tsx
index 5875cc24ab..276c691448 100644
--- a/libs/remix-ui/tabs/src/lib/remix-ui-tabs.tsx
+++ b/libs/remix-ui/tabs/src/lib/remix-ui-tabs.tsx
@@ -1,6 +1,5 @@
import React, { useState, useRef, useEffect, useReducer } from 'react' // eslint-disable-line
-import { Tab, Tabs, TabList, TabPanel } from 'react-tabs'
-
+import { Tab, Tabs, TabList, TabPanel } from '../../react-tabs/src/index'
import './remix-ui-tabs.css'
/* eslint-disable-next-line */
@@ -33,12 +32,12 @@ export const TabsUI = (props: TabsUIProps) => {
const renderTab = (tab, index) => {
const classNameImg = 'my-1 mr-1 text-dark ' + tab.iconClass
- const classNameTab = 'nav-item nav-link tab' + (index === currentIndexRef.current ? ' active' : '')
+ const classNameTab = 'nav-item nav-link d-flex justify-content-center align-items-center px-2 py-1 tab' + (index === currentIndexRef.current ? ' active' : '')
return (
-
{ tabsRef.current[index] = el }} className={classNameTab} title={tab.tooltip}>
+
{ props.onSelect(index); currentIndexRef.current = index; setSelectedIndex(index) }} ref={el => { tabsRef.current[index] = el }} className={classNameTab} title={tab.tooltip}>
{tab.icon ? (
) : (
)}
{tab.title}
-
props.onClose(index)}>
+ { props.onClose(index); event.stopPropagation() }}>
@@ -62,16 +61,23 @@ export const TabsUI = (props: TabsUIProps) => {
}, [])
return (
-
-
-
props.onZoomOut()}>
-
props.onZoomIn()}>
-
+
+
+
+ props.onZoomOut()}>
+ props.onZoomIn()}>
+
+
+
+ {props.tabs.map((tab, i) => {renderTab(tab, i)})}
+
+ {props.tabs.map((tab) => )}
+
-
{ props.onSelect(index); currentIndexRef.current = index; setSelectedIndex(index) }} >
- {props.tabs.map((tab, i) => {renderTab(tab, i)})}
- {props.tabs.map((tab) => )}
-
+
)
}
diff --git a/libs/remix-ui/terminal/src/lib/components/Context.tsx b/libs/remix-ui/terminal/src/lib/components/Context.tsx
index a354c4cab4..b51d9385e6 100644
--- a/libs/remix-ui/terminal/src/lib/components/Context.tsx
+++ b/libs/remix-ui/terminal/src/lib/components/Context.tsx
@@ -12,7 +12,7 @@ const Context = ({ opts, blockchain }) => {
const val = data.value
let hash = data.hash ? helper.shortenHexData(data.hash) : ''
const input = data.input ? helper.shortenHexData(data.input) : ''
- const logs = data.logs && data.logs.decoded && data.logs.decoded.length ? data.logs.decoded.length : 0
+ const logs = opts.logs && opts.logs.decoded && opts.logs.decoded.length ? opts.logs.decoded.length : 0
const block = data.receipt ? data.receipt.blockNumber : data.blockNumber || ''
const i = data.receipt ? data.transactionIndex : data.transactionIndex
const value = val ? typeConversion.toInt(val) : 0
diff --git a/libs/remix-ui/terminal/src/lib/components/RenderKnownTransactions.tsx b/libs/remix-ui/terminal/src/lib/components/RenderKnownTransactions.tsx
index 79e1ba4c8a..c8508a676c 100644
--- a/libs/remix-ui/terminal/src/lib/components/RenderKnownTransactions.tsx
+++ b/libs/remix-ui/terminal/src/lib/components/RenderKnownTransactions.tsx
@@ -21,7 +21,7 @@ const RenderKnownTransactions = ({ tx, receipt, resolvedData, logs, index, plugi
const from = tx.from
const to = resolvedData.contractName + '.' + resolvedData.fn
const txType = 'knownTx'
- const options = { from, to, tx }
+ const options = { from, to, tx, logs }
return (
txDetails(event, tx)}>
diff --git a/libs/remix-ui/terminal/src/lib/components/Table.tsx b/libs/remix-ui/terminal/src/lib/components/Table.tsx
index 33e9cabf58..948b9b1e59 100644
--- a/libs/remix-ui/terminal/src/lib/components/Table.tsx
+++ b/libs/remix-ui/terminal/src/lib/components/Table.tsx
@@ -36,125 +36,219 @@ const showTable = (opts, showTableHash) => {
}
const val = opts.val != null ? typeConversion.toInt(opts.val) : 0
return (
-
+
-
- status |
- {`${opts.status} ${msg}`} |
-
- {opts.hash ? (
- transaction hash |
- {opts.hash}
-
- |
-
) : null }
- {
- opts.contractAddress ? (
-
- contract address |
- {opts.contractAddress}
-
- |
-
- ) : null
- }
- {
- opts.from ? (
-
- from |
- {opts.from}
-
- |
-
- ) : null
- }
- {
- opts.to ? (
-
- to |
- {toHash}
-
- |
-
- ) : null
- }
- {
- opts.gas ? (
-
- gas |
- {opts.gas} gas
-
- |
-
- ) : null
- }
- {
- opts.transactionCost ? (
-
- transaction cost |
- {opts.transactionCost} gas {callWarning}
-
- |
-
- ) : null
- }
- {
- opts.executionCost ? (
-
- execution cost |
- {opts.executionCost} gas {callWarning}
-
- |
-
- ) : null
- }
+ {opts.status !== undefined ? (
+
+
+ status
+ |
+ {`${opts.status} ${msg}`} |
+
+ ) : null}
+ {opts.hash && !opts.isCall ? (
+
+
+ transaction hash
+ |
+
+ {opts.hash}
+
+ |
+
+ ) : null}
+ {opts.contractAddress ? (
+
+
+ contract address
+ |
+
+ {opts.contractAddress}
+
+ |
+
+ ) : null}
+ {opts.from ? (
+
+
+ from
+ |
+
+ {opts.from}
+
+ |
+
+ ) : null}
+ {opts.to ? (
+
+
+ to
+ |
+
+ {toHash}
+
+ |
+
+ ) : null}
+ {opts.gas ? (
+
+
+ gas
+ |
+
+ {opts.gas} gas
+
+ |
+
+ ) : null}
+ {opts.transactionCost ? (
+
+
+ transaction cost
+ |
+
+ {opts.transactionCost} gas {callWarning}
+
+ |
+
+ ) : null}
+ {opts.executionCost ? (
+
+
+ execution cost
+ |
+
+ {opts.executionCost} gas {callWarning}
+
+ |
+
+ ) : null}
{opts.hash ? (
-
- hash |
- {opts.hash}
-
+
+
+ hash
+ |
+
+ {opts.hash}
+
|
) : null}
{opts.input ? (
-
- input |
- {helper.shortenHexData(opts.input)}
-
+
+
+ input
+ |
+
+ {helper.shortenHexData(opts.input)}
+
|
) : null}
{opts['decoded input'] ? (
-
- decoded input |
- {opts['decoded input'].trim()}
-
+ |
+
+ decoded input
+ |
+
+ {opts['decoded input'].trim()}
+
|
) : null}
{opts['decoded output'] ? (
-
- decoded output |
- {opts['decoded output']}
-
+ |
+
+ decoded output
+ |
+
+ {opts['decoded output']}
+
|
) : null}
{opts.logs ? (
-
- logs |
-
+ |
+
+ logs
+ |
+
{JSON.stringify(stringified, null, '\t')}
-
-
+
+
|
) : null}
{opts.val ? (
-
- val |
- {val} wei
-
+ |
+
+ val
+ |
+
+ {val} wei
+
|
) : null}
diff --git a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx
index 8b729f07d4..3c13ed625c 100644
--- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx
+++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx
@@ -24,7 +24,7 @@ export interface ClipboardEvent extends SyntheticEvent {
}
export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
- const { call, _deps, on, config, event, gistHandler, logHtmlResponse, logResponse, version } = props.plugin
+ const { call, _deps, on, config, event, gistHandler, version } = props.plugin
const [toggleDownUp, setToggleDownUp] = useState('fa-angle-double-down')
const [_cmdIndex, setCmdIndex] = useState(-1)
const [_cmdTemp, setCmdTemp] = useState('')
@@ -84,12 +84,15 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
}
useEffect(() => {
- scriptRunnerDispatch({ type: 'html', payload: { message: logHtmlResponse } })
- }, [logHtmlResponse])
-
- useEffect(() => {
- scriptRunnerDispatch({ type: 'log', payload: { message: logResponse } })
- }, [logResponse])
+ props.onReady({
+ logHtml: (html) => {
+ scriptRunnerDispatch({ type: 'html', payload: { message: [html.innerText] } })
+ },
+ log: (message) => {
+ scriptRunnerDispatch({ type: 'log', payload: { message: [message] } })
+ }
+ })
+ }, [])
// events
useEffect(() => {
@@ -115,7 +118,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
useEffect(() => {
scrollToBottom()
- }, [newstate.journalBlocks.length, logHtmlResponse.length, toaster])
+ }, [newstate.journalBlocks.length, toaster])
function execute (file, cb) {
function _execute (content, cb) {
diff --git a/libs/remix-ui/terminal/src/lib/types/terminalTypes.ts b/libs/remix-ui/terminal/src/lib/types/terminalTypes.ts
index 66eea4d655..7a77b11dab 100644
--- a/libs/remix-ui/terminal/src/lib/types/terminalTypes.ts
+++ b/libs/remix-ui/terminal/src/lib/types/terminalTypes.ts
@@ -24,5 +24,6 @@ export const LISTEN_ON_NETWORK = 'listenOnNetWork'
export const CMD_HISTORY = 'cmdHistory'
export interface RemixUiTerminalProps {
- plugin: any
+ plugin: any,
+ onReady: (api: any) => void
}
diff --git a/libs/remix-ui/workspace/src/lib/reducers/workspace.ts b/libs/remix-ui/workspace/src/lib/reducers/workspace.ts
index b92d7b041e..152b283fa9 100644
--- a/libs/remix-ui/workspace/src/lib/reducers/workspace.ts
+++ b/libs/remix-ui/workspace/src/lib/reducers/workspace.ts
@@ -504,11 +504,11 @@ export const browserReducer = (state = browserInitialState, action: Action) => {
...state,
browser: {
...state.browser,
- contextMenu: state.mode === 'browser' ? addContextMenuItem(state, payload) : state.browser.contextMenu
+ contextMenu: addContextMenuItem(state, payload)
},
localhost: {
...state.localhost,
- contextMenu: state.mode === 'localhost' ? addContextMenuItem(state, payload) : state.localhost.contextMenu
+ contextMenu: addContextMenuItem(state, payload)
}
}
}
@@ -520,11 +520,11 @@ export const browserReducer = (state = browserInitialState, action: Action) => {
...state,
browser: {
...state.browser,
- contextMenu: state.mode === 'browser' ? removeContextMenuItem(state, payload) : state.browser.contextMenu
+ contextMenu: removeContextMenuItem(state, payload)
},
localhost: {
...state.localhost,
- contextMenu: state.mode === 'localhost' ? removeContextMenuItem(state, payload) : state.localhost.contextMenu
+ contextMenu: removeContextMenuItem(state, payload)
}
}
}
@@ -536,11 +536,11 @@ export const browserReducer = (state = browserInitialState, action: Action) => {
...state,
browser: {
...state.browser,
- expandPath: state.mode === 'browser' ? payload : state.browser.expandPath
+ expandPath: payload
},
localhost: {
...state.localhost,
- expandPath: state.mode === 'localhost' ? payload : state.localhost.expandPath
+ expandPath: payload
}
}
}
diff --git a/package.json b/package.json
index 8faaf4c999..e3fdd751bb 100644
--- a/package.json
+++ b/package.json
@@ -136,6 +136,7 @@
]
},
"dependencies": {
+ "@babel/plugin-proposal-class-properties": "^7.16.0",
"@erebos/bzz-node": "^0.13.0",
"@ethereumjs/block": "^3.5.1",
"@ethereumjs/common": "^2.5.0",
| |