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

134432 get editor from TableButton

soumaeda 2 лет назад
Родитель
Сommit
f8aaebb144

+ 15 - 11
apps/app/src/components/PageEditor/HandsontableModal.tsx

@@ -1,8 +1,5 @@
-import React, { useEffect, useState } from 'react';
+import React, { useState } from 'react';
 
 
-import {
-  GlobalCodeMirrorEditorKey, useCodeMirrorEditorIsolated,
-} from '@growi/editor';
 import { HotTable } from '@handsontable/react';
 import { HotTable } from '@handsontable/react';
 import Handsontable from 'handsontable';
 import Handsontable from 'handsontable';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
@@ -14,7 +11,6 @@ import { debounce } from 'throttle-debounce';
 
 
 import MarkdownTable from '~/client/models/MarkdownTable';
 import MarkdownTable from '~/client/models/MarkdownTable';
 import mtu from '~/components/PageEditor/MarkdownTableUtil';
 import mtu from '~/components/PageEditor/MarkdownTableUtil';
-import mtue from '~/components/PageEditor/MarkdownTableUtilForEditor';
 import { useHandsontableModal } from '~/stores/modal';
 import { useHandsontableModal } from '~/stores/modal';
 
 
 import ExpandOrContractButton from '../ExpandOrContractButton';
 import ExpandOrContractButton from '../ExpandOrContractButton';
@@ -36,12 +32,12 @@ export const HandsontableModal = (): JSX.Element => {
 
 
   const { t } = useTranslation('commons');
   const { t } = useTranslation('commons');
   const { data: handsontableModalData, close: closeHandsontableModal } = useHandsontableModal();
   const { data: handsontableModalData, close: closeHandsontableModal } = useHandsontableModal();
-  const { data: codeMirrorEditor } = useCodeMirrorEditorIsolated(GlobalCodeMirrorEditorKey.MAIN);
 
 
   const isOpened = handsontableModalData?.isOpened ?? false;
   const isOpened = handsontableModalData?.isOpened ?? false;
+  const table = handsontableModalData?.table;
   const autoFormatMarkdownTable = handsontableModalData?.autoFormatMarkdownTable ?? false;
   const autoFormatMarkdownTable = handsontableModalData?.autoFormatMarkdownTable ?? false;
+  const editor = handsontableModalData?.editor;
   const onSave = handsontableModalData?.onSave;
   const onSave = handsontableModalData?.onSave;
-  const editor = codeMirrorEditor?.view;
 
 
   const defaultMarkdownTable = () => {
   const defaultMarkdownTable = () => {
     return new MarkdownTable(
     return new MarkdownTable(
@@ -106,9 +102,17 @@ export const HandsontableModal = (): JSX.Element => {
   const debouncedHandleWindowExpandedChange = debounce(100, handleWindowExpandedChange);
   const debouncedHandleWindowExpandedChange = debounce(100, handleWindowExpandedChange);
 
 
   const handleModalOpen = () => {
   const handleModalOpen = () => {
-    const editorMarkdownTable = mtue.getMarkdownTable(editor);
-    const initTableInstance = editorMarkdownTable == null ? defaultMarkdownTable : editorMarkdownTable.clone();
-    setMarkdownTable(editorMarkdownTable ?? defaultMarkdownTable);
+    let markdownTableState;
+    if (table == null) {
+      // markdowntable state from Editor
+      markdownTableState = mtu.getMarkdownTable(editor);
+    }
+    else {
+      // markdowntable state from View
+      markdownTableState = table;
+    }
+    const initTableInstance = markdownTableState == null ? defaultMarkdownTable : markdownTableState.clone();
+    setMarkdownTable(markdownTableState ?? defaultMarkdownTable);
     setMarkdownTableOnInit(initTableInstance);
     setMarkdownTableOnInit(initTableInstance);
     debouncedHandleWindowExpandedChange();
     debouncedHandleWindowExpandedChange();
   };
   };
@@ -168,7 +172,7 @@ export const HandsontableModal = (): JSX.Element => {
       return;
       return;
     }
     }
 
 
-    mtue.replaceFocusedMarkdownTableWithEditor(editor, newMarkdownTable);
+    mtu.replaceFocusedMarkdownTableWithEditor(editor, newMarkdownTable);
     cancel();
     cancel();
   };
   };
 
 

+ 0 - 161
apps/app/src/components/PageEditor/MarkdownTableUtilForEditor.js

@@ -1,161 +0,0 @@
-import MarkdownTable from '~/client/models/MarkdownTable';
-
-/**
- * Utility for markdown table
- */
-class MarkdownTableUtil {
-
-  constructor() {
-    // https://github.com/markdown-it/markdown-it/blob/d29f421927e93e88daf75f22089a3e732e195bd2/lib/rules_block/table.js#L83
-    this.tableAlignmentLineRE = /^[-:|][-:|\s]*$/;
-    this.tableAlignmentLineNegRE = /^[^-:]*$/; // it is need to check to ignore empty row which is matched above RE
-    // https://regex101.com/r/7BN2fR/10
-    this.linePartOfTableRE = /^([^\r\n|]*)\|(([^\r\n|]*\|)+)$/;
-    // https://regex101.com/r/1UuWBJ/3
-    this.emptyLineOfTableRE = /^([^\r\n|]*)\|((\s*\|)+)$/;
-
-    this.getEot = this.getEot.bind(this);
-    this.getStrFromBot = this.getStrFromBot.bind(this);
-    this.getStrToEot = this.getStrToEot.bind(this);
-    this.isInTable = this.isInTable.bind(this);
-    this.replaceFocusedMarkdownTableWithEditor = this.replaceFocusedMarkdownTableWithEditor.bind(this);
-    this.replaceMarkdownTableWithReformed = this.replaceFocusedMarkdownTableWithEditor; // alias
-  }
-
-  /**
-   * return the postion of the BOT(beginning of table)
-   * (If the cursor is not in a table, return its position)
-   */
-  getBot(editor) {
-    const curPos = editor.getCursor();
-    if (!this.isInTable(editor)) {
-      return { line: curPos.line, ch: curPos.ch };
-    }
-
-    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)) {
-        break;
-      }
-    }
-    const botLine = Math.max(firstLine, line + 1);
-    return { line: botLine, ch: 0 };
-  }
-
-  /**
-   * return the postion of the EOT(end of table)
-   * (If the cursor is not in a table, return its position)
-   */
-  getEot(editor) {
-    const curPos = editor.getCursor();
-    if (!this.isInTable(editor)) {
-      return { line: curPos.line, ch: curPos.ch };
-    }
-
-    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)) {
-        break;
-      }
-    }
-    const eotLine = Math.min(line - 1, lastLine);
-    const lineLength = editor.getDoc().getLine(eotLine).length;
-    return { line: eotLine, ch: lineLength };
-  }
-
-  /**
-   * return strings from BOT(beginning of table) to the cursor position
-   */
-  getStrFromBot(editor) {
-    const curPos = editor.getCursor();
-    return editor.getDoc().getRange(this.getBot(editor), curPos);
-  }
-
-  /**
-   * return strings from the cursor position to EOT(end of table)
-   */
-  getStrToEot(editor) {
-    const curPos = editor.getCursor();
-    return editor.getDoc().getRange(curPos, this.getEot(editor));
-  }
-
-  /**
-   * return MarkdownTable instance of the table where the cursor is
-   * (If the cursor is not in a table, return null)
-   */
-  getMarkdownTable(editor) {
-    if (!this.isInTable(editor)) {
-      return null;
-    }
-
-    const strFromBotToEot = editor.getDoc().getRange(this.getBot(editor), this.getEot(editor));
-    return MarkdownTable.fromMarkdownString(strFromBotToEot);
-  }
-
-  /**
-   * return boolean value whether the cursor position is end of line
-   */
-  isEndOfLine(editor) {
-    const curPos = editor.getCursor();
-    return (curPos.ch === editor.getDoc().getLine(curPos.line).length);
-  }
-
-  /**
-   * 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));
-  }
-
-  /**
-   * add a row at the end
-   * (This function overwrite directory markdown table specified as argument.)
-   * @param {MarkdownTable} markdown table
-   */
-  addRowToMarkdownTable(mdtable) {
-    const numCol = mdtable.table.length > 0 ? mdtable.table[0].length : 1;
-    const newRow = [];
-    (new Array(numCol)).forEach(() => { return newRow.push('') }); // create cols
-    mdtable.table.push(newRow);
-  }
-
-  /**
-   * return markdown table that is merged all of markdown table in array
-   * (The merged markdown table options are used for the first markdown table.)
-   * @param {Array} array of markdown table
-   */
-  mergeMarkdownTable(mdtableList) {
-    if (mdtableList == null || !(mdtableList instanceof Array)) {
-      return undefined;
-    }
-
-    let newTable = [];
-    const options = mdtableList[0].options; // use option of first markdown-table
-    mdtableList.forEach((mdtable) => {
-      newTable = newTable.concat(mdtable.table);
-    });
-    return (new MarkdownTable(newTable, options));
-  }
-
-  /**
-   * replace focused markdown table with editor
-   * (A replaced table is reformed by markdown-table.)
-   * @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);
-  }
-
-}
-
-// singleton pattern
-const instance = new MarkdownTableUtil();
-Object.freeze(instance);
-export default instance;

+ 12 - 3
packages/editor/src/components/CodeMirrorEditor/Toolbar/TableButton.tsx

@@ -1,12 +1,21 @@
 import { useCallback } from 'react';
 import { useCallback } from 'react';
 
 
+import { useCodeMirrorEditorIsolated } from '../../../stores';
 import { useHandsontableModal } from '../../../stores/use-hands-on-table';
 import { useHandsontableModal } from '../../../stores/use-hands-on-table';
 
 
-export const TableButton = (): JSX.Element => {
+
+type Props = {
+  editorKey: string,
+}
+
+export const TableButton = (props: Props): JSX.Element => {
+  const { editorKey } = props;
+  const { data: codeMirrorEditor } = useCodeMirrorEditorIsolated(editorKey);
   const { open: openTableModal } = useHandsontableModal();
   const { open: openTableModal } = useHandsontableModal();
+  const editor = codeMirrorEditor?.view;
   const openTableModalHandler = useCallback(() => {
   const openTableModalHandler = useCallback(() => {
-    openTableModal();
-  }, []);
+    openTableModal(editor);
+  }, [editor]);
 
 
   return (
   return (
     <button type="button" className="btn btn-toolbar-button" onClick={openTableModalHandler}>
     <button type="button" className="btn btn-toolbar-button" onClick={openTableModalHandler}>

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

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

+ 7 - 3
packages/editor/src/stores/use-hands-on-table.ts

@@ -1,5 +1,6 @@
 import { useCallback } from 'react';
 import { useCallback } from 'react';
 
 
+import { EditorView } from '@codemirror/view';
 import { useSWRStatic } from '@growi/core/dist/swr';
 import { useSWRStatic } from '@growi/core/dist/swr';
 import type { SWRResponse } from 'swr';
 import type { SWRResponse } from 'swr';
 
 
@@ -7,12 +8,14 @@ type HandsonTableModalSaveHandler = () => void;
 
 
 type HandsontableModalStatus = {
 type HandsontableModalStatus = {
   isOpened: boolean,
   isOpened: boolean,
+  editor?: EditorView,
   // onSave is passed only when editing table directly from the page.
   // onSave is passed only when editing table directly from the page.
   onSave?: HandsonTableModalSaveHandler
   onSave?: HandsonTableModalSaveHandler
 }
 }
 
 
 type HandsontableModalStatusUtils = {
 type HandsontableModalStatusUtils = {
   open(
   open(
+    editor?: EditorView,
     onSave?: HandsonTableModalSaveHandler
     onSave?: HandsonTableModalSaveHandler
   ): void
   ): void
   close(): void
   close(): void
@@ -21,20 +24,21 @@ type HandsontableModalStatusUtils = {
 export const useHandsontableModal = (status?: HandsontableModalStatus): SWRResponse<HandsontableModalStatus, Error> & HandsontableModalStatusUtils => {
 export const useHandsontableModal = (status?: HandsontableModalStatus): SWRResponse<HandsontableModalStatus, Error> & HandsontableModalStatusUtils => {
   const initialData: HandsontableModalStatus = {
   const initialData: HandsontableModalStatus = {
     isOpened: false,
     isOpened: false,
+    editor: undefined,
   };
   };
 
 
   const swrResponse = useSWRStatic<HandsontableModalStatus, Error>('handsontableModalStatus', status, { fallbackData: initialData });
   const swrResponse = useSWRStatic<HandsontableModalStatus, Error>('handsontableModalStatus', status, { fallbackData: initialData });
 
 
   const { mutate } = swrResponse;
   const { mutate } = swrResponse;
 
 
-  const open = useCallback((onSave?: HandsonTableModalSaveHandler): void => {
+  const open = useCallback((editor?: EditorView, onSave?: HandsonTableModalSaveHandler): void => {
     mutate({
     mutate({
-      isOpened: true, onSave,
+      isOpened: true, editor, onSave,
     });
     });
   }, [mutate]);
   }, [mutate]);
   const close = useCallback((): void => {
   const close = useCallback((): void => {
     mutate({
     mutate({
-      isOpened: false, onSave: undefined,
+      isOpened: false, editor: undefined, onSave: undefined,
     });
     });
   }, [mutate]);
   }, [mutate]);