@@ -764,6 +764,8 @@ function TextEditor({
764764 )
765765
766766 const textareaStuckRef = useRef ( true )
767+ const renderedContentRef = useRef ( renderedContent )
768+ renderedContentRef . current = renderedContent
767769
768770 useEffect ( ( ) => {
769771 if ( ! shouldUseCodeRenderer ) return
@@ -772,14 +774,13 @@ function TextEditor({
772774
773775 const updateActiveLineNumber = ( ) => {
774776 const pos = textarea . selectionStart
775- const textBeforeCursor = renderedContent . substring ( 0 , pos )
777+ const textBeforeCursor = renderedContentRef . current . substring ( 0 , pos )
776778 const nextActiveLineNumber = textBeforeCursor . split ( '\n' ) . length
777779 setActiveLineNumber ( ( currentLineNumber ) =>
778780 currentLineNumber === nextActiveLineNumber ? currentLineNumber : nextActiveLineNumber
779781 )
780782 }
781783
782- updateActiveLineNumber ( )
783784 textarea . addEventListener ( 'click' , updateActiveLineNumber )
784785 textarea . addEventListener ( 'keyup' , updateActiveLineNumber )
785786 textarea . addEventListener ( 'focus' , updateActiveLineNumber )
@@ -789,60 +790,64 @@ function TextEditor({
789790 textarea . removeEventListener ( 'keyup' , updateActiveLineNumber )
790791 textarea . removeEventListener ( 'focus' , updateActiveLineNumber )
791792 }
792- } , [ renderedContent , shouldUseCodeRenderer ] )
793+ } , [ shouldUseCodeRenderer ] )
794+
795+ const calculateVisualLinesRef = useRef ( ( ) => { } )
796+ calculateVisualLinesRef . current = ( ) => {
797+ const preElement = codeEditorRef . current ?. querySelector ( 'pre' )
798+ if ( ! ( preElement instanceof HTMLElement ) ) return
799+
800+ const lines = renderedContentRef . current . split ( '\n' )
801+ const newVisualLineHeights : number [ ] = [ ]
802+
803+ const tempContainer = document . createElement ( 'div' )
804+ tempContainer . style . cssText = `
805+ position: absolute;
806+ visibility: hidden;
807+ height: auto;
808+ width: ${ preElement . clientWidth } px;
809+ font-family: ${ window . getComputedStyle ( preElement ) . fontFamily } ;
810+ font-size: ${ window . getComputedStyle ( preElement ) . fontSize } ;
811+ line-height: ${ CODE_EDITOR_LINE_HEIGHT_PX } px;
812+ padding: 8px;
813+ white-space: pre-wrap;
814+ word-break: break-word;
815+ box-sizing: border-box;
816+ `
817+ document . body . appendChild ( tempContainer )
818+
819+ lines . forEach ( ( line ) => {
820+ const lineDiv = document . createElement ( 'div' )
821+ lineDiv . textContent = line || ' '
822+ tempContainer . appendChild ( lineDiv )
823+ const actualHeight = lineDiv . getBoundingClientRect ( ) . height
824+ const lineUnits = Math . max ( 1 , Math . ceil ( actualHeight / CODE_EDITOR_LINE_HEIGHT_PX ) )
825+ newVisualLineHeights . push ( lineUnits )
826+ tempContainer . removeChild ( lineDiv )
827+ } )
828+
829+ document . body . removeChild ( tempContainer )
830+ setVisualLineHeights ( ( currentVisualLineHeights ) =>
831+ areNumberArraysEqual ( currentVisualLineHeights , newVisualLineHeights )
832+ ? currentVisualLineHeights
833+ : newVisualLineHeights
834+ )
835+ }
793836
794837 useEffect ( ( ) => {
795838 if ( ! shouldUseCodeRenderer || ! codeEditorRef . current ) return
796839
797- const calculateVisualLines = ( ) => {
798- const preElement = codeEditorRef . current ?. querySelector ( 'pre' )
799- if ( ! ( preElement instanceof HTMLElement ) ) return
800-
801- const lines = renderedContent . split ( '\n' )
802- const newVisualLineHeights : number [ ] = [ ]
803-
804- const tempContainer = document . createElement ( 'div' )
805- tempContainer . style . cssText = `
806- position: absolute;
807- visibility: hidden;
808- height: auto;
809- width: ${ preElement . clientWidth } px;
810- font-family: ${ window . getComputedStyle ( preElement ) . fontFamily } ;
811- font-size: ${ window . getComputedStyle ( preElement ) . fontSize } ;
812- line-height: ${ CODE_EDITOR_LINE_HEIGHT_PX } px;
813- padding: 8px;
814- white-space: pre-wrap;
815- word-break: break-word;
816- box-sizing: border-box;
817- `
818- document . body . appendChild ( tempContainer )
819-
820- lines . forEach ( ( line ) => {
821- const lineDiv = document . createElement ( 'div' )
822- lineDiv . textContent = line || ' '
823- tempContainer . appendChild ( lineDiv )
824- const actualHeight = lineDiv . getBoundingClientRect ( ) . height
825- const lineUnits = Math . max ( 1 , Math . ceil ( actualHeight / CODE_EDITOR_LINE_HEIGHT_PX ) )
826- newVisualLineHeights . push ( lineUnits )
827- tempContainer . removeChild ( lineDiv )
828- } )
829-
830- document . body . removeChild ( tempContainer )
831- setVisualLineHeights ( ( currentVisualLineHeights ) =>
832- areNumberArraysEqual ( currentVisualLineHeights , newVisualLineHeights )
833- ? currentVisualLineHeights
834- : newVisualLineHeights
835- )
836- }
837-
838- const timeoutId = setTimeout ( calculateVisualLines , 50 )
839- const resizeObserver = new ResizeObserver ( calculateVisualLines )
840+ const resizeObserver = new ResizeObserver ( ( ) => calculateVisualLinesRef . current ( ) )
840841 resizeObserver . observe ( codeEditorRef . current )
841842
842843 return ( ) => {
843- clearTimeout ( timeoutId )
844844 resizeObserver . disconnect ( )
845845 }
846+ } , [ shouldUseCodeRenderer ] )
847+
848+ useEffect ( ( ) => {
849+ if ( ! shouldUseCodeRenderer ) return
850+ calculateVisualLinesRef . current ( )
846851 } , [ renderedContent , shouldUseCodeRenderer ] )
847852
848853 const renderCodeLineNumbers = useCallback ( ( ) : ReactElement [ ] => {
@@ -938,7 +943,7 @@ function TextEditor({
938943 if ( streamingContent === undefined ) {
939944 if ( isLoading ) return DOCUMENT_SKELETON
940945
941- if ( error ) {
946+ if ( error && ! isInitialized ) {
942947 return (
943948 < div className = 'flex flex-1 items-center justify-center' >
944949 < p className = 'text-[13px] text-[var(--text-muted)]' > Failed to load file content</ p >
0 commit comments