Browse Source

134432 insert table from modal

soumaeda 2 years ago
parent
commit
8bdbc00fdb

+ 38 - 24
apps/app/src/components/PageEditor/MarkdownTableUtil.js

@@ -14,6 +14,7 @@ class MarkdownTableUtil {
     // https://regex101.com/r/1UuWBJ/3
     this.emptyLineOfTableRE = /^([^\r\n|]*)\|((\s*\|)+)$/;
 
+    this.getBot = this.getBot.bind(this);
     this.getEot = this.getEot.bind(this);
     this.getStrFromBot = this.getStrFromBot.bind(this);
     this.getStrToEot = this.getStrToEot.bind(this);
@@ -27,21 +28,22 @@ class MarkdownTableUtil {
    * (If the cursor is not in a table, return its position)
    */
   getBot(editor) {
-    const curPos = editor.getCursor();
+    const curPos = editor.state.selection.main.head;
     if (!this.isInTable(editor)) {
-      return { line: curPos.line, ch: curPos.ch };
+      return curPos;
     }
 
-    const firstLine = editor.getDoc().firstLine();
-    let line = curPos.line - 1;
-    for (; line >= firstLine; line--) {
-      const strLine = editor.getDoc().getLine(line);
-      if (!this.linePartOfTableRE.test(strLine)) {
+    const doc = editor.state.doc;
+    const firstLine = doc.line(1);
+    let line = doc.lineAt(curPos).number - 1;
+    for (; line >= firstLine.number; line--) {
+      const strLine = doc.line(line);
+      if (!this.linePartOfTableRE.test(strLine.text)) {
         break;
       }
     }
-    const botLine = Math.max(firstLine, line + 1);
-    return { line: botLine, ch: 0 };
+    const botLine = doc.line(line + 1);
+    return botLine.from;
   }
 
   /**
@@ -49,22 +51,22 @@ class MarkdownTableUtil {
    * (If the cursor is not in a table, return its position)
    */
   getEot(editor) {
-    const curPos = editor.getCursor();
+    const curPos = editor.state.selection.main.head;
     if (!this.isInTable(editor)) {
-      return { line: curPos.line, ch: curPos.ch };
+      return curPos;
     }
 
-    const lastLine = editor.getDoc().lastLine();
-    let line = curPos.line + 1;
-    for (; line <= lastLine; line++) {
-      const strLine = editor.getDoc().getLine(line);
-      if (!this.linePartOfTableRE.test(strLine)) {
+    const doc = editor.state.doc;
+    const lastLine = doc.line(doc.lines);
+    let line = doc.lineAt(curPos).number + 1;
+    for (; line <= lastLine.number; line++) {
+      const strLine = doc.line(line);
+      if (!this.linePartOfTableRE.test(strLine.text)) {
         break;
       }
     }
-    const eotLine = Math.min(line - 1, lastLine);
-    const lineLength = editor.getDoc().getLine(eotLine).length;
-    return { line: eotLine, ch: lineLength };
+    const eotLine = doc.line(line - 1);
+    return eotLine.to;
   }
 
   /**
@@ -113,8 +115,9 @@ class MarkdownTableUtil {
    * return boolean value whether the cursor position is in a table
    */
   isInTable(editor) {
-    const curPos = editor.getCursor();
-    return this.linePartOfTableRE.test(editor.getDoc().getLine(curPos.line));
+    const curPos = editor.state.selection.main.head;
+    const lineText = editor.state.doc.lineAt(curPos).text;
+    return this.linePartOfTableRE.test(lineText);
   }
 
   /**
@@ -153,9 +156,20 @@ class MarkdownTableUtil {
    * @param {MarkdownTable} table
    */
   replaceFocusedMarkdownTableWithEditor(editor, table) {
-    const curPos = editor.getCursor();
-    editor.getDoc().replaceRange(table.toString(), this.getBot(editor), this.getEot(editor));
-    editor.getDoc().setCursor(curPos.line + 1, 2);
+    const botPos = this.getBot(editor);
+    const eotPos = this.getEot(editor);
+    const curPos = editor.state.selection.main.head;
+
+    editor.dispatch({
+      changes: {
+        from: botPos,
+        to: eotPos,
+        insert: table.toString(),
+      },
+    });
+    editor.dispatch({
+      selection: { anchor: editor.state.doc.lineAt(curPos).to },
+    });
   }
 
   /**

+ 22 - 6
packages/editor/src/components/CodeMirrorEditor/Toolbar/TableButton.tsx

@@ -1,13 +1,29 @@
+import { useCallback, useEffect } from 'react';
+
+import { useCodeMirrorEditorIsolated } from '../../../stores';
 import { useHandsontableModal } from '../../../stores/use-handosontable';
 
-export const TableButton = (): JSX.Element => {
-  const { open: openHandsontableModal } = useHandsontableModal();
 
-  const openModalHandler = () => {
-    openHandsontableModal();
-  };
+type TableButtonProps = {
+  editorKey: string,
+}
+
+export const TableButton = (props: TableButtonProps): JSX.Element => {
+  const { editorKey } = props;
+  const { open: openHandsontableModal } = useHandsontableModal();
+  const { data: codeMirrorEditor } = useCodeMirrorEditorIsolated(editorKey);
+  useEffect(() => {
+    if (codeMirrorEditor) {
+      const editor = codeMirrorEditor.view;
+      openHandsontableModal(editor);
+    }
+  }, [codeMirrorEditor, openHandsontableModal]);
+  const openTableModalHandler = useCallback(() => {
+    const editor = codeMirrorEditor?.view;
+    openHandsontableModal(editor);
+  }, [codeMirrorEditor?.view, openHandsontableModal]);
   return (
-    <button type="button" className="btn btn-toolbar-button" onClick={openModalHandler}>
+    <button type="button" className="btn btn-toolbar-button" onClick={openTableModalHandler}>
       <span className="material-symbols-outlined fs-5">table_chart</span>
     </button>
   );

+ 1 - 1
packages/editor/src/components/CodeMirrorEditor/Toolbar/Toolbar.tsx

@@ -29,7 +29,7 @@ export const Toolbar = memo((props: Props): JSX.Element => {
       <EmojiButton
         editorKey={editorKey}
       />
-      <TableButton />
+      <TableButton editorKey={editorKey} />
       <DiagramButton />
       <TemplateButton />
     </div>

+ 8 - 3
packages/editor/src/stores/use-handosontable.ts

@@ -1,5 +1,6 @@
 import { useCallback } from 'react';
 
+import { EditorView } from '@codemirror/view';
 import { useSWRStatic } from '@growi/core/dist/swr';
 import type { SWRResponse } from 'swr';
 
@@ -7,12 +8,13 @@ type HandsonTableModalSaveHandler = () => void;
 
 type HandsontableModalStatus = {
   isOpened: boolean,
+  editor?: EditorView,
   onSave?: HandsonTableModalSaveHandler
 }
 
 type HandsontableModalStatusUtils = {
   open(
-    onSave?: HandsonTableModalSaveHandler
+    editor?: EditorView, onSave?: HandsonTableModalSaveHandler
   ): void
   close(): void
 }
@@ -20,16 +22,19 @@ type HandsontableModalStatusUtils = {
 export const useHandsontableModal = (status?: HandsontableModalStatus): SWRResponse<HandsontableModalStatus, Error> & HandsontableModalStatusUtils => {
   const initialData: HandsontableModalStatus = {
     isOpened: false,
+    editor: undefined,
   };
 
   const swrResponse = useSWRStatic<HandsontableModalStatus, Error>('handsontableModalStatus', status, { fallbackData: initialData });
 
   const { mutate } = swrResponse;
 
-  const open = useCallback((onSave?: HandsonTableModalSaveHandler): void => {
+  const open = useCallback((editor?: EditorView, onSave?: HandsonTableModalSaveHandler): void => {
+    console.log('useHandsontableModalで受け取ったeditor:', editor);
     mutate({
-      isOpened: true, onSave,
+      isOpened: true, editor, onSave,
     });
+    console.log('modal22', editor);
   }, [mutate]);
   const close = useCallback((): void => {
     mutate({