|
|
@@ -1,81 +1,80 @@
|
|
|
import React, {
|
|
|
- forwardRef, ReactNode, Ref,
|
|
|
+ useCallback, useRef, MutableRefObject,
|
|
|
} from 'react';
|
|
|
|
|
|
import { Editor } from 'codemirror';
|
|
|
import { ICodeMirror, UnControlled as CodeMirror } from 'react-codemirror2';
|
|
|
|
|
|
-import AbstractEditor, { AbstractEditorProps } from '~/components/PageEditor/AbstractEditor';
|
|
|
-
|
|
|
window.CodeMirror = require('codemirror');
|
|
|
require('codemirror/addon/display/placeholder');
|
|
|
require('~/client/util/codemirror/gfm-growi.mode');
|
|
|
|
|
|
-export interface UncontrolledCodeMirrorProps extends AbstractEditorProps {
|
|
|
+export interface UncontrolledCodeMirrorProps extends ICodeMirror {
|
|
|
value: string;
|
|
|
- options?: ICodeMirror['options'];
|
|
|
isGfmMode?: boolean;
|
|
|
lineNumbers?: boolean;
|
|
|
+ onScrollCursorIntoView?: (line: number) => void;
|
|
|
+ onSave?: () => Promise<void>;
|
|
|
+ onPasteFiles?: (event: Event) => void;
|
|
|
+ onCtrlEnter?: (event: Event) => void;
|
|
|
}
|
|
|
|
|
|
-interface UncontrolledCodeMirrorCoreProps extends UncontrolledCodeMirrorProps {
|
|
|
- forwardedRef: Ref<UncontrolledCodeMirrorCore>;
|
|
|
-}
|
|
|
-
|
|
|
-export class UncontrolledCodeMirrorCore extends AbstractEditor<UncontrolledCodeMirrorCoreProps> {
|
|
|
+export const UncontrolledCodeMirror = React.forwardRef<CodeMirror|null, UncontrolledCodeMirrorProps>((props, forwardedRef): JSX.Element => {
|
|
|
|
|
|
- editor: Editor;
|
|
|
+ const wrapperRef = useRef<CodeMirror|null>();
|
|
|
|
|
|
- // wrapperRef: RefObject<any>;
|
|
|
+ const editorRef = useRef<Editor>();
|
|
|
|
|
|
- constructor(props: UncontrolledCodeMirrorCoreProps) {
|
|
|
- super(props);
|
|
|
- this.editorDidMount = this.editorDidMount.bind(this);
|
|
|
- this.editorWillUnmount = this.editorWillUnmount.bind(this);
|
|
|
- }
|
|
|
+ const editorDidMountHandler = useCallback((editor: Editor): void => {
|
|
|
+ editorRef.current = editor;
|
|
|
+ }, []);
|
|
|
|
|
|
- editorDidMount(e: Editor): void {
|
|
|
- this.editor = e;
|
|
|
- }
|
|
|
-
|
|
|
- editorWillUnmount(): void {
|
|
|
+ const editorWillUnmountHandler = useCallback((): void => {
|
|
|
// workaround to fix editor duplicating by https://github.com/scniro/react-codemirror2/issues/284#issuecomment-1155928554
|
|
|
- (this.editor as any).display.wrapper.remove();
|
|
|
- }
|
|
|
-
|
|
|
- override render(): ReactNode {
|
|
|
+ if (editorRef.current != null) {
|
|
|
+ (editorRef.current as any).display.wrapper.remove();
|
|
|
+ }
|
|
|
+ if (wrapperRef.current != null) {
|
|
|
+ (wrapperRef.current as any).hydrated = false;
|
|
|
+ }
|
|
|
+ }, []);
|
|
|
+
|
|
|
+ const {
|
|
|
+ value, lineNumbers, options,
|
|
|
+ ...rest
|
|
|
+ } = props;
|
|
|
+
|
|
|
+ // default true
|
|
|
+ const isGfmMode = rest.isGfmMode ?? true;
|
|
|
|
|
|
- const {
|
|
|
- value, isGfmMode, lineNumbers, options, forwardedRef,
|
|
|
- ...rest
|
|
|
- } = this.props;
|
|
|
-
|
|
|
- return (
|
|
|
- <CodeMirror
|
|
|
- ref={forwardedRef}
|
|
|
- value={value}
|
|
|
- options={{
|
|
|
- lineNumbers: lineNumbers ?? true,
|
|
|
- mode: isGfmMode ? 'gfm-growi' : undefined,
|
|
|
- tabSize: 4,
|
|
|
- ...options,
|
|
|
- }}
|
|
|
- editorDidMount={this.editorDidMount}
|
|
|
- editorWillUnmount={this.editorWillUnmount}
|
|
|
- {...rest}
|
|
|
- />
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-export const UncontrolledCodeMirror = forwardRef<UncontrolledCodeMirrorCore, UncontrolledCodeMirrorProps>((props, ref) => {
|
|
|
return (
|
|
|
- <UncontrolledCodeMirrorCore
|
|
|
- {...props}
|
|
|
- forwardedRef={ref}
|
|
|
+ <CodeMirror
|
|
|
+ ref={(elem) => {
|
|
|
+ // register to wrapperRef
|
|
|
+ wrapperRef.current = elem;
|
|
|
+ // register to forwardedRef
|
|
|
+ if (forwardedRef != null) {
|
|
|
+ if (typeof forwardedRef === 'function') {
|
|
|
+ forwardedRef(elem);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ (forwardedRef as MutableRefObject<CodeMirror|null>).current = elem;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ value={value}
|
|
|
+ options={{
|
|
|
+ lineNumbers: lineNumbers ?? true,
|
|
|
+ mode: isGfmMode ? 'gfm-growi' : undefined,
|
|
|
+ tabSize: 4,
|
|
|
+ ...options,
|
|
|
+ }}
|
|
|
+ editorDidMount={editorDidMountHandler}
|
|
|
+ editorWillUnmount={editorWillUnmountHandler}
|
|
|
+ {...rest}
|
|
|
/>
|
|
|
);
|
|
|
+
|
|
|
});
|
|
|
|
|
|
UncontrolledCodeMirror.displayName = 'UncontrolledCodeMirror';
|