魔改 Simditor 编辑器,增强自定义上传

2018-07-13 今天得空,就来梳理下这个东东。

这个现场情况是这样的:

  • 需要将附件通过web直传到Aliyun-OSS
  • web-client upload file -> Aliyun-OSS Server -> response file-token -> web-client upload file-token to private-server -> response source-url -> web-client preview
  • 这个需求,就必须得自行编写个Simditor-upload插件了

  • Simditor-upload插件 : simditor-http-upload.js
  • Simditor配置:simditor.config.js

simditor-http-upload.js

/* eslint-disable */
import $ from 'jquery'
import Simditor from 'simditor'

const inputAttribute = {
  accept: 'image/gif,image/jpeg,image/jpg,image/png,image/svg',
  multiple: false
}

class HttpUploadButton extends Simditor.Button {
  constructor(...args) {
    super(...args)
    this.i18n = {
      'zh-CN': {
        httpupload: '上传文件'
      },
      'en-US': {
        httpupload: 'upload file'
      }
    }
    this.init()
  }

  init() {
    const {
      httpUpload
    } = this.editor.opts
    if (!httpUpload && !httpUpload.bindUpload) {
      throw new Error('upload httpUpload must config httpUpload.')
    }

    this.input = $('', {
      type: 'file',
      class: 'plugin-http-upload',
      accept: inputAttribute.accept,
      multiple: inputAttribute.multiple,
      style: 'position:absolute;top:0;right:0;opacity:0;filter:alpha(opacity=0);cursor:pointer;'
    }).prependTo(this.editor.el)

    this.editor.el.on('click mouseup', '.toolbar-item-httpupload', (e) => {
      if (!this.editor.selection.range()) {
        console.warn('current not is focus.')
        httpUpload.error('请点击编辑区域,然后上传')
        return undefined
      }
      this.$rootNodes = this.editor.selection.blockNodes()
      this.editor.selection.save()
      this.input.trigger('click')
      e.stopPropagation()
    })
    this.editor.el.on('change', '.plugin-http-upload', () => {
      httpUpload.bindUpload(this.input, (data) => {
        this.input.val('')
        if (['', null, undefined].indexOf(data) === -1) {
          let $insert = ''
          if (Array.isArray(data)) {
            const imgs = data.map(link => ``)
            $insert = $(`${imgs.join('')}`)
          } else if (typeof data === 'string') {
            $insert = /^http/.test(data) ? $(``) : $(`${data}`)
          }
          this.editor.selection.restore()
          this.editor.selection.insertNode($insert)
        }
        this.editor.trigger('valuechanged')
        this.editor.trigger('selectionchanged')
      })
    })
  }
}
HttpUploadButton.prototype.type = 'ul.simditor-uploadfile'
HttpUploadButton.prototype.name = 'httpupload'
// HttpUploadButton.prototype.icon = 'upload'
HttpUploadButton.prototype.icon = 'picture-o'

export default (option = {}) => {
  Object.assign(inputAttribute, option)
  Simditor.Toolbar.addButton(HttpUploadButton)
}


simditor.config.js

/* eslint-disable */
import { Toast } from 'mint-ui'
import Simditor from 'simditor'
import SimditorHttpUpload from './simditor-http-upload'

class SimditorConfig {
  constructor(context, el) {
    // 组件环境
    this.context = context
    // 编辑器实例
    this.instance = this.init(el)
  }

  init(el) {
    SimditorHttpUpload({
      accept: 'image/jpeg,image/jpg,image/png'
    })
    return new Simditor({
      textarea: document.querySelector(el),
      toolbar: ['bold', 'italic', '|', 'httpupload'],
      placeholder: '请输入正文',
      toolbarFloat: true,
      toolbarFloatOffset: 0,
      pasteImage: false,
      httpUpload: {
        bindUpload: this.bindAttachUpload.bind(this),
        error: (err) => {
          console.warn(`httpUpload Error: ${err}`)
          Toast(err)
        }
      }
    })
  }

  // 绑定上传
  bindAttachUpload(uploadInput, callback) {
    if (callback) {
      this.handleUpload(uploadInput[0].files)
        .then((list) => {
          callback(list)
        })
        .catch(err => console.warn(err))
    }
  }

  // 销毁
  destroy() {
    this.instance.destroy()
  }

  // 真实上传
  handleUpload(files) {
    return new Promise((resolve, reject) => {
      if (this.context.httpUpload) {
        this.context.httpUpload({
          files,
          success: (list) => {
            resolve(list)
          }
        })
      } else {
        reject('not found methods: httpUpload.')
        throw new Error(`${this.context} not found methods: httpUpload.`)
      }
    })
  }
}

export default SimditorConfig


使用

Index.vue

import SimditorConfig from './simditor.config'

export default {
  name: 'RichText',
  mounted() {
    this.$nextTick(() => {
      this.editor = new SimditorConfig(this, '#editor')
    })
  },
  methods: {
    // 三方上传
    httpUpload({ files, success } = {}) {
      if (!this.oss) {
        this.$topTips('关键信息初始化失败,请刷新重试')
        return undefined
      }

      const upload = (fileList) => {
        fileList.forEach((file) => {
          file.progress = (p) => {
            this.progress = p * 100
          }
        })
        this.handleUploadFileMultiple({ files: fileList })
          .then((response) => {
            const imgs = response.map(obj => obj.url)
            success(imgs)
          })
          .catch((err) => {
            console.error(err)
          })
      }
      upload([...files])
    }
  }
}

你可能感兴趣的:(魔改 Simditor 编辑器,增强自定义上传)