前言
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.writeapi 写入 iframe 文档中
monaco editor 的案例请见 monaco-editor-samples
2、扩展 wangEditor 菜单
在扩展菜单初始化时我们需要完成以下操作
- 将 iframe 添加到编辑器的编辑区容器中
- 初始化 保存/退出 的控制器
- 绑定 drop list(本菜单基于 BtnMenu + dropList 实现)
扩展菜单的代码
2.1、将 iframe 添加到编辑器的编辑区容器中
2.2、初始化 保存/退出 的控制器
这段静态HTML改自最开始的 Monaco Editor 示例
值得注意的是,monaco 的加载是在初次打开源码编辑功能时,这样的好处是避免不必要的资源加载,缺点是首次使用源码功能会有一定的迟钝感。
并且加载成功后对控制器的 open 方法进行了重写,这样可以去掉不必要的判断(判断 monaco 是否已初始化)。
控制器:打开 Monaco 编辑器
控制器:保存数据
控制器:退出源码编辑状态
控制器:完整代码
2.3、绑定自定义 dropList
由于此扩展菜单的特殊性,无法单独使用 BtnMenu 或 DropListMenu 实现,我这里采用了 BtnMenu + DropList 的形式进行实现的。
这也意味着我需要对 BtnMenu 进行一些特殊改造来实现在源码编辑器打开状态下,dropList 悬浮才进行显示的效果。
BtnMenu 和 DropListMenu 底层源码对比图。更多详情请看项目源码
自定义 dropList 的最终实现