1
- import React , { useCallback , useLayoutEffect , useRef } from 'react'
1
+ import React , { useCallback , useInsertionEffect , useRef } from 'react'
2
2
import type { FC } from 'react'
3
3
4
4
import { useIsPrintMode } from '~/atoms/css-media'
5
5
import { useIsDark } from '~/hooks/common/use-is-dark'
6
+ import { loadScript , loadStyleSheet } from '~/lib/load-script'
6
7
import { toast } from '~/lib/toast'
7
8
8
9
import styles from './CodeHighlighter.module.css'
9
- import { renderCodeHighlighter } from './render.server'
10
10
11
11
declare global {
12
12
interface Window {
@@ -24,25 +24,70 @@ export const HighLighter: FC<Props> = (props) => {
24
24
25
25
const handleCopy = useCallback ( ( ) => {
26
26
navigator . clipboard . writeText ( value )
27
- toast . success ( 'COPIED!' )
27
+ toast ( 'COPIED!' , 'success ')
28
28
} , [ value ] )
29
29
30
+ const prevThemeCSS = useRef < ReturnType < typeof loadStyleSheet > > ( )
30
31
const isPrintMode = useIsPrintMode ( )
31
32
const isDark = useIsDark ( )
32
33
33
- useLayoutEffect ( ( ) => {
34
- ; ( async ( ) => {
35
- const html = await renderCodeHighlighter (
36
- value ,
37
- language as string ,
38
- isPrintMode ? 'github-light' : isDark ? 'github-dark' : 'github-light' ,
39
- )
40
- if ( ! ref . current ) {
41
- return
34
+ useInsertionEffect ( ( ) => {
35
+ const css = loadStyleSheet (
36
+ `https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/prism-themes/1.9.0/prism-one-${
37
+ isPrintMode ? 'light' : isDark ? 'dark' : 'light'
38
+ } .css`,
39
+ )
40
+
41
+ if ( prevThemeCSS . current ) {
42
+ const $prev = prevThemeCSS . current
43
+ css . $link . onload = ( ) => {
44
+ $prev . remove ( )
42
45
}
43
- ref . current . innerHTML = html
44
- } ) ( )
45
- } , [ isDark , value , language , isPrintMode ] )
46
+ }
47
+
48
+ prevThemeCSS . current = css
49
+ } , [ isDark , isPrintMode ] )
50
+ useInsertionEffect ( ( ) => {
51
+ loadStyleSheet (
52
+ 'https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/prism/1.23.0/plugins/line-numbers/prism-line-numbers.min.css' ,
53
+ )
54
+
55
+ Promise . all ( [
56
+ loadScript (
57
+ 'https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/prism/1.23.0/components/prism-core.min.js' ,
58
+ ) ,
59
+ ] )
60
+ . then ( ( ) =>
61
+ Promise . all ( [
62
+ loadScript (
63
+ 'https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/prism/1.23.0/plugins/autoloader/prism-autoloader.min.js' ,
64
+ ) ,
65
+ loadScript (
66
+ 'https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/prism/1.23.0/plugins/line-numbers/prism-line-numbers.min.js' ,
67
+ ) ,
68
+ ] ) ,
69
+ )
70
+ . then ( ( ) => {
71
+ if ( ref . current ) {
72
+ requestAnimationFrame ( ( ) => {
73
+ window . Prism ?. highlightElement ( ref . current )
74
+
75
+ requestAnimationFrame ( ( ) => {
76
+ window . Prism ?. highlightElement ( ref . current )
77
+ } )
78
+ } )
79
+ } else {
80
+ requestAnimationFrame ( ( ) => {
81
+ window . Prism ?. highlightAll ( )
82
+ // highlightAll twice
83
+
84
+ requestAnimationFrame ( ( ) => {
85
+ window . Prism ?. highlightAll ( )
86
+ } )
87
+ } )
88
+ }
89
+ } )
90
+ } , [ ] )
46
91
47
92
const ref = useRef < HTMLElement > ( null )
48
93
return (
0 commit comments