11import React , { useEffect , useImperativeHandle , useRef } from 'react' ;
2- import { EditorStateConfig } from '@codemirror/state' ;
2+ import { EditorStateConfig , StateEffect } from '@codemirror/state' ;
33import { getDefaultExtensions } from '@uiw/react-codemirror' ;
44import { MergeView , MergeConfig , DirectMergeConfig } from '@codemirror/merge' ;
55import { useStore } from './store' ;
@@ -25,15 +25,16 @@ export const Internal = React.forwardRef<InternalRef, CodeMirrorMergeProps>((pro
2525 renderRevertControl,
2626 ...elmProps
2727 } = props ;
28- const { modified, modifiedExtension, original, originalExtension, theme, view , dispatch, ...otherStore } = useStore ( ) ;
28+ const { modified, modifiedExtension, original, originalExtension, theme, dispatch, ...otherStore } = useStore ( ) ;
2929 const editor = useRef < HTMLDivElement > ( null ) ;
30+ const view = useRef < MergeView > ( ) ;
3031 const opts = { orientation, revertControls, highlightChanges, gutter, collapseUnchanged, renderRevertControl } ;
3132
3233 useImperativeHandle (
3334 ref ,
3435 ( ) => ( {
3536 container : editor . current ,
36- view,
37+ view : view . current ,
3738 modified,
3839 original,
3940 config : {
@@ -47,9 +48,8 @@ export const Internal = React.forwardRef<InternalRef, CodeMirrorMergeProps>((pro
4748 ) ;
4849
4950 useEffect ( ( ) => {
50- if ( view && original && modified && theme && editor . current && dispatch ) {
51- editor . current . innerHTML = '' ;
52- new MergeView ( {
51+ if ( ! view . current && editor . current ) {
52+ view . current = new MergeView ( {
5353 a : {
5454 ...original ,
5555 extensions : [
@@ -68,24 +68,58 @@ export const Internal = React.forwardRef<InternalRef, CodeMirrorMergeProps>((pro
6868 ...opts ,
6969 } ) ;
7070 }
71- } , [ theme , editor . current , original , modified , originalExtension , modifiedExtension ] ) ;
71+ } , [ view , editor ] ) ;
7272
7373 useEffect ( ( ) => {
74- if ( ! view && editor . current && original ?. extensions && modified ?. extensions ) {
75- const viewDefault = new MergeView ( {
76- a : original ,
77- b : modified ,
78- parent : editor . current ,
79- ...opts ,
80- } ) ;
81- dispatch && dispatch ( { view : viewDefault , container : editor . current , ...opts } ) ;
74+ if ( original && original . doc && view . current ) {
75+ const originalDoc = view . current ?. a . state . doc . toString ( ) ;
76+ if ( originalDoc !== original . doc ) {
77+ view . current ?. a . dispatch ( {
78+ changes : { from : 0 , to : originalDoc . length , insert : original . doc || '' } ,
79+ // effects: StateEffect.reconfigure.of([
80+ // ...(originalExtension?.extension || []),
81+ // ...getDefaultExtensions({ ...originalExtension?.option, theme }),
82+ // ])
83+ } ) ;
84+ }
8285 }
83- } , [ editor . current , original , modified , view ] ) ;
86+ if ( modified && modified . doc && view . current ) {
87+ const modifiedDoc = view . current ?. b . state . doc . toString ( ) ;
88+ if ( modifiedDoc !== modified . doc ) {
89+ view . current ?. b . dispatch ( {
90+ changes : { from : 0 , to : modifiedDoc . length , insert : modified . doc || '' } ,
91+ // effects: StateEffect.reconfigure.of([
92+ // ...(modifiedExtension?.extension || []),
93+ // ...getDefaultExtensions({ ...modifiedExtension?.option, theme }),
94+ // ])
95+ } ) ;
96+ }
97+ }
98+ view . current ?. destroy ( ) ;
99+ view . current = new MergeView ( {
100+ a : {
101+ ...original ,
102+ extensions : [
103+ ...( originalExtension ?. extension || [ ] ) ,
104+ ...getDefaultExtensions ( { ...originalExtension ?. option , theme } ) ,
105+ ] ,
106+ } ,
107+ b : {
108+ ...modified ,
109+ extensions : [
110+ ...( modifiedExtension ?. extension || [ ] ) ,
111+ ...getDefaultExtensions ( { ...modifiedExtension ?. option , theme } ) ,
112+ ] ,
113+ } ,
114+ parent : editor . current ! ,
115+ ...opts ,
116+ } ) ;
117+ } , [ view , theme , editor . current , original , modified , originalExtension , modifiedExtension ] ) ;
84118
85- useEffect ( ( ) => ( ) => view && view . destroy ( ) , [ ] ) ;
119+ useEffect ( ( ) => ( ) => view . current && view . current . destroy ( ) , [ ] ) ;
86120
87121 useEffect ( ( ) => {
88- if ( view ) {
122+ if ( view . current ) {
89123 const opts : MergeConfig = { } ;
90124 if ( otherStore . orientation !== orientation ) {
91125 opts . orientation = orientation ;
@@ -102,29 +136,15 @@ export const Internal = React.forwardRef<InternalRef, CodeMirrorMergeProps>((pro
102136 if ( otherStore . collapseUnchanged !== collapseUnchanged ) {
103137 opts . collapseUnchanged = collapseUnchanged ;
104138 }
105- if ( Object . keys ( opts ) . length && dispatch && original && modified && editor . current ) {
106- view . destroy ( ) ;
107- const viewDefault = new MergeView ( {
108- a : original ,
109- b : modified ,
110- parent : editor . current ,
111- ...opts ,
112- } ) ;
113- dispatch ( { ...opts , renderRevertControl, view : viewDefault } ) ;
139+ if ( otherStore . renderRevertControl !== renderRevertControl ) {
140+ opts . collapseUnchanged = collapseUnchanged ;
141+ }
142+ if ( Object . keys ( opts ) . length && dispatch && view . current ) {
143+ view . current . reconfigure ( { ...opts } ) ;
144+ dispatch ( { ...opts } ) ;
114145 }
115146 }
116- } , [
117- view ,
118- original ,
119- modified ,
120- editor ,
121- orientation ,
122- revertControls ,
123- highlightChanges ,
124- gutter ,
125- collapseUnchanged ,
126- renderRevertControl ,
127- ] ) ;
147+ } , [ dispatch , view , orientation , revertControls , highlightChanges , gutter , collapseUnchanged , renderRevertControl ] ) ;
128148
129149 const defaultClassNames = 'cm-merge-theme' ;
130150 return (
0 commit comments