<template>
  <div class="el-CEditor"><div id="div1" ref="editor"></div></div>
</template>

<script>
import i18next from 'i18next';
import MapLoader from './loadEditor';
MapLoader().then(()=>{
});
export default {
  name: 'cc-editor',
  props: {
    settings: {
      type: Object,
      default: {}
    }
  },
  data() {
    return {
      a: null,
      AlertMenu: '',
      HeadMenu: '',
      E: window.wangEditor,
      editorContent: ''
    };
  },
  mounted() {
    this.init();
  },
  methods: {
    // 添加菜单
    menuBtn(name = '自定义按钮') {
      let that = this;
      // 配置菜单
      return (this.AlertMenu = class AlertMenu extends window.wangEditor.BtnMenu {
        constructor(editor) {
          // data-title属性表示当鼠标悬停在该按钮上时提示该按钮的功能简述
          const $elem = window.wangEditor.$(
            `<div class="w-e-menu" data-title=${name}>
                <span style="font-size:10px">${name}</span>
            </div>`
          );
          super($elem, editor);
        }
        // 菜单点击事件
        clickHandler() {
          // 做任何你想做的事情
          // 可参考【常用 API】文档，来操作编辑器
          that.$emit('customDialog');
          // alert('hello world')
        }
        // 菜单是否被激活（如果不需要，这个函数可以空着）
        // 1. 激活是什么？光标放在一段加粗、下划线的文本时，菜单栏里的 B 和 U 被激活，如下图
        // 2. 什么时候执行这个函数？每次编辑器区域的选区变化（如鼠标操作、键盘操作等），都会触发各个菜单的 tryChangeActive 函数，重新计算菜单的激活状态
        tryChangeActive() {
          // 激活菜单
          // 1. 菜单 DOM 节点会增加一个 .w-e-active 的 css class
          // 2. this.this.isActive === true
          // // 取消激活菜单
          // // 1. 菜单 DOM 节点会删掉 .w-e-active
          // // 2. this.this.isActive === false
          // this.unActive()
        }
      });
    },
    head() {
      return (this.HeadMenu = class Head extends window.wangEditor.DropListMenu {
        constructor(editor) {
          // 菜单栏中，标题菜单的 DOM 元素
          // 注意，这里的 $ 不是 jQuery ，是 E.$ （wangEditor 自带的 DOM 操作工具，类似于 jQuery）
          // data-title属性表示当鼠标悬停在该按钮上时提示该按钮的功能简述
          const $elem = window.wangEditor.$(
            '<div class="w-e-menu" data-title="标题"><i >DropListMenu</i></div>'
          );

          // droplist 配置
          const dropListConf = {
            width: 100,
            title: '设置标题',
            type: 'list',
            list: [
              { $elem: window.wangEditor.$('<h1>H1</h1>'), value: '<h1>' },
              { $elem: window.wangEditor.$('<h2>H2</h2>'), value: '<h2>' },
              { $elem: window.wangEditor.$('<h3>H3</h3>'), value: '<h3>' },
              { $elem: window.wangEditor.$('<h4>H4</h4>'), value: '<h4>' },
              { $elem: window.wangEditor.$('<h5>H5</h5>'), value: '<h5>' },
              { $elem: window.wangEditor.$('<p>正文</p>'), value: '<p>'}
            ],
            // droplist 每个 item 的点击事件
            clickHandler: (value) => {
              // value 参数即 dropListConf.list 中配置的 value
              this.command(value);
            }
          };

          super($elem, editor, dropListConf);
        }

        command(value) {
          // 设置标题
          this.editor.cmd.do('formatBlock', value);
        }

        // 菜单是否需要激活
        tryChangeActive() {
          const reg = /^h/i;
          const cmdValue = this.editor.cmd.queryCommandValue('formatBlock');
          if (reg.test(cmdValue)) {
            // 选区处于标题内，激活菜单
            this.active();
          } else {
            // 否则，取消激活
            this.unActive();
          }
        }
      });
    },
    init(setting = this.settings) {
    // 初始化
      let that = this;
      this.a = new this.E(this.$refs.editor);
      // 选择语言
      if (setting.lang === 'zh') {
        this.a.config.lang = 'zh-CN';
      } else {
      // 其他情况展示英文
        this.a.config.lang = 'en';
      }
      // 引入 i18next 插件
      this.a.i18next = i18next;
      if (setting.newBtname) {
        var menuKey = 'alertMenuKey';
      }
      // const menuHead = "alertMenuHead";
      // const menuPanel = "alertMenuPanel";
      // 注册菜单
      this.a.menus.extend(menuKey, this.menuBtn(setting.newBtname));
      // this.a.menus.extend(menuHead, setting.ccalertmenuhead);
      // this.a.menus.extend(menuPanel, setting.ccalertmenupanel);
      this.a.config.menus = setting.menusList
        ? setting.menusList
        : [
          'head', // 标题
          'bold', // 粗体
          'fontSize', // 字号
          'fontName', // 字体
          'italic', // 斜体
          'underline', // 下划线
          'strikeThrough', // 删除线
          'indent', // 缩进
          'lineHeight', // 行高
          'foreColor', // 文字颜色
          'backColor', // 背景颜色
          'link', // 插入链接
          'list', // 列表
          'todo', // 代码
          'justify', // 对齐方式
          'quote', // 引用
          'emoticon', // 表情
          'image', // 插入图片
          'video', // 插入视频
          'table', // 表格
          'code', // 插入代码
          'splitLine', // 分割线
          'undo', // 撤销
          'redo' // 重复
        ];
      if (menuKey) {
        this.a.config.menus.push('alertMenuKey');
      }
      // 配置 onchange 回调函数
      this.a.config.onchange = () => {
        that.editorContent = this.a.txt.html();
      };

      // 配置 onSelectionChange 回调函数
      this.a.config.onSelectionChange = function(newSelection) {
        console.log('onSelectionChange', newSelection);
        /**
              {
                 text:'wangeditor', // 当前选择文本
                 html: '<p>wangeditor</p>', // 当前选中的html
                 selection: selection, // 原生selection对象
              }
             */
      };

      // 自定义上传图片
      this.a.config.customUploadImg = function(resultFiles, insertImgFn) {
        // resultFiles 是 input 中选中的文件列表
        // insertImgFn 是获取图片 url 后，插入到编辑器的方法
        let formData = new FormData();
        formData.append('file', resultFiles[0]);
        // formData.append("fileName", resultFiles[0].name);
        that.$emit('uploadImg', formData, insertImgFn);
        //   if (res.data) {
        //     // 上传图片，返回结果，将图片插入到编辑器中.upload
        // insertImgFn();
        //   }
      };

      // 插入网络图片的回调
      this.a.config.linkImgCallback = function(src, alt, href) {
        console.log('图片 src ', src);
        console.log('图片文字说明', alt);
        console.log('跳转链接', href);
      };
      // 自定义上传视频(传参进来来进行判断是否展示本地上传)
      // this.a.config.customUploadVideo = function (resultFiles, insertVideoFn) {
      //   // resultFiles 是 input 中选中的文件列表
      //   // insertVideoFn 是获取视频 url 后，插入到编辑器的方法
      //   that.$emit('uploadVideo', formData, insertImgFn)
      //   // 上传视频，返回结果，将视频地址插入到编辑器中
      //   // insertVideoFn(videoUrl)
      // };

      // 自定义检查插入视频的回调
      this.a.config.onlineVideoCallback = function(video) {
        // 自定义回调内容，内容成功插入后会执行该函数
        console.log('插入视频内容', video);
      };

      // // 自定义检查插入视频的回调
      this.a.config.onlineVideoCallback = function(video) {
        // 自定义回调内容，内容成功插入后会执行该函数
        console.log('插入视频内容', video);
      };

      // 自定义检查插入的链接
      this.a.config.linkCheck = function(text, link) {
        // 以下情况，请三选一
        // 1. 返回 true ，说明检查通过
        return true;
        // // 2. 返回一个字符串，说明检查未通过，编辑器会阻止链接插入。会 alert 出错误信息（即返回的字符串）
        // return '链接有 xxx 错误'
        // 3. 返回 undefined（即没有任何返回），说明检查未通过，编辑器会阻止链接插入。
        // 此处，你可以自定义提示错误信息，自由发挥
      };

      // 自定义检查插入图片的链接
      // 参数中的imgSrc、alt、href分别代表图片地址、图片文本说明和跳转链接
      // 后面两个参数是可选参数
      this.a.config.linkImgCheck = function(imgSrc, alt, href) {
        // 以下情况，请三选一
        // 1. 返回 true ，说明检查通过
        return true;
        // // 2. 返回一个字符串，说明检查未通过，编辑器会阻止图片插入。会 alert 出错误信息（即返回的字符串）
        // return '图片 src 有 xxx 错误'
        // 3. 返回 undefined（即没有任何返回），说明检查未通过，编辑器会阻止图片插入。
        // 此处，你可以自定义提示错误信息，自由发挥
      };

      // 自定义检查插入视频的链接
      this.a.config.onlineVideoCheck = function(video) {
        // 编辑器会根据返回的内容做校验：比如以下几种情况
        // 1. 返回 true ，说明检查通过
        return true;
        // 2. 返回一个字符串，说明检查未通过，编辑器会阻止视频插入。会 alert 出错误信息（即返回的字符串）
        // return '插入的视频 有 xxx 错误'
        // 3. 返回 undefined（即没有任何返回），说明检查未通过，编辑器会阻止视频插入。
        // 此处，你可以自定义提示错误信息，自由发挥
      };

      // 配置粘贴文本的内容处理(不适用于 IE11)
      this.a.config.pasteTextHandle = function(pasteStr) {
        // 对粘贴的文本进行处理，然后返回处理后的结果
        return pasteStr;
      };

      // 编辑区域 focus（聚焦）时触发的回调函数
      this.a.config.onblur = function(newHtml) {
        console.log('onblur', newHtml); // 获取最新的 html 内容
      };

      // 编辑区域blur（失焦）时触发的回调函数
      this.a.config.onfocus = function(newHtml) {
        console.log('onfocus', newHtml); // 获取最新的 html 内容
      };
      // 使用回调函数，对上传图片的不同阶段，做相应处理
      this.a.config.uploadImgHooks = {
        // 上传图片之前
        before: function(xhr) {
          console.log(xhr);

          // 可阻止图片上传
          return {
            prevent: true,
            msg: '需要提示给用户的错误信息'
          };
        },
        // 图片上传并返回了结果，图片插入已成功
        success: function(xhr) {
          console.log('success', xhr);
        },
        // 图片上传并返回了结果，但图片插入时出错了
        fail: function(xhr, editor, resData) {
          console.log('fail', resData);
        },
        // 上传图片出错，一般为 http 请求的错误
        error: function(xhr, editor, resData) {
          console.log('error', xhr, resData);
        },
        // 上传图片超时
        timeout: function(xhr) {
          console.log('timeout');
        },
        // 图片上传并返回了结果，想要自己把图片插入到编辑器中
        // 例如服务器端返回的不是 { errno: 0, data: [...] } 这种格式，可使用 customInsert
        customInsert: function(insertImgFn, result) {
          // result 即服务端返回的接口
          console.log('customInsert', result);

          // insertImgFn 可把图片插入到编辑器，传入图片 src ，执行函数即可
          insertImgFn(result.data[0]);
        }
      };

      // 配置颜色（文字颜色、背景色）
      this.a.config.colors = setting.colors
        ? setting.colors
        : [
          '#000000',
          '#eeece0',
          '#1c487f',
          '#4d80bf',
          '#c24f4a',
          '#8baa4a',
          '#7b5ba1',
          '#46acc8',
          '#f9963b',
          '#ffffff'
        ];

      // 配置字体
      this.a.config.fontNames = setting.fontNames
        ? setting.fontNames
        : [
          '黑体',
          '仿宋',
          '楷体',
          '标楷体',
          '华文仿宋',
          '华文楷体',
          '宋体',
          '微软雅黑',
          'Arial',
          'Tahoma',
          'Verdana',
          'Times New Roman',
          'Courier New'
        ];
      this.a.config.fontSizes = {
        'x-small': { name: '10px', value: '1' },
        small: { name: '13px', value: '2' },
        normal: { name: '16px', value: '3' },
        large: { name: '18px', value: '4' },
        'x-large': { name: '24px', value: '5' },
        'xx-large': { name: '32px', value: '6' },
        'xxx-large': { name: '48px', value: '7' }
      };
      // 配置行高
      this.a.config.lineHeights = ['1', '1.15', '1.6', '2', '2.5', '3'];
      // 是否展示全屏功能按钮（不支持工具栏和编辑区域分离的情况）
      this.a.config.showFullScreen = setting.showFullScreen ? setting.showFullScreen : true;
      this.a.config.height = setting.height ? setting.height : 300;
      // 取消自动 focus
      this.a.config.focus = setting.focus ? setting.focus : false;
      this.a.config.placeholder = setting.placeholder ? setting.placeholder : '';
      this.a.config.uploadImgMaxSize = 2 * 1024 * 1024; // 将图片大小限制为 2M
      this.a.config.uploadImgMaxLength = 6; // 限制一次最多上传 6 张图片
      this.a.config.uploadImgTimeout = 3 * 60 * 1000; // 设置超时时间
      // 限制图片类型(空数组不限制类型)
      this.a.config.uploadImgAccept = [];
      // 配置 server 接口地址
      // this.a.config.uploadImgServer = '/upload-img'
      // 关闭粘贴样式的过滤
      // this.a.config.pasteFilterStyle = false;
      // 隐藏插入网络图片的功能
      this.a.config.showLinkImg = false;
      // 网络图片设置alt和跳转链接
      // 配置alt选项
      // this.a.config.showLinkImgAlt = false;
      // 配置超链接
      // this.a.config.showLinkImgHref = false;
      // this.a.config.showLinkVideo = true
      // 忽略粘贴内容中的图片(不适用于 IE11)
      // this.a.config.pasteIgnoreImg = true;
      // 限制视频大小
      this.a.config.uploadVideoMaxSize = 1 * 1024 * 1024 * 1024; // 1024m
      // 限制视频类型
      this.a.config.uploadVideoAccept = ['mp4'];
      this.a.config.zIndex = 1;
      // 隐藏菜单栏提示
      // this.a.config.showMenuTooltips = false
      this.a.create();
    },
    // 清空副文本编辑器的值
    clearvalue() {
      this.a.txt.clear();
    },
    // 富文本回显
    signContent(val) {
      let div = `<div>${val}</div>`;
      this.a.txt.append(div);
    },
    // 邮件回复模板
    wangEditorese(val) {
      this.a.txt && this.a.txt.append(val);
    }
  },
  watch: {
    editorContent(val) {
      this.$emit('editorContent', val);
    }
  }
};
</script>
