All files / src BaseMarkdownWidget.vue.js

88% Statements 22/25
64.28% Branches 9/14
100% Functions 11/11
90.9% Lines 20/22

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114                                  1x                                   3x                                           4x 3x             2x 2x 2x   2x         2x             7x       3x 1x 1x   1x   3x 3x         1x     1x       1x       2x          
// @ts-check
import { invoke, isEmpty, isNil, toString } from "lodash";
 
import AnimGroup from "./BaseAnimation/BaseAnimationGroup.vue";
import CodeMirrorEditor from "./plugins/CodeMirrorEditor.vue";
import MarkdownViewer from "./plugins/MarkdownViewer.vue";
import BaseRibbon from "./BaseRibbon.vue";
import BaseKeyboardEventMixin from "./mixins/BaseKeyboardEventMixin";
import Vue from "vue";
 
/**
 * @typedef {{
 *  cmEditor: V.Instance<typeof CodeMirrorEditor>
 * }} Refs
 */
 
 
const component = /** @type {V.Constructor<any, Refs>} */ (Vue).extend({
  name: "BaseMarkdownWidget",
  components: { CodeMirrorEditor, MarkdownViewer, BaseRibbon, AnimGroup },
  mixins: [ BaseKeyboardEventMixin({ local: true }) ],
  props: {
    value: { type: [ String ], default: "" },
    inEdit: { type: Boolean, default: false },
    maxLength: { type: Number, default: -1 }
  },
  /**
   * @returns {{
   *   editValue: string | null,
   *   showPreview: boolean,
   *   cmOptions: any,
   *   mdOptions: any
   * }}
   */
  data() {
    return {
      editValue: "",
      showPreview: false,
      cmOptions: {
        mode: "markdown",
        lineNumbers: true,
        line: true,
        tabSize: 2
      },
      mdOptions: {
        html: true,
        linkify: true,
        typographer: true
      }
    };
  },
  watch: {
    /**
     * @param {string|null} v
     * @param {string|null} old
     */
    value(v /*: ?(string) */, old /*: ?(string) */) {
      if (isEmpty(this.editValue) || (this.editValue === toString(old))) {
        this.editValue = toString(v);
      }
    },
    /**
     * @param {boolean} v
     */
    inEdit(v /*: boolean */) {
      Eif (v) {
        const editValue = toString(this.value);
        if (editValue === this.editValue) {
          // Force emit the event when we enter edit mode
          this.$emit("edit", this.editValue);
        }
        else E{
          this.editValue = editValue; /* clear old editValue when entering edit */
        }
        this.refreshEditor();
      }
    },
    /**
     * @return {void}
    */
    editValue: function() {
      this.$emit("edit", this.editValue);
    }
  },
  mounted() {
    this.onKey("ctrl-enter-keydown", () => {
      Iif (!this.inEdit) { return; }
      this.togglePreview();
      // Manage Focus
      this.$nextTick(() => this.focus());
    });
    Eif (!isNil(this.value)) {
      this.editValue = toString(this.value);
    }
  },
  methods: {
    togglePreview() {
      this.showPreview = !this.showPreview;
    },
    focus() {
      Iif (this.showPreview) {
        invoke(this, [ "$el", "focus" ]);
      }
      else {
        invoke(this, [ "$refs", "cmEditor", "focus" ]);
      }
    },
    refreshEditor() {
      this.$nextTick(() => invoke(this, [ "$refs", "cmEditor", "refresh" ]));
    }
  }
});
export default component;