给 wangEditor v4 写个源码编辑扩展

2,193 阅读2分钟

前言

wangEditor v4 发布已经几个月了,这期间有同学提出源码编辑的功能,但是 wang 的作者最近回复,由于各种考量,暂时不支持这个功能(#2299)。因此我尝试着将这个功能写成一个扩展库,然后我们来看下效果:

源码编辑是依赖 Monaco Editor 实现的

一:方案选择

1、通过 webpack 将扩展菜单的代码和 monaco 一起打包

弃用。想法很美好,奈何打包失败。

2、iframe + postMessage + monaco

弃用。postMessage通信耗时太长,体验差。

3、iframe + moanco

直接将 monaco 实例挂载在 iframe 的 window 对象上,然后在父窗口直接拿取到该实例进行操作

二:实现思路

1、通过 require + CDN 的形式,写一个 Monaco Editor 的简单示例

这段代码将通过 document.write api 写入 iframe 文档中

monaco editor 的案例请见 monaco-editor-samples

2、扩展 wangEditor 菜单

在扩展菜单初始化时我们需要完成以下操作

  1. 将 iframe 添加到编辑器的编辑区容器中
  2. 初始化 保存/退出 的控制器
  3. 绑定 drop list(本菜单基于 BtnMenu + dropList 实现)

扩展菜单的代码

2.1、将 iframe 添加到编辑器的编辑区容器中

2.2、初始化 保存/退出 的控制器

这段静态HTML改自最开始的 Monaco Editor 示例

值得注意的是,monaco 的加载是在初次打开源码编辑功能时,这样的好处是避免不必要的资源加载,缺点是首次使用源码功能会有一定的迟钝感。

并且加载成功后对控制器的 open 方法进行了重写,这样可以去掉不必要的判断(判断 monaco 是否已初始化)。

控制器:打开 Monaco 编辑器

控制器:保存数据

控制器:退出源码编辑状态

控制器:完整代码

2.3、绑定自定义 dropList

由于此扩展菜单的特殊性,无法单独使用 BtnMenuDropListMenu 实现,我这里采用了 BtnMenu + DropList 的形式进行实现的。

这也意味着我需要对 BtnMenu 进行一些特殊改造来实现在源码编辑器打开状态下,dropList 悬浮才进行显示的效果。

BtnMenu 和 DropListMenu 底层源码对比图。更多详情请看项目源码

自定义 dropList 的最终实现

三:完整的代码地址

github.com/clinfc/wang…