Просмотр исходного кода

Merge pull request #6476 from weseek/fix/call-setCaretLine-from-header

fix: Call setCaretLine from header
Yuki Takei 3 лет назад
Родитель
Сommit
8beb707b6b

+ 9 - 8
packages/app/src/components/Page/DisplaySwitcher.tsx

@@ -29,14 +29,14 @@ const WIKI_HEADER_LINK = 120;
 const { isTopPage } = pagePathUtils;
 
 
-const DisplaySwitcher = (): JSX.Element => {
-  const { t } = useTranslation();
+const PageEditor = dynamic(() => import('../PageEditor'), { ssr: false });
+const EditorNavbarBottom = dynamic(() => import('../PageEditor/EditorNavbarBottom'), { ssr: false });
+const HashChanged = dynamic(() => import('../EventListeneres/HashChanged'), { ssr: false });
+const ContentLinkButtons = dynamic(() => import('../ContentLinkButtons'), { ssr: false });
+const NotFoundPage = dynamic(() => import('../NotFoundPage'), { ssr: false });
 
-  const PageEditor = dynamic(() => import('../PageEditor'), { ssr: false });
-  const EditorNavbarBottom = dynamic(() => import('../PageEditor/EditorNavbarBottom'), { ssr: false });
-  const HashChanged = dynamic(() => import('../EventListeneres/HashChanged'), { ssr: false });
-  const ContentLinkButtons = dynamic(() => import('../ContentLinkButtons'), { ssr: false });
-  const NotFoundPage = dynamic(() => import('../NotFoundPage'), { ssr: false });
+const DisplaySwitcher = React.memo((): JSX.Element => {
+  const { t } = useTranslation();
 
   // get element for smoothScroll
   // const getCommentListDom = useMemo(() => { return document.getElementById('page-comments-list') }, []);
@@ -141,6 +141,7 @@ const DisplaySwitcher = (): JSX.Element => {
       { isEditable && <HashChanged></HashChanged> }
     </>
   );
-};
+});
+DisplaySwitcher.displayName = 'DisplaySwitcher';
 
 export default DisplaySwitcher;

+ 4 - 3
packages/app/src/components/PageEditor.tsx

@@ -80,7 +80,7 @@ let lastScrolledDateWithCursor: Date | null = null;
 let isOriginOfScrollSyncEditor = false;
 let isOriginOfScrollSyncPreview = false;
 
-const PageEditor = (props: Props): JSX.Element => {
+const PageEditor = React.memo((props: Props): JSX.Element => {
   // const {
   //   pageContainer, editorContainer,
   // } = props;
@@ -222,7 +222,7 @@ const PageEditor = (props: Props): JSX.Element => {
       editorRef.current.terminateUploadingState();
     }
   // }, [editorMode, mutateGrant, pageContainer]);
-  }, [editorMode, mutateGrant]);
+  }, [currentPagePath, mutateGrant, pageId]);
 
 
   const scrollPreviewByEditorLine = useCallback((line: number) => {
@@ -477,7 +477,8 @@ const PageEditor = (props: Props): JSX.Element => {
       /> */}
     </div>
   );
-};
+});
+PageEditor.displayName = 'PageEditor';
 
 /**
    * Wrapper component for using unstated

+ 4 - 3
packages/app/src/components/PageEditor/CodeMirrorEditor.jsx

@@ -116,6 +116,7 @@ class CodeMirrorEditor extends AbstractEditor {
       emojiSearchText: null,
     };
 
+    this.cm = React.createRef();
     this.gridEditModal = React.createRef();
     this.linkEditModal = React.createRef();
     this.handsontableModal = React.createRef();
@@ -227,7 +228,7 @@ class CodeMirrorEditor extends AbstractEditor {
   }
 
   getCodeMirror() {
-    return this.cm.editor;
+    return this.cm.current?.editor;
   }
 
   /**
@@ -279,7 +280,7 @@ class CodeMirrorEditor extends AbstractEditor {
     }
 
     const editor = this.getCodeMirror();
-    const linePosition = Math.max(0, line);
+    const linePosition = Math.max(0, line - 1);
 
     editor.setCursor({ line: linePosition }); // leave 'ch' field as null/undefined to indicate the end of line
 
@@ -991,7 +992,7 @@ class CodeMirrorEditor extends AbstractEditor {
       <div className={`grw-codemirror-editor ${styles['grw-codemirror-editor']}`}>
 
         <UncontrolledCodeMirror
-          ref={(c) => { this.cm = c }}
+          ref={this.cm}
           className={additionalClasses}
           placeholder="search"
           editorDidMount={(editor) => {

+ 10 - 15
packages/app/src/components/PageEditor/Editor.tsx

@@ -60,38 +60,33 @@ const Editor = React.forwardRef((props: EditorPropsType, ref): JSX.Element => {
   const cmEditorRef = useRef<CodeMirrorEditor>(null);
   const taEditorRef = useRef<TextAreaEditor>(null);
 
-  const editorSubstance = isMobile ? taEditorRef.current : cmEditorRef.current;
+  const editorSubstance = useCallback(() => {
+    return isMobile ? taEditorRef.current : cmEditorRef.current;
+  }, [isMobile]);
 
   const methods: Partial<IEditorMethods> = useMemo(() => {
     return {
       forceToFocus: () => {
-        if (editorSubstance == null) { return }
-        editorSubstance.forceToFocus();
+        editorSubstance()?.forceToFocus();
       },
       setValue: (newValue: string) => {
-        if (editorSubstance == null) { return }
-        editorSubstance.setValue(newValue);
+        editorSubstance()?.setValue(newValue);
       },
       setGfmMode: (bool: boolean) => {
-        if (editorSubstance == null) { return }
-        editorSubstance.setGfmMode(bool);
+        editorSubstance()?.setGfmMode(bool);
       },
       setCaretLine: (line: number) => {
-        if (editorSubstance == null) { return }
-        editorSubstance.setCaretLine(line);
+        editorSubstance()?.setCaretLine(line);
       },
       setScrollTopByLine: (line: number) => {
-        if (editorSubstance == null) { return }
-        editorSubstance.setScrollTopByLine(line);
+        editorSubstance()?.setScrollTopByLine(line);
       },
       insertText: (text: string) => {
-        if (editorSubstance == null) { return }
-        editorSubstance.insertText(text);
+        editorSubstance()?.insertText(text);
       },
       getNavbarItems: (): JSX.Element[] => {
-        if (editorSubstance == null) { return [] }
         // concat common items and items specific to CodeMirrorEditor or TextAreaEditor
-        const navbarItems = editorSubstance.getNavbarItems() ?? [];
+        const navbarItems = editorSubstance()?.getNavbarItems() ?? [];
         return navbarItems;
       },
     };

+ 3 - 4
packages/app/src/components/PageEditor/TextAreaEditor.jsx

@@ -2,15 +2,14 @@ import React from 'react';
 // import PropTypes from 'prop-types';
 
 import { Input } from 'reactstrap';
+
 import InterceptorManager from '~/services/interceptor-manager';
 import loggerFactory from '~/utils/logger';
 
 
 import AbstractEditor from './AbstractEditor';
-
-import pasteHelper from './PasteHelper';
 import mlu from './MarkdownListUtil';
-
+import pasteHelper from './PasteHelper';
 import PreventMarkdownListInterceptor from './PreventMarkdownListInterceptor';
 
 export default class TextAreaEditor extends AbstractEditor {
@@ -89,7 +88,7 @@ export default class TextAreaEditor extends AbstractEditor {
     // scroll to bottom
     this.textarea.scrollTop = this.textarea.scrollHeight;
 
-    const lines = this.textarea.value.split('\n').slice(0, line + 1);
+    const lines = this.textarea.value.split('\n').slice(0, line);
     /* eslint-disable no-param-reassign, no-return-assign */
     const pos = lines
       .map((lineStr) => { return lineStr.length + 1 }) // correct length+1 of each lines

+ 11 - 1
packages/app/src/components/ReactMarkdownComponents/Header.tsx

@@ -1,3 +1,5 @@
+import EventEmitter from 'events';
+
 import { Element } from 'react-markdown/lib/rehype-filter';
 
 import { NextLink } from './NextLink';
@@ -6,6 +8,14 @@ import { NextLink } from './NextLink';
 import styles from './Header.module.scss';
 
 
+declare const globalEmitter: EventEmitter;
+
+function setCaretLine(line?: number): void {
+  if (line != null) {
+    globalEmitter.emit('setCaretLine', line);
+  }
+}
+
 type EditLinkProps = {
   line?: number,
 }
@@ -18,7 +28,7 @@ const EditLink = (props: EditLinkProps): JSX.Element => {
 
   return (
     <span className="revision-head-edit-button">
-      <a href="#edit" aria-disabled={isDisabled} onClick={() => console.log(`TODO: Jump to the line '${props.line}'`)}>
+      <a href="#edit" aria-disabled={isDisabled} onClick={() => setCaretLine(props.line)}>
         <i className="icon-note"></i>
       </a>
     </span>