Преглед изворни кода

Merge pull request #716 from weseek/fix/703-emoji-autocomplete

Fix/703 emoji autocomplete
Yuki Takei пре 7 година
родитељ
комит
dccddfdcce

+ 1 - 0
config/webpack.common.js

@@ -77,6 +77,7 @@ module.exports = (options) => {
           exclude: {
             test:    helpers.root('node_modules'),
             exclude: [  // include as a result
+              helpers.root('node_modules/codemirror/src'),
               helpers.root('node_modules/string-width'),
               helpers.root('node_modules/is-fullwidth-code-point'), // depends from string-width
             ]

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

@@ -1,3 +1,5 @@
+import UpdateDisplayUtil from '../../util/codemirror/update-display-util.ext';
+
 class EmojiAutoCompleteHelper {
 
   constructor(emojiStrategy) {
@@ -42,6 +44,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
+     */
+    UpdateDisplayUtil.forceUpdateViewOffset(editor);
+
     // see https://codemirror.net/doc/manual.html#addon_show-hint
     editor.showHint({
       completeSingle: false,

+ 41 - 0
src/client/js/util/codemirror/update-display-util.ext.js

@@ -0,0 +1,41 @@
+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 UpdateDisplayUtil {
+
+  /**
+   * 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
+   */
+  static forceUpdateViewOffset(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));
+  }
+
+}
+
+
+export default UpdateDisplayUtil;