diff options
author | August Skare <post@augustskare.no> | 2018-10-25 19:19:56 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-25 19:19:56 +0800 |
commit | 43e55a963bef2a2e4740ce27d456927b020b71f2 (patch) | |
tree | 742e684d5f3275e2bcbf5288c8718def845582cd /packages | |
parent | 9cf055c1596d8abce854fea8f4e209573d6df7c8 (diff) | |
download | dexon-sol-tools-43e55a963bef2a2e4740ce27d456927b020b71f2.tar dexon-sol-tools-43e55a963bef2a2e4740ce27d456927b020b71f2.tar.gz dexon-sol-tools-43e55a963bef2a2e4740ce27d456927b020b71f2.tar.bz2 dexon-sol-tools-43e55a963bef2a2e4740ce27d456927b020b71f2.tar.lz dexon-sol-tools-43e55a963bef2a2e4740ce27d456927b020b71f2.tar.xz dexon-sol-tools-43e55a963bef2a2e4740ce27d456927b020b71f2.tar.zst dexon-sol-tools-43e55a963bef2a2e4740ce27d456927b020b71f2.zip |
Feature/syntaxhighlighting (#9)
* wip code highlighting of lines
* Implements gutter component
* WIP: Profiler with gutter
* cleaned up highlight code
* Removes before content for gutter styling
* Styles gutter
* Add correct Profiler code content
* Adds color variable for gutter gray
* refactor code component width gutter and diffing
Diffstat (limited to 'packages')
-rw-r--r-- | packages/dev-tools-pages/package.json | 1 | ||||
-rw-r--r-- | packages/dev-tools-pages/ts/components/Code.tsx | 106 | ||||
-rw-r--r-- | packages/dev-tools-pages/ts/components/Intro.tsx | 1 | ||||
-rw-r--r-- | packages/dev-tools-pages/ts/highlight.tsx | 47 | ||||
-rw-r--r-- | packages/dev-tools-pages/ts/pages/Cov.tsx | 30 | ||||
-rw-r--r-- | packages/dev-tools-pages/ts/pages/Profiler.tsx | 25 | ||||
-rw-r--r-- | packages/dev-tools-pages/ts/variables.tsx | 1 |
7 files changed, 159 insertions, 52 deletions
diff --git a/packages/dev-tools-pages/package.json b/packages/dev-tools-pages/package.json index c85ff44a6..eb34e3715 100644 --- a/packages/dev-tools-pages/package.json +++ b/packages/dev-tools-pages/package.json @@ -18,7 +18,6 @@ "dependencies": { "@0xproject/react-shared": "^1.0.15", "highlight.js": "^9.13.1", - "highlighter": "^0.1.0", "less": "^2.7.2", "polished": "^1.9.2", "react": "^16.5.2", diff --git a/packages/dev-tools-pages/ts/components/Code.tsx b/packages/dev-tools-pages/ts/components/Code.tsx index 5a03e79ac..ce4443357 100644 --- a/packages/dev-tools-pages/ts/components/Code.tsx +++ b/packages/dev-tools-pages/ts/components/Code.tsx @@ -4,12 +4,13 @@ import styled from 'styled-components'; import { colors } from 'ts/variables'; import BaseButton from './Button'; -var highlight = require('highlighter')(); - interface CodeProps { children: React.ReactNode; language?: string; light?: boolean; + diff?: boolean; + gutter?: Array<number>; + gutterLength?: number; } interface CodeState { @@ -30,37 +31,73 @@ const Button = styled(BaseButton)` const Base = styled.div < - CodeProps > - ` + CodeProps > + ` color: ${props => (props.language === undefined ? colors.white : 'inherit')}; background-color: ${props => - props.light ? 'rgba(255,255,255,.15)' : props.language === undefined ? colors.black : colors.lightGray}; + props.light ? 'rgba(255,255,255,.15)' : props.language === undefined ? colors.black : '#F1F4F5'}; white-space: ${props => (props.language === undefined ? 'nowrap' : '')}; position: relative; + + ${props => + props.diff + ? ` + background-color: #E9ECED; + display: flex; + padding-top: 1.5rem; + padding-bottom: 1.5rem; + ` + : ` + padding: 1.5rem; + `} + + overflow-y: scroll; + -webkit-overflow-scrolling: touch; + &:hover ${Button} { opacity: 1; } `; -const StyledCode = styled.code` - padding-top: 1.5rem; - padding-bottom: 1.5rem; - display: block; - overflow-y: scroll; - -webkit-overflow-scrolling: touch; +const StyledCodeDiff = + styled.code < + any > + ` + ::before { + content: ''; + width: calc(.75rem + ${props => props.gutterLength}ch); + background-color: #e2e5e6; + position: absolute; + top: 0; + left: 0; + bottom: 0; + } - - .diff-addition { - background-color: #d2e9e0; - padding: 0.3125rem; + [class^='line-'] { display: inline-block; width: 100%; + position: relative; + padding-right: 1.5rem; + padding-left: calc(2.25rem + ${props => props.gutterLength}ch); + ::before { + content: attr(data-test); + font-size: 0.875rem; + width: ${props => props.gutterLength}; + padding-left: .375rem; + padding-right: .375rem; + position: absolute; + top: 50%; + left: 0; + transform: translateY(-50%); + z-index: 1; + } } - .diff-deletion { - background-color: #ebdcdc; - padding: 0.3125rem; - display: inline-block; - width: 100%; + + .line-addition { + background-color: rgba(0, 202, 105, 0.1); + } + .line-deletion { + background-color: rgba(255, 0, 0, 0.07); } `; @@ -88,13 +125,16 @@ class Code extends React.Component<CodeProps, CodeState> { } async componentDidMount() { - const { language, children } = this.props; + const { language, children, diff, gutter } = this.props; + + const code = children as string; if (language !== undefined) { - const { default: hljs } = await System.import(/* webpackChunkName: 'highlightjs' */ 'ts/highlight'); + const { default: highlight } = await System.import(/* webpackChunkName: 'highlightjs' */ 'ts/highlight'); - const hlCode = hljs(children as string, language); - this.setState({ hlCode }); + this.setState({ + hlCode: highlight(language, code, diff, gutter), + }); } } @@ -115,16 +155,20 @@ class Code extends React.Component<CodeProps, CodeState> { }; render() { - const { language, light, children } = this.props; + const { language, light, diff, children, gutterLength } = this.props; + const { hlCode } = this.state; + + const Code = diff ? StyledCodeDiff : 'code'; return ( - <Base language={language} light={light}> + <Base language={language} diff={diff} light={light}> <StyledPre> - {this.state.hlCode !== undefined ? ( - <StyledCode dangerouslySetInnerHTML={{ __html: this.state.hlCode }} /> - ) : ( - <StyledCode>{this.props.children}</StyledCode> - )} + <Code + gutterLength={gutterLength} + dangerouslySetInnerHTML={hlCode ? { __html: this.state.hlCode } : null} + > + {hlCode === undefined ? children : null} + </Code> </StyledPre> {navigator.userAgent !== 'ReactSnap' ? <Button onClick={this.handleCopy}>Copy</Button> : null} {!('clipboard' in navigator) ? ( diff --git a/packages/dev-tools-pages/ts/components/Intro.tsx b/packages/dev-tools-pages/ts/components/Intro.tsx index 4fc1289fb..e5c95d4c2 100644 --- a/packages/dev-tools-pages/ts/components/Intro.tsx +++ b/packages/dev-tools-pages/ts/components/Intro.tsx @@ -43,6 +43,7 @@ const IntroLead = styled(Lead)` `; const IntroAside = styled.div` max-width: 32.5rem; + position: relative; ${media.small` margin-left: -30px; diff --git a/packages/dev-tools-pages/ts/highlight.tsx b/packages/dev-tools-pages/ts/highlight.tsx index 9d7844c89..7187118d0 100644 --- a/packages/dev-tools-pages/ts/highlight.tsx +++ b/packages/dev-tools-pages/ts/highlight.tsx @@ -1,8 +1,47 @@ -const highlight = require('highlight.js/lib/highlight'); +const hljs = require('highlight.js/lib/highlight'); const javascript = require('highlight.js/lib/languages/javascript'); -const json = require('highlight.js/lib/languages/json'); -highlight.registerLanguage('javascript', javascript); -highlight.registerLanguage('json', json); +hljs.registerLanguage('javascript', javascript); + +interface PatchInterface { + [key: string]: string; +} + +var PATCH_TYPES: PatchInterface = { + '+': 'addition', + '-': 'deletion', + '!': 'change', +}; + +function diffHighlight(language: string, code: any, gutter: any) { + return code + .split(/\r?\n/g) + .map((line: string, index: number) => { + var type; + if (/^-{3} [^-]+ -{4}$|^\*{3} [^*]+ \*{4}$|^@@ [^@]+ @@$/.test(line)) { + type = 'chunk'; + } else if (/^Index: |^[+\-*]{3}|^[*=]{5,}$/.test(line)) { + type = 'header'; + } else { + type = PATCH_TYPES[line[0] as string] || 'null'; + line = line.replace(/^[+\-! ]/, ''); + } + + const g = gutter[index]; + + return `<span data-test="${g !== undefined ? g + 'x' : ''}" class="line-${type}">${ + hljs.highlight(language, line).value + }</span>`; + }) + .join('\n'); +} + +function highlight(language: string, code: string, diff: boolean, gutter: any) { + if (diff) { + return diffHighlight(language, code, gutter); + } + + return hljs.highlight(language, code).value; +} export default highlight; diff --git a/packages/dev-tools-pages/ts/pages/Cov.tsx b/packages/dev-tools-pages/ts/pages/Cov.tsx index 01966537c..197ff174d 100644 --- a/packages/dev-tools-pages/ts/pages/Cov.tsx +++ b/packages/dev-tools-pages/ts/pages/Cov.tsx @@ -22,19 +22,25 @@ function Cov() { coverage. </IntroLead> <IntroAside> - <Code language="js.diff"> + <Code + language="javascript" + diff + gutterLength={2} + gutter={[4, undefined, 4, 4, 4, undefined, 4, 2, 2, 2]} + > {`+function executeTransaction(uint transactionId) - public -+notExecuted(transactionId) -+pastTimeLock(transactionId) + public ++ notExecuted(transactionId) ++ fullyConfirmed(transactionId) ++ pastTimeLock(transactionId) { -+Transaction storage tx = transactions[transactionId] -+tx.executed = true -+if (tx.destination.call.value(tx.value)(tx.data)) -+Execution(transactionId) -else { --ExecutionFailure(transactionId) - ++ Transaction storage tx = transactions[transactionId] ++ tx.executed = true ++ if (tx.destination.call.value(tx.value)(tx.data)) ++ Execution(transactionId) + else { +- ExecutionFailure(transactionId) +- tx.executed = false } }`} </Code> @@ -69,7 +75,7 @@ else { <Tabs> <TabBlock title="Sol-compiler"> - <Code language="js"> + <Code language="javascript"> {`import { SolCompilerArtifactAdapter } from '@0x/sol-trace'; // Both artifactsDir and contractsDir are optional and will be fetched from compiler.json if not passed in diff --git a/packages/dev-tools-pages/ts/pages/Profiler.tsx b/packages/dev-tools-pages/ts/pages/Profiler.tsx index ac88bd933..462789a16 100644 --- a/packages/dev-tools-pages/ts/pages/Profiler.tsx +++ b/packages/dev-tools-pages/ts/pages/Profiler.tsx @@ -9,18 +9,35 @@ import { Tabs, TabBlock } from 'ts/components/Tabs'; import Code from 'ts/components/Code'; import InlineCode from 'ts/components/InlineCode'; import { List, ListItem } from 'ts/components/List'; -import Intro from 'ts/components/Intro'; import Breakout from 'ts/components/Breakout'; +import { Intro, IntroLead, IntroAside } from 'ts/components/Intro'; function Profiler() { return ( <Base context={context}> - <Intro title="ra"> - <p> + <Intro title="Headline"> + <IntroLead> Sol-profiler gathers line-by-line gas usage for any transaction submitted through your provider. This will help you find unexpected inefficiencies in parts of your smart contract, and take a data-driven approach to optimizing it. - </p> + </IntroLead> + <IntroAside> + <Code language="javascript" diff gutterLength={6} gutter={[15, 15, undefined, 21747, 20303, 1435]}> + {`+function() public payable { ++ deposit(); +} ++function deposit() public payabble { ++ balanceOf[msg.sender] += msg.value; ++ Deposit(msg.sender, msg.value); +} +-function withdraw(uint wad) public { +- require(balanceOf[msg.sender] >= wad); +- balanceOf[msg.sender] -= wad; +- msg.sender.transfer(wad); +- Withdrawal(msg.sender, wad); +}`} + </Code> + </IntroAside> </Intro> <Content> <ContentBlock main title="Get started" /> diff --git a/packages/dev-tools-pages/ts/variables.tsx b/packages/dev-tools-pages/ts/variables.tsx index 8f08d13eb..76a675546 100644 --- a/packages/dev-tools-pages/ts/variables.tsx +++ b/packages/dev-tools-pages/ts/variables.tsx @@ -6,6 +6,7 @@ const colors = { lightGray: '#F1F4F5', gray: '#F1F2F7', darkGray: '#E9ECED', + darkestGray: '#E2E5E6', blueGray: '#ECEFF9', }; |