Skip to content

Commit dac7ad2

Browse files
author
Jakub Rożek
authored
fix: restore older impl of CodeViewer (#168)
* fix: restore older impl of CodeViewer * chore: move directories * chore: langs * fix: types and stuff * fix: add refractor dep * revert: directory structure * test: refractor is typed now
1 parent c6df86f commit dac7ad2

17 files changed

Lines changed: 1128 additions & 36 deletions

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
"react-tabs": "^3.1.0",
5656
"react-virtualized-auto-sizer": "^1.0.2",
5757
"react-window": "~1.8.5",
58+
"refractor": "^3.0.0",
5859
"yup": "^0.28.0"
5960
},
6061
"devDependencies": {
@@ -86,6 +87,7 @@
8687
"@types/react-tabs": "^2.3.1",
8788
"@types/react-virtualized-auto-sizer": "^1.0.0",
8889
"@types/react-window": "^1.8.1",
90+
"@types/refractor": "^2.8.0",
8991
"@types/yup": "~0.26.27",
9092
"autoprefixer": "^9.7.3",
9193
"babel-loader": "^8.0.6",
Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,77 @@
1-
import { mount } from 'enzyme';
1+
import { shallow } from 'enzyme';
22
import 'jest-enzyme';
33
import * as React from 'react';
4-
import { CodeViewer } from '..';
4+
import { CodeViewer } from '../index';
5+
import { astToReact } from '../utils/astToReact';
6+
import { parseCode } from '../utils/parseCode';
7+
8+
jest.mock('../utils/astToReact');
9+
jest.mock('../utils/parseCode');
510

611
describe('Code Viewer component', () => {
12+
afterEach(() => {
13+
(parseCode as jest.Mock).mockReset();
14+
(astToReact as jest.Mock).mockReset();
15+
});
16+
717
it('renders code element with raw value for inline view', () => {
818
const code = '{}';
919
const language = 'json';
1020

11-
const wrapper = mount(<CodeViewer language={language} value={code} inline />);
12-
expect(wrapper).toHaveHTML(
13-
`<code class="bp3-code-editor isInline"><span class="token punctuation">{</span><span class="token punctuation">}</span></code>`,
14-
);
21+
const wrapper = shallow(<CodeViewer language={language} value={code} inline />);
22+
expect(wrapper).toHaveText(code);
23+
expect(wrapper).toHaveDisplayName('code');
24+
25+
expect(parseCode).not.toHaveBeenCalled();
1526
});
1627

1728
it('renders pre element for block view', () => {
1829
const code = '{}';
1930
const language = 'json';
2031

21-
const wrapper = mount(<CodeViewer language={language} value={code} />);
22-
expect(wrapper).toHaveHTML(
23-
`<pre class="bp3-code-editor language-json"><span class="token punctuation">{</span><span class="token punctuation">}</span></pre>`,
24-
);
32+
const wrapper = shallow(<CodeViewer language={language} value={code} />);
33+
expect(wrapper).toHaveDisplayName('pre');
34+
});
35+
36+
it('renders code as is if parsing fails', () => {
37+
const code = '{}';
38+
const language = 'json';
39+
(parseCode as jest.Mock).mockReturnValue(null);
40+
41+
const wrapper = shallow(<CodeViewer language={language} value={code} />);
42+
expect(wrapper).toHaveText(code);
43+
44+
expect(parseCode).toHaveBeenCalledWith(code, language, false);
45+
});
46+
47+
it('does not try to map ast nodes to react nodes if parsing failed', () => {
48+
(parseCode as jest.Mock).mockReturnValue(null);
49+
shallow(<CodeViewer language="javascript" value="foo()" />);
50+
51+
expect(astToReact).not.toHaveBeenCalled();
2552
});
2653

2754
it('renders parsed markup if possible', () => {
2855
const code = 'function';
2956
const language = 'javascript';
30-
const html = `<pre class="bp3-code-editor language-javascript"><span class="token keyword">function</span></pre>`;
57+
const ast = [
58+
{
59+
type: 'element',
60+
tagName: 'span',
61+
properties: {
62+
className: ['token', 'function'],
63+
},
64+
value: 'function',
65+
},
66+
];
67+
const markup = <span className="token function">function</span>;
68+
69+
(parseCode as jest.Mock).mockReturnValue(ast);
70+
(astToReact as jest.Mock).mockReturnValue(() => markup);
3171

32-
const wrapper = mount(<CodeViewer language={language} value={code} />);
33-
expect(wrapper).toHaveHTML(html);
72+
const wrapper = shallow(<CodeViewer language={language} value={code} />);
73+
expect(wrapper).toContainReact(markup);
74+
expect(parseCode).toHaveBeenCalledWith(code, language, false);
75+
expect(astToReact).toHaveBeenCalled();
3476
});
3577
});

src/CodeViewer/index.tsx

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import * as cn from 'classnames';
2-
import 'prismjs';
32
import * as React from 'react';
43

54
import { Classes } from '../classes';
6-
import { highlightCode } from '../CodeEditor/utils/highlightCode';
5+
import { astToReact } from './utils/astToReact';
6+
import { parseCode } from './utils/parseCode';
77

88
const languageMaps: { [from: string]: string } = {
99
md: 'markdown',
@@ -12,7 +12,7 @@ const languageMaps: { [from: string]: string } = {
1212
/**
1313
* CODE VIEWER
1414
*/
15-
interface ICodeViewerProps extends React.HTMLAttributes<HTMLDivElement> {
15+
interface ICodeViewerProps extends React.HTMLAttributes<HTMLPreElement> {
1616
value: string;
1717
language?: string;
1818
showLineNumbers?: boolean;
@@ -27,32 +27,34 @@ const CodeViewer: React.FunctionComponent<ICodeViewerProps> = ({
2727
className,
2828
...rest
2929
}) => {
30-
const lang = (language && languageMaps[language]) || language || '';
31-
32-
const code = React.useMemo(() => highlightCode(value, lang, showLineNumbers), [value, lang, showLineNumbers]);
30+
const lang = (language && languageMaps[language]) || language;
3331

3432
if (inline) {
3533
return (
3634
<code
3735
className={cn(Classes.CODE_EDITOR, className, {
3836
isInline: inline,
39-
'line-numbers': showLineNumbers,
37+
showLineNumbers,
4038
})}
4139
{...rest}
42-
dangerouslySetInnerHTML={{ __html: code }}
43-
/>
40+
>
41+
{value}
42+
</code>
4443
);
4544
}
4645

46+
const markup = parseCode(value, lang, showLineNumbers);
47+
4748
return (
4849
<pre
4950
className={cn(Classes.CODE_EDITOR, className, `language-${lang || 'unknown'}`, {
5051
isInline: inline,
51-
'line-numbers': showLineNumbers,
52+
showLineNumbers,
5253
})}
53-
{...(rest as React.HTMLAttributes<HTMLPreElement>)}
54-
dangerouslySetInnerHTML={{ __html: code }}
55-
/>
54+
{...rest}
55+
>
56+
{markup ? markup.map(astToReact()) : value}
57+
</pre>
5658
);
5759
};
5860

src/CodeViewer/types.ts

Lines changed: 0 additions & 10 deletions
This file was deleted.
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`astToReact util fixture clike 1`] = `
4+
<pre>
5+
int
6+
<span
7+
className="token function"
8+
key="cv-0-1"
9+
>
10+
main
11+
</span>
12+
<span
13+
className="token punctuation"
14+
key="cv-0-2"
15+
>
16+
(
17+
</span>
18+
<span
19+
className="token punctuation"
20+
key="cv-0-3"
21+
>
22+
)
23+
</span>
24+
25+
<span
26+
className="token punctuation"
27+
key="cv-0-5"
28+
>
29+
{
30+
</span>
31+
32+
33+
<span
34+
className="token comment"
35+
key="cv-0-7"
36+
>
37+
// some dumb code
38+
</span>
39+
40+
41+
<span
42+
className="token keyword"
43+
key="cv-0-9"
44+
>
45+
return
46+
</span>
47+
48+
<span
49+
className="token number"
50+
key="cv-0-11"
51+
>
52+
0
53+
</span>
54+
<span
55+
className="token punctuation"
56+
key="cv-0-12"
57+
>
58+
;
59+
</span>
60+
61+
62+
<span
63+
className="token punctuation"
64+
key="cv-0-14"
65+
>
66+
}
67+
</span>
68+
</pre>
69+
`;
70+
71+
exports[`astToReact util fixture javascript 1`] = `
72+
<pre>
73+
<span
74+
className="token keyword"
75+
key="cv-0-0"
76+
>
77+
const
78+
</span>
79+
defaultValue
80+
<span
81+
className="token operator"
82+
key="cv-0-2"
83+
>
84+
=
85+
</span>
86+
stoplight
87+
<span
88+
className="token punctuation"
89+
key="cv-0-4"
90+
>
91+
.
92+
</span>
93+
<span
94+
className="token function"
95+
key="cv-0-5"
96+
>
97+
io
98+
</span>
99+
<span
100+
className="token punctuation"
101+
key="cv-0-6"
102+
>
103+
(
104+
</span>
105+
<span
106+
className="token punctuation"
107+
key="cv-0-7"
108+
>
109+
)
110+
</span>
111+
<span
112+
className="token punctuation"
113+
key="cv-0-8"
114+
>
115+
;
116+
</span>
117+
</pre>
118+
`;

0 commit comments

Comments
 (0)