UEditor 是由百度「FEX前端研发团队」开发的所见即所得富文本 web 编辑器,具有轻量,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码。这里贴上该项目在 Github 上的链接地址: https://github.com/fex-team/ueditor
虽然说 UEditor 是 6 年前的老项目了,但是放在今天来看在 PC 端能比 UEditor 更加优秀的编辑器确实没有几个。广大前端程序员朋友对该编辑器也是喜爱有加,唯一的不足就是官方团队现在对该项目基本上处于停止维护的状态。其中一些插件及功能显得有点过时。现在,我们就来将其默认的代码高亮插件 SyntaxHighlighter 修改成时下非常流行并且用户众多的 highlight.js。
首先,我们需要下载 UEditor 的项目源码至本地计算机:
您可以手动下载或使用 git 命令克隆项目至本地,本文示例代码基于 UEditor dev-1.5.0
版本进行修改
git clone https://github.com/fex-team/ueditor.git // 克隆项目
npm install // 安装项目依赖
grunt default // 按照默认设置进行打包,打包完成后最终代码在 /dist/ 目录下
下面是 UEditor 项目的源码包目录结构:
├── /_example/ ueditor 的使用演示及示例
├── /_parse/ ueditor.parse.js 的源码
├── /_src/ ueditor.all.js 的源码
├── /_test/ 测试目录
├── /dialogs/ 弹出对话框对应的资源和JS文件
├── /lang/ 编辑器国际化语言包
├── /themes/ 主题样式和相关图片文件
├── /third-party/ 第三方插件(包括代码高亮,源码编辑等组件)
├── /.editorconfig
├── /.gitignore
├── /Gruntfile.js
├── /ISSUE_TEMPLATE.md
├── /LICENSE
├── /README.md
├── /changelog.md
├── /package.json
├── /ueditor.config.js
├── /ueditor.parse.js
下载 highlight.js 代码高亮插件
插件下载地址:https://highlightjs.org/
下载完成后,将 highlight.js 放置在 UEditor 源码目录的 /third-party/ 目录下。
两款插件的结构区别
UEditor 默认代码高亮插件结构如下:
<pre class="brush:javascript;toolbar:false;">
// 这里是 javascript 代码
</pre>
highlight.js 高亮插件要求的结构如下:
<pre>
<code class="javascript">
// 这里是 javascript 代码
</code>
</pre>
下面我们来正式开始修改:
第一步,打开 /_src/plugins/insertcode.js 文件
1、将第 16 行 me.setOpt("insertcode", { ... })
这里修改为 highlight.js 高亮插件支持的语言,设置示例:
me.setOpt("insertcode", {
Apache: "Apache",
Bash: "Bash",
CSharp: "C#",
Cpp: "C++",
CSS: "CSS",
HTML: "HTML, XML",
HTTP: "HTTP",
Ini: "Ini, TOML",
JSON: "JSON",
Java: "Java",
JavaScript: "JavaScript",
Makefile: "Makefile",
Markdown: "Markdown",
Nginx: "Nginx",
"Objective-C": "Objective-C",
PHP: "PHP",
Perl: "Perl",
Python: "Python",
Ruby: "Ruby",
SQL: "SQL",
Shell: "Shell",
Session: "Session"
});
2、源码第 71 行,将 pre 改为 code (注意:是源码源文件第 71 行,请复制一份对照源码文件进行修改
)
pre = domUtils.findParentByTagName(rng.startContainer, "pre", true);
改为
pre = domUtils.findParentByTagName(rng.startContainer, "code", true);
3、源码第 73 行的代码进行修改
if (pre) {
pre.className = "brush:" + lang + ";toolbar:false;";
}
改为
if (pre) {
pre.className = lang;
}
4、源码第 157 - 165 行进行修改
me.execCommand(
"inserthtml",
'<pre id="coder"class="brush:' +
lang +
';toolbar:false">' +
code +
"</pre>",
true
);
改为
me.execCommand(
"inserthtml",
'<pre><code id="coder" class="' + lang + '">' + code + "</code></pre>",
true
);
5、源码第 193 - 197 行进行修改
if (node.nodeName == "PRE") {
var match = node.className.match(/brush:([^;]+)/);
lang = match && match[1] ? match[1] : "";
return false;
}
改为
if (node.nodeName == "CODE") {
lang = node.className;
return false;
}
6、源码第 204 行进行修改
utils.each(root.getNodesByTagName("pre"), function(pre) {
改为
utils.each(root.getNodesByTagName("code"), function(pre) {
7、源码第 229 行需要做同样的修改
utils.each(root.getNodesByTagName("pre"), function(pre) {
改为
utils.each(root.getNodesByTagName("code"), function(pre) {
8、源码第 280 行
var pre = domUtils.findParentByTagName(rng.startContainer, "pre", true);
改为
var pre = domUtils.findParentByTagName(rng.startContainer, "code", true);
9、源码第 406 行
var pre = domUtils.findParentByTagName(rng.startContainer, "pre", true);
改为
var pre = domUtils.findParentByTagName(rng.startContainer, "code", true);
10、源码第 471 行
pre = domUtils.findParentByTagName(rng.startContainer, "pre", true);
改为
pre = domUtils.findParentByTagName(rng.startContainer, "code", true);
11、源码第 575 行
if (
rng.collapsed &&
(pre = domUtils.findParentByTagName(rng.startContainer, "pre", true)) &&
!pre.nextSibling
) {
改为
if (
rng.collapsed &&
(pre = domUtils.findParentByTagName(rng.startContainer, "code", true)) &&
!pre.nextSibling
) {
12、源码第 599 行
if (
domUtils.isTagNode(start, "pre") &&
rng.collapsed &&
domUtils.isStartInblock(rng)
) {
改为
if (
domUtils.isTagNode(start, "code") &&
rng.collapsed &&
domUtils.isStartInblock(rng)
) {
第二步,打开 /_src/plugins/source.js 文件
源码第 180 行
case "pre":
node.innerText(node.innerText().replace(/ /g, " "));
改为
case "code":
node.innerText(node.innerText().replace(/ /g, " "));
至此 UEditor 编辑器部分修改完成,下面是查看预览的部分。
第三步,打开 /_parse/insertcode.js 进行修改。该文件主要负责动态引入 highlight.js 的样式及脚本文件,并且执行代码高亮
此文件由于代码量非常少,所以直接贴上修改后的代码。代码中的 jsurl 与 cssurl 变量对应 UEditor 源码目录下 /third-party/ 里面 highlight.js 的路径
UE.parse.register("insertcode", function(utils) {
var pres = this.root.getElementsByTagName("pre");
if (pres.length) {
var jsurl, cssurl;
if (this.rootPath !== undefined) {
jsurl = utils.removeLastbs(this.rootPath) + "/third-party/highlight/highlight.pack.js"; // 高亮脚本
cssurl = utils.removeLastbs(this.rootPath) + "/third-party/highlight/styles/a11y-dark.css"; // 样式文件,这里可以修改成自己喜欢的主题样式
} else {
jsurl = this.highlightJsUrl;
cssurl = this.highlightCssUrl;
}
utils.loadFile(document, {
id: "syntaxhighlighter_css",
tag: "link",
rel: "stylesheet",
type: "text/css",
href: cssurl
});
utils.loadFile(
document, {
id: "syntaxhighlighter_js",
src: jsurl,
tag: "script",
type: "text/javascript",
defer: "defer"
},
function() {
hljs.initHighlightingOnLoad();
}
);
}
});
最后,执行以下命令进行整体打包
grunt default
打包完成后将 /dist/ 目录下的最终文件拷贝到自己的项目中进行部署即可,关于部署这里不再进行赘述,参考官方文档进行部署即可。