react-codemirror-merge
Version:
CodeMirror merge view for React.
203 lines • 7.68 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose";
var _excluded = ["className", "children", "orientation", "revertControls", "highlightChanges", "gutter", "collapseUnchanged", "destroyRerender", "renderRevertControl", "diffConfig", "root"],
_excluded2 = ["modified", "modifiedExtension", "original", "originalExtension", "theme", "dispatch"];
import React, { useEffect, useImperativeHandle, useRef } from 'react';
import { getDefaultExtensions } from '@uiw/react-codemirror';
import { MergeView } from '@codemirror/merge';
import { useStore } from "./store.js";
import { EditorView } from '@codemirror/view';
import { jsx as _jsx } from "react/jsx-runtime";
export var Internal = /*#__PURE__*/React.forwardRef((props, ref) => {
var {
className,
children,
orientation,
revertControls,
highlightChanges,
gutter,
collapseUnchanged,
destroyRerender = true,
renderRevertControl,
diffConfig,
root
} = props,
elmProps = _objectWithoutPropertiesLoose(props, _excluded);
var _useStore = useStore(),
{
modified,
modifiedExtension,
original,
originalExtension,
theme,
dispatch
} = _useStore,
otherStore = _objectWithoutPropertiesLoose(_useStore, _excluded2);
var editor = useRef(null);
var view = useRef();
var opts = {
orientation,
revertControls,
highlightChanges,
gutter,
collapseUnchanged,
renderRevertControl,
diffConfig,
root
};
useImperativeHandle(ref, () => ({
container: editor.current,
view: view.current,
modified,
original,
config: _extends({
a: original,
b: modified,
parent: editor.current
}, opts)
}), [editor, view, modified, original, opts]);
var originalUpdateListener = EditorView.updateListener.of(vu => {
if (vu.docChanged && typeof (originalExtension == null ? void 0 : originalExtension.onChange) === 'function') {
var doc = vu.state.doc;
var val = doc.toString();
originalExtension == null || originalExtension.onChange(val, vu);
}
});
var modifiedUpdateListener = EditorView.updateListener.of(vu => {
if (vu.docChanged && typeof (modifiedExtension == null ? void 0 : modifiedExtension.onChange) === 'function') {
var doc = vu.state.doc;
var val = doc.toString();
modifiedExtension == null || modifiedExtension.onChange(val, vu);
}
});
useEffect(() => {
if (!view.current && editor.current && originalExtension && modifiedExtension) {
view.current = new MergeView(_extends({
a: _extends({}, original, {
extensions: [...((originalExtension == null ? void 0 : originalExtension.extension) || []), ...getDefaultExtensions(_extends({}, originalExtension == null ? void 0 : originalExtension.option, {
theme
})), originalUpdateListener]
}),
b: _extends({}, modified, {
extensions: [...((modifiedExtension == null ? void 0 : modifiedExtension.extension) || []), ...getDefaultExtensions(_extends({}, modifiedExtension == null ? void 0 : modifiedExtension.option, {
theme
})), modifiedUpdateListener]
}),
parent: editor.current
}, opts));
dispatch({
view: view.current
});
}
}, [view, editor, originalExtension, modifiedExtension]);
useEffect(() => {
if (original && original.doc && view.current) {
var _view$current;
var originalDoc = (_view$current = view.current) == null ? void 0 : _view$current.a.state.doc.toString();
if (originalDoc !== original.doc) {
var _view$current2;
(_view$current2 = view.current) == null || _view$current2.a.dispatch({
changes: {
from: 0,
to: originalDoc.length,
insert: original.doc || ''
}
// effects: StateEffect.reconfigure.of([
// ...(originalExtension?.extension || []),
// ...getDefaultExtensions({ ...originalExtension?.option, theme }),
// ])
});
}
}
if (modified && modified.doc && view.current) {
var _view$current3;
var modifiedDoc = (_view$current3 = view.current) == null ? void 0 : _view$current3.b.state.doc.toString();
if (modifiedDoc !== modified.doc) {
var _view$current4;
(_view$current4 = view.current) == null || _view$current4.b.dispatch({
changes: {
from: 0,
to: modifiedDoc.length,
insert: modified.doc || ''
}
// effects: StateEffect.reconfigure.of([
// ...(modifiedExtension?.extension || []),
// ...getDefaultExtensions({ ...modifiedExtension?.option, theme }),
// ])
});
}
}
if (destroyRerender && view.current) {
var originalFrom = view.current.a.state.selection.ranges[0].from;
var modifiedFrom = view.current.b.state.selection.ranges[0].from;
view.current.destroy();
view.current = new MergeView(_extends({
a: _extends({}, original, {
extensions: [...((originalExtension == null ? void 0 : originalExtension.extension) || []), ...getDefaultExtensions(_extends({}, originalExtension == null ? void 0 : originalExtension.option, {
theme
}))]
}),
b: _extends({}, modified, {
extensions: [...((modifiedExtension == null ? void 0 : modifiedExtension.extension) || []), ...getDefaultExtensions(_extends({}, modifiedExtension == null ? void 0 : modifiedExtension.option, {
theme
}))]
}),
parent: editor.current
}, opts));
if (originalFrom) {
view.current.a.focus();
view.current.a.dispatch({
selection: {
anchor: originalFrom,
head: originalFrom
}
});
}
if (modifiedFrom) {
view.current.b.focus();
view.current.b.dispatch({
selection: {
anchor: modifiedFrom,
head: modifiedFrom
}
});
}
}
}, [view, theme, editor.current, original, modified, originalExtension, modifiedExtension, destroyRerender]);
useEffect(() => () => view.current && view.current.destroy(), []);
useEffect(() => {
if (view.current) {
var _opts = {};
if (otherStore.orientation !== orientation) {
_opts.orientation = orientation;
}
if (otherStore.revertControls !== revertControls) {
_opts.revertControls = revertControls;
}
if (otherStore.highlightChanges !== highlightChanges) {
_opts.highlightChanges = highlightChanges;
}
if (otherStore.gutter !== gutter) {
_opts.gutter = gutter;
}
if (otherStore.collapseUnchanged !== collapseUnchanged) {
_opts.collapseUnchanged = collapseUnchanged;
}
if (otherStore.renderRevertControl !== renderRevertControl) {
_opts.collapseUnchanged = collapseUnchanged;
}
if (Object.keys(_opts).length && dispatch && view.current) {
view.current.reconfigure(_extends({}, _opts));
dispatch(_extends({}, _opts));
}
}
}, [dispatch, view, orientation, revertControls, highlightChanges, gutter, collapseUnchanged, renderRevertControl]);
var defaultClassNames = 'cm-merge-theme';
return /*#__PURE__*/_jsx("div", _extends({
ref: editor,
className: "" + defaultClassNames + (className ? " " + className : '')
}, elmProps, {
children: children
}));
});
Internal.displayName = 'CodeMirrorMerge.Internal';