فهرست منبع

ensure to update `cm.display.viewOffset` forcely

Yuki Takei 7 سال پیش
والد
کامیت
ec03fc4669
1فایلهای تغییر یافته به همراه47 افزوده شده و 0 حذف شده
  1. 47 0
      src/client/js/components/PageEditor/EmojiAutoCompleteHelper.js

+ 47 - 0
src/client/js/components/PageEditor/EmojiAutoCompleteHelper.js

@@ -1,3 +1,9 @@
+import { sawCollapsedSpans } from 'codemirror/src/line/saw_special_spans';
+import { getLine } from 'codemirror/src/line/utils_line';
+import { heightAtLine, visualLineEndNo, visualLineNo } from 'codemirror/src/line/spans';
+import { DisplayUpdate } from 'codemirror/src/display/update_display';
+import { adjustView } from 'codemirror/src/display/view_tracking';
+
 class EmojiAutoCompleteHelper {
 
   constructor(emojiStrategy) {
@@ -20,6 +26,35 @@ class EmojiAutoCompleteHelper {
     }
   }
 
+  /**
+   * Transplant 'updateDisplayIfNeeded' method to fix weseek/growi#703
+   *
+   * @see https://github.com/weseek/growi/issues/703
+   * @see https://github.com/codemirror/CodeMirror/blob/5.42.0/src/display/update_display.js#L125
+   *
+   * @param {CodeMirror} cm
+   */
+  forceUpdateDisplay(cm) {
+    const doc = cm.doc;
+    const display = cm.display;
+
+    const update = new DisplayUpdate(cm, cm.getViewport());
+
+    // Compute a suitable new viewport (from & to)
+    let end = doc.first + doc.size;
+    let from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first);
+    let to = Math.min(end, update.visible.to + cm.options.viewportMargin);
+    if (display.viewFrom < from && from - display.viewFrom < 20) from = Math.max(doc.first, display.viewFrom);
+    if (display.viewTo > to && display.viewTo - to < 20) to = Math.min(end, display.viewTo);
+    if (sawCollapsedSpans) {
+      from = visualLineNo(cm.doc, from);
+      to = visualLineEndNo(cm.doc, to);
+    }
+    adjustView(cm, from, to);
+
+    display.viewOffset = heightAtLine(getLine(doc, display.viewFrom));
+  }
+
   /**
    * try to find emoji terms and show hint
    * @param {any} editor An editor instance of CodeMirror
@@ -42,6 +77,18 @@ class EmojiAutoCompleteHelper {
       return;
     }
 
+    /*
+     * https://github.com/weseek/growi/issues/703 is caused
+     * because 'editor.display.viewOffset' is zero
+     *
+     * call stack:
+     *   1. https://github.com/codemirror/CodeMirror/blob/5.42.0/addon/hint/show-hint.js#L220
+     *   2. https://github.com/codemirror/CodeMirror/blob/5.42.0/src/edit/methods.js#L189
+     *   3. https://github.com/codemirror/CodeMirror/blob/5.42.0/src/measurement/position_measurement.js#L372
+     *   4. https://github.com/codemirror/CodeMirror/blob/5.42.0/src/measurement/position_measurement.js#L315
+     */
+    this.forceUpdateDisplay(editor);
+
     // see https://codemirror.net/doc/manual.html#addon_show-hint
     editor.showHint({
       completeSingle: false,