@@ -16,9 +16,9 @@ import {ResponsiveContext} from 'grommet/contexts/ResponsiveContext';
16
16
import emoji from './emoji' ;
17
17
import { fetchTokenInfo , defaultThemeColors } from './lib/codeHighlight' ;
18
18
import { isPromise } from 'relay-runtime' ;
19
- import Config from './config' ;
20
19
import Tippy from '@tippyjs/react' ;
21
20
import { slugify } from './Post' ;
21
+ import ConfigContext from './ConfigContext' ;
22
22
23
23
import type { TokenInfo } from './lib/codeHighlight' ;
24
24
import type { StatelessFunctionalComponent , Node } from 'react' ;
@@ -33,12 +33,10 @@ type Props = {|
33
33
} > ,
34
34
| } ;
35
35
36
- class CodeBlock extends React . PureComponent <
37
- {
38
- value : string ,
39
- language : string ,
40
- theme : string ,
41
- } ,
36
+ type CodeBlockProps = { | value : string , language : string , theme : string | } ;
37
+
38
+ export class CodeBlock extends React . PureComponent <
39
+ CodeBlockProps ,
42
40
{
43
41
tokenInfo : TokenInfo | Promise < TokenInfo > ,
44
42
} ,
@@ -51,18 +49,48 @@ class CodeBlock extends React.PureComponent<
51
49
} ) ,
52
50
} ;
53
51
54
- componentDidMount ( ) {
55
- const { tokenInfo} = this . state ;
52
+ _updateTokenInfo = ( tokenInfo : TokenInfo | Promise < TokenInfo > ) => {
56
53
if ( isPromise ( tokenInfo ) ) {
57
54
tokenInfo
58
- . then ( ( res ) => this . setState ( { tokenInfo : res } ) )
55
+ . then ( ( res ) => {
56
+ this . setState ( ( prevState ) => {
57
+ if ( prevState . tokenInfo === tokenInfo ) {
58
+ return { tokenInfo : res } ;
59
+ } else {
60
+ return prevState ;
61
+ }
62
+ } ) ;
63
+ } )
59
64
. catch ( ( e ) => {
60
65
console . error ( 'Error fetching token info' , e ) ;
61
66
} ) ;
62
67
}
68
+ } ;
69
+
70
+ componentDidMount ( ) {
71
+ this . _updateTokenInfo ( this . state . tokenInfo ) ;
72
+ }
73
+
74
+ componentDidUpdate ( prevProps : CodeBlockProps ) {
75
+ if (
76
+ this . props . value !== prevProps . value ||
77
+ this . props . language !== prevProps . language ||
78
+ this . props . theme !== prevProps . theme
79
+ ) {
80
+ const tokenInfo = fetchTokenInfo ( {
81
+ code : this . props . value ,
82
+ language : this . props . language ,
83
+ theme : this . props . theme ,
84
+ } ) ;
85
+ this . setState ( {
86
+ tokenInfo,
87
+ } ) ;
88
+ this . _updateTokenInfo ( tokenInfo ) ;
89
+ }
63
90
}
91
+
64
92
render ( ) {
65
- const { language, value} = this . props ;
93
+ const { language, value, theme } = this . props ;
66
94
const { tokenInfo} = this . state ;
67
95
68
96
if ( ! isPromise ( tokenInfo ) ) {
@@ -105,10 +133,8 @@ class CodeBlock extends React.PureComponent<
105
133
overflowX : 'auto' ,
106
134
padding : '1em' ,
107
135
borderRadius : 4 ,
108
- color :
109
- defaultThemeColors [ Config . codeTheme ] ?. foregroundColor || '#fff' ,
110
- background :
111
- defaultThemeColors [ Config . codeTheme ] ?. backgroundColor || '#000' ,
136
+ color : defaultThemeColors [ theme ] ?. foregroundColor || '#fff' ,
137
+ background : defaultThemeColors [ theme ] ?. backgroundColor || '#000' ,
112
138
} } >
113
139
< code className = { `language-${ language } ` } > { value } </ code >
114
140
</ pre >
@@ -257,6 +283,18 @@ function Link(props) {
257
283
return < Anchor { ...props } /> ;
258
284
}
259
285
286
+ function Code ( props ) {
287
+ const { config} = React . useContext ( ConfigContext ) ;
288
+ if ( props . language === 'backmatter' ) {
289
+ return null ;
290
+ }
291
+ return (
292
+ < Box margin = { { vertical : 'small' } } >
293
+ < CodeBlock theme = { config . codeTheme } { ...props } />
294
+ </ Box >
295
+ ) ;
296
+ }
297
+
260
298
function flatten ( text , child ) {
261
299
return typeof child === 'string'
262
300
? text + child
@@ -305,16 +343,7 @@ const defaultRenderers = ({
305
343
</ code >
306
344
) ;
307
345
} ,
308
- code ( props ) {
309
- if ( props . language === 'backmatter' ) {
310
- return null ;
311
- }
312
- return (
313
- < Box margin = { { vertical : 'small' } } >
314
- < CodeBlock theme = { Config . codeTheme } { ...props } />
315
- </ Box >
316
- ) ;
317
- } ,
346
+ code : Code ,
318
347
image : Image ,
319
348
paragraph : ParagraphWrapper ,
320
349
heading ( props ) {
0 commit comments