<template>
  <div class="markdown-editor">
    <mavon-editor v-model="editorValue" v-bind="getBindValue()" v-on="$listeners">
      <!-- 左工具栏前加入自定义按钮 -->
      <template slot="left-toolbar-before">
        <slot name="left-toolbar-before"></slot>
      </template>

      <!-- 左工具栏后加入自定义按钮  -->
      <template slot="left-toolbar-after">
        <slot name="left-toolbar-after"></slot>
      </template>
      <!-- 右工具栏前加入自定义按钮  -->
      <template slot="right-toolbar-before">
        <slot name="right-toolbar-before"></slot>
      </template>
      <!-- 右工具栏后加入自定义按钮  -->
      <template slot="right-toolbar-after">
        <slot name="right-toolbar-after"></slot>
      </template>
    </mavon-editor>
  </div>
</template>

<script>
import { mavonEditor } from 'mavon-editor'
import 'mavon-editor/dist/css/index.css'
import highlight from "./highlight";

/**
 * Markdown编辑器
 * - 示例
 *
 * ```vue
 * <ed-mark-editor v-model="value"></ed-mark-editor>
 * ```
 *
 * [](./EdMarkEditorProps.md ':include')
 */
export default {
  name: "EdMarkEditor",
  components: { mavonEditor },
  props: {
    // 初始值
    value: {
      type: String,
      default: ""
    },

    // 语言选择，暂支持 zh-CN: 简体中文, zh-TW: 正体中文 ， en: 英文 ， fr: 法语， pt-BR: 葡萄牙语， ru: 俄语， de: 德语， ja: 日语
    language: {
      type: String,
      default: "zh-CN"
    },

    // 编辑区域文字大小
    fonts: {
      type: [String, Number],
      default: "14px"
    },

    // 开启滚动条样式(暂时仅支持chrome)
    scrollStyle: {
      type: Boolean,
      default: true
    },

    // 开启边框阴影
    boxShadow: {
      type: Boolean,
      default: true
    },

    // 边框阴影样式
    boxShadowStyle: {
      type: String,
      default: "0 2px 12px 0 rgba(0, 0, 0, 0.1)"
    },

    // 是否开启过渡动画
    transition: {
      type: Boolean,
      default: true
    },

    // 工具栏背景颜色
    toolbarsBackground: {
      type: String,
      default: "#ffffff"
    },

    // 预览框背景颜色
    previewBackground: {
      type: String,
      default: "#fbfbfb"
    },

    // true： 双栏(编辑预览同屏)， false： 单栏(编辑预览分屏)
    subfield: {
      type: Boolean,
      default: true
    },

    // 在单栏（subfield=false）时默认展示区域.
    // edit： 默认展示编辑区域，
    // preview： 默认展示预览区域
    // 其他 = edit
    defaultOpen: {
      type: String,
    },

    // 输入框为空时默认提示文本
    placeholder: {
      type: String,
      default: "开始编辑..."
    },

    // 是否允许编辑
    editable: {
      type: Boolean,
      default: true
    },

    // markdown样式： 默认github, 可选配色方案
    codeStyle: {
      type: String,
      default: "code-github"
    },

    // 工具栏是否显示
    toolbarsFlag: {
      type: Boolean,
      default: true
    },

    // 默认展示目录
    navigation: {
      type: Boolean,
      default: false
    },

    // 是否启用快捷键
    shortCut: {
      type: Boolean,
      default: true
    },

    // 自动聚焦到文本框
    autofocus: {
      type: Boolean,
      default: true
    },

    // 代码高亮
    ishljs: {
      type: Boolean,
      default: true
    },

    // 图片过滤函数，参数为一个File Object，要求返回一个Boolean, true表示文件合法，false表示文件不合法
    imageFilter: {
      type: Function
    },

    // 图片点击事件，默认为预览，可覆盖
    imageClick: {
      type: Function
    },

    // tab转化为几个空格，默认为\t
    tabSize: {
      type: Number,
    },

    // 启用HTML标签，因为历史原因这个标记一直默认为true，但建议不使用HTML标签就关闭它，它能彻底杜绝安全问题。
    html: {
      type: Boolean,
      default: true
    },

    // 组件默认cdn外链依赖组件，如需本地化加载，请设置externalLink (false:加载本地 true:加载CDN)
    externalLink: {
      type: Boolean,
      default: true
    },

    // xss规则配置, 默认开启，设置false可以关闭，开启后会对HTML标签进行过滤，默认过滤所有HTML标签属性，建议按需配置白名单减少被攻击的可能。
    // - 自定义规则参考: https://jsxss.com/zh/options.html
    // - 参考DEMO: dev-demo
    xssOptions: {
      type: Object,
      default: () => {
      }
    },

    // 工具栏
    toolbars: {
      type: Object,
      default: () => {
        return {}
      }
    }
  },
  model: {
    prop: "value",
    event: "input"
  },
  data() {
    return {
      editorValue: this.value,
      defaultToolbars: {
        bold: true, // 粗体
        italic: true, // 斜体
        header: true, // 标题
        underline: true, // 下划线
        strikethrough: true, // 中划线
        mark: true, // 标记
        superscript: false, // 上角标
        subscript: false, // 下角标
        quote: true, // 引用
        ol: true, // 有序列表
        ul: true, // 无序列表
        link: true, // 链接
        imagelink: true, // 图片链接
        code: true, // code
        table: true, // 表格
        fullscreen: true, // 全屏编辑
        readmodel: true, // 沉浸式阅读
        htmlcode: true, // 展示html源码
        help: true, // 帮助
        /* 1.3.5 */
        undo: true, // 上一步
        redo: true, // 下一步
        trash: true, // 清空
        save: true, // 保存（触发events中的save事件）
        /* 1.4.2 */
        navigation: true, // 导航目录
        /* 2.1.8 */
        alignleft: true, // 左对齐
        aligncenter: true, // 居中
        alignright: true, // 右对齐
        /* 2.2.1 */
        subfield: true, // 单双栏模式
        preview: true, // 预览
      }
    }
  },
  computed: {
    fontSize() {
      return typeof this.fonts === 'number' ? this.fonts + 'px' : this.fonts
    }
  },
  methods: {
    /**
     * 获取绑定数据
     */
    getBindValue() {
      let props = Object.assign({},  this.$props)
      // props.fontSize = this.fontSize
      props.toolbars = Object.assign({}, this.defaultToolbars, this.toolbars)

      return props
    },

    /**
     * @name setHandleOn
     * @return {Object}
     * @description 设置事件
     */
    setHandleOn() {
      return {
        change: this.handleChange,
        save: this.handleSave,
        fullScreen: this.handleFullScreen,
        readModel: this.handleReadModel,
        htmlCode: this.handleHtmlCode,
        subfieldToggle: this.handleSubfieldToggle,
        previewToggle: this.handlePreviewToggle,
        helpToggle: this.handleHelpToggle,
        navigationToggle: this.handleNavigationToggle,
        imgAdd: this.handleImgAdd,
        imgDel: this.handleImgDel,
      }
    },

    /**
     * @name handleChange
     * @param value {String} 值
     * @param render {String} 解析后的html
     * @description 编辑区发生变化的回调事件
     */
    handleChange(value, render) {
      this.$emit('input', value)
      this.$emit("change", value, render)
    },

    /**
     * @name handleSave
     * @param value {String} 值
     * @param render {String} 解析后的html
     * @description ctrl + s 的回调事件(保存按键,同样触发该回调)
     */
    handleSave(value, render) {
      this.$emit("save", value, render)
    },

    /**
     * @name handleFullScreen
     * @param status {Boolean}
     * @param value {String}
     * @description 切换全屏编辑的回调事件(boolean: 全屏开启状态)
     */
    handleFullScreen(status, value) {
      this.$emit('fullScreen', status, value)
    },

    /**
     * @name handleReadModel
     * @param status {Boolean}
     * @param value {String}
     * @description 切换沉浸式阅读的回调事件(boolean: 阅读开启状态)
     */
    handleReadModel(status, value) {
      this.$emit('readModel', status, value)
    },

    /**
     * @name handleHtmlCode
     * @param status
     * @param value
     * @description 查看html源码的回调事件(boolean: 源码开启状态)
     */
    handleHtmlCode(status, value) {
      this.$emit('htmlCode', status, value)
    },

    /**
     * @name handleSubfieldToggle
     * @param status
     * @param value
     * @description 切换单双栏编辑的回调事件(boolean: 双栏开启状态)
     */
    handleSubfieldToggle(status, value) {
      this.$emit('subfieldToggle', status, value)
    },

    // 切换预览编辑的回调事件(boolean: 预览开启状态)
    handlePreviewToggle(status, value) {
    },
    // 查看帮助的回调事件(boolean: 帮助开启状态)
    handleHelpToggle(status, value) {
    },
    // 切换导航目录的回调事件(boolean: 导航开启状态)
    handleNavigationToggle(status, value) {
    },
    // 图片文件添加回调事件(pos: 图片在列表中的位置, File: File Object)
    handleImgAdd(pos, imgFile) {
    },
    // 图片文件删除回调事件(Array(2): 两个元素的数组，第一位是图片在列表中的位置，第二位是File对象)
    handleImgDel(files) {
    }
  }
}
</script>

<style scoped>

</style>
