如何让富文本编辑器tinymce支持视频上传功能并能预览?

328 阅读2分钟

背景:

突然某一天,领导说给编辑器增加一个上传视频的功能,较劲脑汁想办法去实现。项目是若依框架,自带的编辑器当然是不满足,只能先换个编辑器,于是选择了坑相对来说比较少的tinymce,查阅资料后终于完成需求开发。

关于插件版本

  • "vue": "2.6.12",
  • "tinymce": "5.1.0",
  • "@tinymce/tinymce-vue": "3.0.1"

tinymce.vue组件完整代码

页面引用

javascript

import tinymce from "@/components/Editor/tinymce";

components: { ClassicEditor, tinymce, ExamQuestionDialog }

template

<tinymce ref="tinymceEditor" :value="form.noticeContent" @input="setEditorHtml" :key="tinymceKey"></tinymce>

上传完视频预览需要修改源码

需要修改node_modules/tinymce/plugins/media/plugin.js文件

1.找到createPreviewIframeNode方法,直接修改:

  var createPreviewIframeNode = function (editor, node) {
    var previewWrapper;
    var previewNode;
    var shimNode;
    var name = node.name;
    previewWrapper = new global$7('span', 1);
    previewWrapper.attr({
      'contentEditable': 'false',
      'style': node.attr('style'),
      'data-mce-object': name,
      'class': 'mce-preview-object mce-object-' + name
    });
    retainAttributesAndInnerHtml(editor, node, previewWrapper);
    previewNode = new global$7(name, 1);
    previewNode.attr({
      src: videoSource || node.attr('src'), // 修改
      controls: 'controls',    // 新增
      allowfullscreen: node.attr('allowfullscreen'),
      style: node.attr('style'),
      class: node.attr('class'),
      width: node.attr('width'),
      height: node.attr('height'),
      frameborder: '0'
    });
    shimNode = new global$7('span', 1);
    shimNode.attr('class', 'mce-shim');
    previewWrapper.append(previewNode);
    previewWrapper.append(shimNode);
    return previewWrapper;
  };

2.找到placeHolderConverter方法

注释掉:

// if (node.name === 'iframe' && Settings.hasLiveEmbeds(editor) && global$8.ceFalse) {
//   if (!isWithinEmbedWrapper(node)) {
//     node.replace(createPreviewIframeNode(editor, node));
//   }
// } else {
//   if (!isWithinEmbedWrapper(node)) {
//     node.replace(createPlaceholderNode(editor, node));
//   }
// }

增加:

if (node.name === 'video' && hasLiveEmbeds(editor) && global$8.ceFalse) {
  videoSource = ''
  if (node.attributes['map'] && node.attributes['map'].src) {
    videoSource = node.attributes['map'].src
  } else {
    for (var ii = 0; ii < node.attributes.length; ii++) {
      if (node.attributes[ii].name == "src") {
        videoSource = node.map.node.attributes[ii].value
      }
    }
  }
  if (node.firstChild && node.firstChild.value) {
    var elel = node.firstChild && node.firstChild.value
    var objE = document.createElement("div");
    objE.innerHTML = elel;
    var dom = objE.getElementsByTagName('source')[0]
    videoSource = dom.getAttribute('src')
  }
  node.replace(createPreviewIframeNode(editor, node));
}

重要:

一顿操作完发现本地可以使用了,但是问题来了,当安装新的依赖后发现修改的源码被还原了,怎么办?
不要慌,这个时候就需要引入一个插件来帮忙:

"patch-package": "^8.0.0"

安装完成之后,修改好tinymec源码。以及修改node_modules其他第三方库后,需要执行patch-package打补丁。

1.为解决问题:修改node_modules下的包代码后,下次运行npm install或yarn add后会被覆盖修改的文件

2.步骤A:npx patch-package '包名'

3.步骤B:package.json中添加postinstall脚本:

"scripts": {
   "postinstall": "patch-package"
}

4.这样每次运行npm install或yarn add后,都会自动应用你修改后的补丁

本文参考文档:

1.【前端】vue引入tinymce富文本编辑器上传视频自动转img问题

2.优雅修改第三方库