Add monaco editor

This commit is contained in:
Anthony Laibe 2018-09-24 15:16:06 +01:00 committed by Pascal Precht
parent 23bd9ce004
commit 0e49165967
No known key found for this signature in database
GPG Key ID: 0EE28D8D6FD85D7D
7 changed files with 100 additions and 73 deletions

View File

@ -4,6 +4,23 @@
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
"@types/prop-types": {
"version": "15.5.5",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.5.5.tgz",
"integrity": "sha512-mOrlCEdwX3seT3n0AXNt4KNPAZZxcsABUHwBgFXOt+nvFUXkxCAO6UBJHPrDxWEa2KDMil86355fjo8jbZ+K0Q==",
"requires": {
"@types/react": "*"
}
},
"@types/react": {
"version": "16.4.14",
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.4.14.tgz",
"integrity": "sha512-Gh8irag2dbZ2K6vPn+S8+LNrULuG3zlCgJjVUrvuiUK7waw9d9CFk2A/tZFyGhcMDUyO7tznbx1ZasqlAGjHxA==",
"requires": {
"@types/prop-types": "*",
"csstype": "^2.2.0"
}
},
"abab": { "abab": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz", "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz",
@ -18,11 +35,6 @@
"negotiator": "0.6.1" "negotiator": "0.6.1"
} }
}, },
"ace-mode-solidity": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/ace-mode-solidity/-/ace-mode-solidity-0.1.0.tgz",
"integrity": "sha512-vLhygG5B0ImeDd/+L3vAB3aD3wQ5OE/+AYUD6dyOmvBc2G40K5mO/Lp7li+d04xpzO1LP82bQKN1N/I35K/wgg=="
},
"acorn": { "acorn": {
"version": "5.7.1", "version": "5.7.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz", "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz",
@ -1468,11 +1480,6 @@
} }
} }
}, },
"brace": {
"version": "0.11.1",
"resolved": "https://registry.npmjs.org/brace/-/brace-0.11.1.tgz",
"integrity": "sha1-SJb8ydVE7vRfS7dmDbMg07N5/lg="
},
"brace-expansion": { "brace-expansion": {
"version": "1.1.11", "version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@ -2565,6 +2572,11 @@
"cssom": "0.3.x" "cssom": "0.3.x"
} }
}, },
"csstype": {
"version": "2.5.7",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.5.7.tgz",
"integrity": "sha512-Nt5VDyOTIIV4/nRFswoCKps1R5CD1hkiyjBE9/thNaNZILLEviVw9yWQw15+O+CpNjQKB/uvdcxFFOrSflY3Yw=="
},
"currently-unhandled": { "currently-unhandled": {
"version": "0.4.1", "version": "0.4.1",
"resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
@ -2763,11 +2775,6 @@
"resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
"integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA=="
}, },
"diff-match-patch": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.1.tgz",
"integrity": "sha512-A0QEhr4PxGUMEtKxd6X+JLnOTFd3BfIPSDpsc4dMvj+CbSaErDwTpoTo/nFJDMSrjxLW4BiNq+FbNisAAHhWeQ=="
},
"diffie-hellman": { "diffie-hellman": {
"version": "5.0.3", "version": "5.0.3",
"resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
@ -6632,11 +6639,6 @@
"resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
"integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw="
}, },
"lodash.get": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
"integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk="
},
"lodash.isarguments": { "lodash.isarguments": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
@ -6647,11 +6649,6 @@
"resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz",
"integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=" "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U="
}, },
"lodash.isequal": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
"integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
},
"lodash.keys": { "lodash.keys": {
"version": "3.1.2", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz",
@ -6958,6 +6955,11 @@
"minimist": "0.0.8" "minimist": "0.0.8"
} }
}, },
"monaco-editor": {
"version": "0.14.3",
"resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.14.3.tgz",
"integrity": "sha512-RhaO4xXmWn/p0WrkEOXe4PoZj6xOcvDYjoAh0e1kGUrQnP1IOpc0m86Ceuaa2CLEMDINqKijBSmqhvBQnsPLHQ=="
},
"ms": { "ms": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
@ -9010,18 +9012,6 @@
"prop-types": "^15.6.0" "prop-types": "^15.6.0"
} }
}, },
"react-ace": {
"version": "6.1.4",
"resolved": "https://registry.npmjs.org/react-ace/-/react-ace-6.1.4.tgz",
"integrity": "sha512-a8/lAsy2bfi7Ho+3Kaj8hBPR+PEiCTG9xFG9LIjCJrv5WQFYFpeFTiPWA96M3t+LgIDFFltwfVTwD2pmdAVOxQ==",
"requires": {
"brace": "^0.11.0",
"diff-match-patch": "^1.0.0",
"lodash.get": "^4.4.2",
"lodash.isequal": "^4.1.1",
"prop-types": "^15.5.8"
}
},
"react-copy-to-clipboard": { "react-copy-to-clipboard": {
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-5.0.1.tgz", "resolved": "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-5.0.1.tgz",
@ -9077,6 +9067,16 @@
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
}, },
"react-monaco-editor": {
"version": "0.18.0",
"resolved": "https://registry.npmjs.org/react-monaco-editor/-/react-monaco-editor-0.18.0.tgz",
"integrity": "sha512-azMSMDF3eS9XFd9RWfujDInYvSQtdipozmEXSJRuJqsq3JmJlToOjMRSNEkTPmxnR6ZcI9DVhMImCLGNgUk5bQ==",
"requires": {
"@types/react": "*",
"monaco-editor": "^0.14.2",
"prop-types": "^15.6.2"
}
},
"react-popper": { "react-popper": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.0.0.tgz", "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.0.0.tgz",

View File

@ -3,7 +3,6 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"dependencies": { "dependencies": {
"ace-mode-solidity": "^0.1.0",
"ansi-to-html": "^0.6.6", "ansi-to-html": "^0.6.6",
"autoscroll-react": "^3.2.0", "autoscroll-react": "^3.2.0",
"axios": "^0.18.0", "axios": "^0.18.0",
@ -14,9 +13,9 @@
"prop-types": "^15.6.2", "prop-types": "^15.6.2",
"qs": "^6.5.2", "qs": "^6.5.2",
"react": "^16.4.2", "react": "^16.4.2",
"react-ace": "^6.1.4",
"react-copy-to-clipboard": "^5.0.1", "react-copy-to-clipboard": "^5.0.1",
"react-dom": "^16.4.1", "react-dom": "^16.4.1",
"react-monaco-editor": "^0.18.0",
"react-redux": "^5.0.7", "react-redux": "^5.0.7",
"react-router-dom": "^4.3.1", "react-router-dom": "^4.3.1",
"react-scripts": "1.1.4", "react-scripts": "1.1.4",

View File

@ -37,5 +37,19 @@
To begin the development, run `npm start` or `yarn start`. To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`. To create a production bundle, use `npm run build` or `yarn build`.
--> -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.14.3/min/vs/loader.js"></script>
<script>
require.config({
paths: {
'vs': 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.14.3/min/vs'
}
});
window.MonacoEnvironment = {
getWorkerUrl: function (workerId, label) {
return '/monaco-editor-worker-loader-proxy.js';
}
};
require(["vs/editor/editor.main"], function () {})
</script>
</body> </body>
</html> </html>

View File

@ -0,0 +1,5 @@
self.MonacoEnvironment = {
baseUrl: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.14.3/min/'
};
importScripts('https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.14.3/min/vs/base/worker/workerMain.js') // eslint-disable-line

View File

@ -1,52 +1,61 @@
import React from 'react'; import React from 'react';
import AceEditor from 'react-ace'; import MonacoEditor from 'react-monaco-editor';
import 'brace/mode/javascript';
import 'brace/theme/tomorrow_night_blue';
import 'ace-mode-solidity/build/remix-ide/mode-solidity';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
class TextEditor extends React.Component { class TextEditor extends React.Component {
language() {
switch(this.props.file.name.split('.').pop()) {
case 'css':
return 'css';
case 'sol':
return 'sol';
case 'html':
return 'html';
case 'json':
return 'json';
default:
return 'javascript';
}
}
extractRowCol(errorMessage) { extractRowCol(errorMessage) {
const errorSplit = errorMessage.split(':'); const errorSplit = errorMessage.split(':');
if (errorSplit.length >= 3) { if (errorSplit.length >= 3) {
return {row: errorSplit[1], col: errorSplit[2]}; return {row: parseInt(errorSplit[1], 10), col: parseInt(errorSplit[2], 10)};
} }
return {row: 0, col: 0}; return {row: 0, col: 0};
} }
annotations() { componentDidUpdate() {
const {errors, warnings} = this.props.contractCompile; const {errors, warnings} = this.props.contractCompile;
return [].concat(errors).concat(warnings).filter((e) => e).map((e) => { const markers = [].concat(errors).concat(warnings).filter((e) => e).map((e) => {
const rowCol = this.extractRowCol(e.formattedMessage); const {row, col} = this.extractRowCol(e.formattedMessage);
return Object.assign({}, { return {
row: rowCol.row - 1, startLineNumber: row,
column: rowCol.col - 1, startColumn: col,
text: e.formattedMessage, endLineNumber: row,
type: e.severity endColumn: col + 1,
}); message: e.formattedMessage,
severity: e.severity
};
}); });
this.state.monaco.editor.setModelMarkers(this.state.editor.getModel(), 'test', markers);
}
editorDidMount(editor, monaco) {
this.setState({editor, monaco});
} }
render() { render() {
return ( return (
<AceEditor <MonacoEditor
mode="solidity" width="800"
theme="tomorrow_night_blue" height="600"
name="fiddle" language={this.language()}
height="60em" theme="vs-dark"
width="100%" value={this.props.file.content}
onChange={this.props.onFileContentChange} onChange={this.props.onFileContentChange}
value={this.props.value} editorDidMount={(editor, monaco) => this.editorDidMount(editor, monaco)}
showGutter={true}
annotations={this.annotations()}
setOptions={{
useWorker: false
}}
editorProps={{
$blockScrolling: Infinity,
enableLiveAutocompletion:true,
highlightSelectedWord: true
}}
/> />
); );
} }
@ -54,7 +63,7 @@ class TextEditor extends React.Component {
TextEditor.propTypes = { TextEditor.propTypes = {
onFileContentChange: PropTypes.func, onFileContentChange: PropTypes.func,
value: PropTypes.string, file: PropTypes.object,
contractCompile: PropTypes.object contractCompile: PropTypes.object
}; };

View File

@ -18,7 +18,7 @@ class ContractSourceContainer extends Component {
return ( return (
<Page.Content title={`${this.props.contract.className} Source`}> <Page.Content title={`${this.props.contract.className} Source`}>
<DataWrapper shouldRender={this.props.file !== undefined } {...this.props} render={({file}) => ( <DataWrapper shouldRender={this.props.file !== undefined } {...this.props} render={({file}) => (
<TextEditor value={file.content} contractCompile={{}} /> <TextEditor file={file} contractCompile={{}} />
)} /> )} />
</Page.Content> </Page.Content>
); );

View File

@ -107,7 +107,7 @@ class TextEditorContainer extends Component {
<Grid.Row className="my-2"> <Grid.Row className="my-2">
{this.renderToolbar()} {this.renderToolbar()}
</Grid.Row> </Grid.Row>
<TextEditor value={this.state.currentFile.content} <TextEditor file={this.state.currentFile}
contractCompile={this.props.contractCompile} contractCompile={this.props.contractCompile}
onFileContentChange={(newContent) => this.onFileContentChange(newContent)} /> onFileContentChange={(newContent) => this.onFileContentChange(newContent)} />
{this.renderContractFooter()} {this.renderContractFooter()}