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

[draw.io] Addable draw.io diagram from Editor. & some bugfixes.

Koki Oyatsu 6 лет назад
Родитель
Сommit
3a91900767

+ 5 - 7
src/client/js/components/Drawio.jsx

@@ -9,11 +9,6 @@ class Drawio extends React.Component {
     super(props);
     super(props);
 
 
     this.drawioContainer = React.createRef();
     this.drawioContainer = React.createRef();
-    const DrawioViewer = window.GraphViewer;
-    if (DrawioViewer != null) {
-      // viewer.min.js の Resize による Scroll イベントを抑止するために無効化する
-      DrawioViewer.useResizeSensor = false;
-    }
 
 
     this.style = {
     this.style = {
       borderRadius: 3,
       borderRadius: 3,
@@ -21,6 +16,9 @@ class Drawio extends React.Component {
       margin: '20px 0',
       margin: '20px 0',
     };
     };
 
 
+    this.isPreview = this.props.isPreview;
+    this.drawioContent = this.props.drawioContent;
+
     this.onEdit = this.onEdit.bind(this);
     this.onEdit = this.onEdit.bind(this);
   }
   }
 
 
@@ -40,13 +38,13 @@ class Drawio extends React.Component {
   }
   }
 
 
   renderContents() {
   renderContents() {
-    return this.props.drawioContent;
+    return this.drawioContent;
   }
   }
 
 
   render() {
   render() {
     return (
     return (
       <div className="editable-with-drawio">
       <div className="editable-with-drawio">
-        { !this.props.isPreview
+        { !this.isPreview
           && (
           && (
           <button type="button" className="drawio-iframe-trigger btn" onClick={this.onEdit}>
           <button type="button" className="drawio-iframe-trigger btn" onClick={this.onEdit}>
             <i className="icon-note"></i> {this.props.t('Edit')}
             <i className="icon-note"></i> {this.props.t('Edit')}

+ 20 - 6
src/client/js/components/PageEditor/DrawioIFrame.jsx

@@ -21,7 +21,7 @@ export default class DrawioIFrame extends React.PureComponent {
 
 
     this.drawioIFrame = React.createRef();
     this.drawioIFrame = React.createRef();
 
 
-    this.headerColor = '#3c4451';
+    this.headerColor = '#334455';
     this.fontFamily = "Lato, -apple-system, BlinkMacSystemFont, 'Hiragino Kaku Gothic ProN', Meiryo, sans-serif";
     this.fontFamily = "Lato, -apple-system, BlinkMacSystemFont, 'Hiragino Kaku Gothic ProN', Meiryo, sans-serif";
 
 
     this.init = this.init.bind(this);
     this.init = this.init.bind(this);
@@ -68,8 +68,10 @@ export default class DrawioIFrame extends React.PureComponent {
   receiveFromDrawio(event) {
   receiveFromDrawio(event) {
     if (event.data === 'ready') {
     if (event.data === 'ready') {
       event.source.postMessage(this.state.drawioMxFile, '*');
       event.source.postMessage(this.state.drawioMxFile, '*');
+      return;
     }
     }
-    else if (event.data === '{"event":"configure"}') {
+
+    if (event.data === '{"event":"configure"}') {
       if (event.source == null) {
       if (event.source == null) {
         return;
         return;
       }
       }
@@ -87,14 +89,17 @@ export default class DrawioIFrame extends React.PureComponent {
           .geEditor { font-family: ${this.fontFamily} !important; }
           .geEditor { font-family: ${this.fontFamily} !important; }
           html td.mxPopupMenuItem {
           html td.mxPopupMenuItem {
             font-family: ${this.fontFamily} !important;
             font-family: ${this.fontFamily} !important;
-            font-size: 9pt !important;
+            font-size: 8pt !important;
           }
           }
           `,
           `,
           customFonts: ['Lato', 'Charter'],
           customFonts: ['Lato', 'Charter'],
         },
         },
       }), '*');
       }), '*');
+
+      return;
     }
     }
-    else if (typeof event.data === 'string' && event.data.match(/mxfile/)) {
+
+    if (typeof event.data === 'string' && event.data.match(/mxfile/)) {
       if (event.data.length > 0) {
       if (event.data.length > 0) {
         const parser = new DOMParser();
         const parser = new DOMParser();
         const dom = parser.parseFromString(event.data, 'text/xml');
         const dom = parser.parseFromString(event.data, 'text/xml');
@@ -105,10 +110,19 @@ export default class DrawioIFrame extends React.PureComponent {
       window.removeEventListener('resize', this.onResizeWindow);
       window.removeEventListener('resize', this.onResizeWindow);
       window.removeEventListener('message', this.receiveFromDrawio);
       window.removeEventListener('message', this.receiveFromDrawio);
       this.hide();
       this.hide();
+
+      return;
     }
     }
-    else {
-      // NOTHING DONE. (Receive unknown iframe message.)
+
+    if (typeof event.data === 'string' && event.data.length === 0) {
+      window.removeEventListener('resize', this.onResizeWindow);
+      window.removeEventListener('message', this.receiveFromDrawio);
+      this.hide();
+
+      return;
     }
     }
+
+    // NOTHING DONE. (Receive unknown iframe message.)
   }
   }
 
 
   onResizeWindow(event) {
   onResizeWindow(event) {

+ 110 - 11
src/client/js/components/PageEditor/MarkdownDrawioUtil.js

@@ -4,28 +4,127 @@
 class MarkdownDrawioUtil {
 class MarkdownDrawioUtil {
 
 
   constructor() {
   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.lineBeginPartOfDrawioRE = /^:::(\s.*)drawio$/;
+    this.lineEndPartOfDrawioRE = /^:::$/;
   }
   }
 
 
   /**
   /**
-   * return MarkdownTable instance of the table where the cursor is
-   * (If the cursor is not in a table, return null)
+   * return the postion of the BOD(beginning of drawio)
+   * (If the cursor is not in a drawio block, return its position)
+   */
+  getBod(editor) {
+    const curPos = editor.getCursor();
+    const firstLine = editor.getDoc().firstLine();
+
+    if (this.lineBeginPartOfDrawioRE.test(editor.getDoc().getLine(curPos.line))) {
+      return { line: curPos.line, ch: 0 };
+    }
+
+    let line = curPos.line - 1;
+    let isFound = false;
+    for (; line >= firstLine; line--) {
+      const strLine = editor.getDoc().getLine(line);
+      if (this.lineBeginPartOfDrawioRE.test(strLine)) {
+        isFound = true;
+        break;
+      }
+
+      if (this.lineEndPartOfDrawioRE.test(strLine)) {
+        isFound = false;
+        break;
+      }
+    }
+
+    if (!isFound) {
+      return { line: curPos.line, ch: curPos.ch };
+    }
+
+    const bodLine = Math.max(firstLine, line);
+    return { line: bodLine, ch: 0 };
+  }
+
+  /**
+   * return the postion of the EOD(end of drawio)
+   * (If the cursor is not in a drawio block, return its position)
+   */
+  getEod(editor) {
+    const curPos = editor.getCursor();
+    const lastLine = editor.getDoc().lastLine();
+
+    if (this.lineEndPartOfDrawioRE.test(editor.getDoc().getLine(curPos.line))) {
+      return { line: curPos.line, ch: editor.getDoc().getLine(curPos.line).length };
+    }
+
+    let line = curPos.line + 1;
+    let isFound = false;
+    for (; line <= lastLine; line++) {
+      const strLine = editor.getDoc().getLine(line);
+      if (this.lineEndPartOfDrawioRE.test(strLine)) {
+        isFound = true;
+        break;
+      }
+
+      if (this.lineBeginPartOfDrawioRE.test(strLine)) {
+        isFound = false;
+        break;
+      }
+    }
+
+    if (!isFound) {
+      return { line: curPos.line, ch: curPos.ch };
+    }
+
+    const eodLine = Math.min(line, lastLine);
+    const lineLength = editor.getDoc().getLine(eodLine).length;
+    return { line: eodLine, ch: lineLength };
+  }
+
+  /**
+   * return boolean value whether the cursor position is in a drawio
+   */
+  isInDrawioBlock(editor) {
+    return (this.getBod(editor) !== this.getEod(editor));
+  }
+
+  /**
+   * return drawioData instance where the cursor is
+   * (If the cursor is not in a drawio block, return current line)
    */
    */
   getMarkdownDrawioMxfile(editor) {
   getMarkdownDrawioMxfile(editor) {
     const curPos = editor.getCursor();
     const curPos = editor.getCursor();
+
+    if (this.isInDrawioBlock(editor)) {
+      const bod = this.getBod(editor);
+      const eod = this.getEod(editor);
+
+      // skip block begin sesion("::: drawio")
+      bod.line++;
+      // skip block end sesion(":::")
+      eod.line--;
+      eod.ch = editor.getDoc().getLine(eod.line).length;
+
+      return editor.getDoc().getRange(bod, eod);
+    }
+
     return editor.getDoc().getLine(curPos.line);
     return editor.getDoc().getLine(curPos.line);
   }
   }
 
 
   replaceFocusedDrawioWithEditor(editor, drawioData) {
   replaceFocusedDrawioWithEditor(editor, drawioData) {
     const curPos = editor.getCursor();
     const curPos = editor.getCursor();
-    const line = editor.getDoc().getLine(curPos.line);
-    editor.getDoc().replaceRange(drawioData.toString(), { line: curPos.line, ch: 0 }, { line: curPos.line, ch: line.length });
+    const drawioBlock = ['::: drawio', drawioData.toString(), ':::'].join('\n');
+    let beginPos;
+    let endPos;
+
+    if (this.isInDrawioBlock(editor)) {
+      beginPos = this.getBod(editor);
+      endPos = this.getEod(editor);
+    }
+    else {
+      beginPos = { line: curPos.line, ch: curPos.ch };
+      endPos = { line: curPos.line, ch: curPos.ch };
+    }
+
+    editor.getDoc().replaceRange(drawioBlock, beginPos, endPos);
   }
   }
 
 
   /**
   /**

+ 6 - 0
src/client/js/util/interceptor/drawio-interceptor.js

@@ -16,6 +16,12 @@ export class DrawioInterceptor extends BasicInterceptor {
 
 
     this.previousPreviewContext = null;
     this.previousPreviewContext = null;
     this.appContainer = appContainer;
     this.appContainer = appContainer;
+
+    const DrawioViewer = window.GraphViewer;
+    if (DrawioViewer != null) {
+      // viewer.min.js の Resize による Scroll イベントを抑止するために無効化する
+      DrawioViewer.useResizeSensor = false;
+    }
   }
   }
 
 
   /**
   /**