解决highlightjs中纯文本被解析成HTML无法展示的问题,记一次工作中bug修复的思考

壹 ❀ 引
在本周迭代bug修复工作中,遇到了两个比较头疼的bug(同一个客户所提),bug问题描述也很奇怪,客户表示产品的富文本编辑器里的代码块功能,在纯文本语言模式下贴特定代码进去有的看不见,有的能看见但无法正常编辑,效果如下:


虽然知道了问题的表象,但还是有点无从下手,毕竟这块的功能不是我做的,实现原理以及功能逻辑都不了解,当然问题到最后肯定还是解决了,不然就不会有这篇文章了,本文也只是记录从零理解问题以及解决问题的思路。
贰 ❀ 排查思路
前端bug排查其实无非几个出发点。接口层,bug数据来源接口是否正常,如果不确证直接甩锅后端同事,此bug直接物理层面被解决。数据层,比如我们公司用的是的react,所以数据检验可以通过chrome插件查看component数据以及redux数据是否符合预期。逻辑层,通过读代码确认逻辑是否符合功能设计,读同事的旧代码往往是一件让人暴躁的事情,我也如此,实在没办法也只能硬着头皮读。
但此问题的表现我的第一感觉是出在渲染层面,所以处于验证,我直接点开了控制台的Elements
,也算走运,一看就发现了问题,原来拷贝到代码块的代码并不是未渲染,而是代码中包含html的标签直接被解析成了页面HTML中的一部分,这才导致了不展示以及无法编辑的问题。
客户拷贝的代码:
/// <summary>
/// show loading
/// </summary>
public void ShowLoading(){ Controller.instance.StartCoroutine(View.instance.ShowWordWarn(Model.instance.lanDic[55021], 0.2f));
}
控制台展示的结构,summary
被解析成了标签

比较幸运,原本以为是两个问题,现在只需要解决一个问题了。
叁 ❀ 修复思路
知道了问题所在,接下来需要了解的是富文本编辑器中的代码块的功能是如何实现的,简单看了下代码,发现实现上依赖了highlightjs,简单了解了下原理,大概如下:

上图中表示有两个视图层,highlight的code preview
也就是三方库渲染后带颜色的代码展示框,而下面还有一个textarer
也就是真正记录用户输入以及编辑结果的的编辑框。code preview
悬浮在textarea
上,再通过样式定位让两个视图层的代码对齐,这才有了我们在编辑彩色代码的效果。
也就是说,highlight
渲染的代码数据其实依赖于textarea
的输入,我们只要在输入做对应的数据转化即可。打开chrome,输入highlightjs html
,点击搜索,然后第一条问题就是我们想要的答案了。highlightjs with html code - Stack Overflow,这种问题咱们肯定不是第一个遇到的,网友绝对不会让你失望。
解决方案其实也很简单,比如以下代码我们不希望被解析html标签,要做的只是将<
和>
转义为<
与>
即可。
<p>听风是风</p>
// 转为
<p>听风是风</p>
代码块是支持语言切换的,我们前面说了只有纯文本只有这个问题,所以只有当前语言类型是纯文本,就需要做标签转义,我大概定义了这样的一个方法:
transformHtmlToText = (code, lang) => {
return lang === 'PlainText' ? code.replace(/</g, '<').replace(/>/g, '>') : code;
}
如果只是作为展示,这样貌似也没什么问题了,取到textarea的值转义后传给highlightjs作为展示。但比较尴尬的是,代码块是支持用户操作的,用户可能会进行代码编辑或者语言切换,以语言切换为例,假设我们一开始的语言是纯文本,且做了转义:
// 此时语言是纯文本
<p>听风是风</p>;
现在用户进行了编辑,删除了部分代码,同时把语言切成了java,那么问题来了,用户编辑删除时操作的是<p>听风是风</p>
还是<p>听风是风</p>
,切换语言后我是不是应该将<p>听风是风</p>
中的<
再反向转义成<
呢?
首先第一个问题我们已经很清楚了,在前面的原理分析中我们已经得知了操作的其实是textarea
的值,因此删除的其实就是textarea
的内容,highlight
只是对textarea
的值在做实时渲染而已。
第二个问题是我们常常会遇到的场景,一个值A因为某个原因被加工成了A+,在经历了一系列操作后已经变得面目全非,用户又在某种场景下又需要切回原有的数据A,那么要在A+的基础上做还原操作吗?很明显是不要的。
我在18年就遇到了类似的问题,用户输入时需要对文本中相同的文字进行标红匹配,我在利用正则匹配做了一系列的替换后达到了该效果,现在用户把输入的内容删除了,我当时的第一反应就是对已标红的文字再做反向还原,但我觉得这太复杂了,数据也极难维护。
当时我同学就说,为什么不把数据当一次性的呢,加工的时候就是一份副本,操作完了自然就遗弃了,你不是本来就有最初的数据吗,为何要还原呢?
没错,在前面的highlight
原理分析中,highlight
本来就是实时拿textarea
的数据,自己进行加工得到了一份彩色代码的副本,这份副本就是纯给我们看的,我们删除新增代码时,操作的其实是textarea的值。而我们切换代码块语言时textarea的值其实是没变化的,变化的是highlight
需要再拿一次textarea
的值按照当前选择的语言再生产一份对应的彩色代码而已。
我想表达的大概是下图这个意思,这是在编程中其实是很重要的一点,保证数据的唯一性,这会让你的数据变得更可控,在代码书写时也会变得相应的简单。

我在修复此bug的过程中,通过阅读代码发现原有逻辑不管是编辑代码还是切换语言,在对应的监听方法中都对state的textarea
的值,代码语言类型,以及highlight
所需要的值加工都做了实时更新,但我觉得后者值的实时获取分散在这么多的方法中没必要的,因为前面说了textarer
的值是才是理论上唯一数据源,在state中制好它的更新即可,考虑了一下,我将这些方法中的highlight
值操作的代码都删除了,并统一到了render
中根据textarer
与语言类型进行统一加工,bug改了代码量也相应的减少了一部分,神清气爽。
那么这大概就是最近一次修bug的经历,可能是太想写博客了,所以写了点东西,那么本文结束。
解决highlightjs中纯文本被解析成HTML无法展示的问题,记一次工作中bug修复的思考的更多相关文章
- Java将Excel中科学计数法解析成数字
需要注意的是一般的科学表达式是1.8E12 1.8E-12 而在Excel中的科学表达式是1.8E+12 1.8E-12 我写的科学计数法的正则表达式是(-?\d+\.?\d*)[Ee]{1}[\+- ...
- 写一个将当前页面 URL 中的 get 参数解析成一个对象的方法。
function getQuery () { var args = {}; var query = window.location.search.substring(1); var pairs = q ...
- WordPress中默认文本编辑器替换成百度UEditor编辑器
1.下载 下载地址: http://pan.baidu.com/s/1geNk19L 2.解压放到plugins目录下 3.插件启用
- WebApi 中FromUri参数自动解析成实体的要求
条件一:类属性名称必须和参数名称相同(不分大小写) 条件二:API参数必须以[FromUri]来修饰(数组也需要添加,否则参数传递不了) 条件三:属性类型为“类”的,如果使用类名(导航属性在本类的名称 ...
- xml解析用正则解决没有标签的文本的解析不出异常
如 <q>sasas<w>eqwe</w>ddas</q> package com.people.xmlToSql; import java.io.F ...
- ibtais中把clob数据类型转换成string并展示到前台
1,在xml中定义一个resultMap <resultMap class="com.aa.bb" id="clobToString"> <r ...
- 记一次工作中的小BUG
今天在调试代码的时候总是遇到一个bug,百思不得其解!先上bug图 我用的webapi 集成的swagger,错误提示是路由名称冲突,可我仔细检查了下并没有冲突的路由地址啊!于是上网查找资料,有位网友 ...
- 解决黑群晖"抱歉,您所指定的页面不存在"-记一次黑群晖修复案例
起因 搞了一个usb外接硬盘准备备份数,刚好看到群晖有个工具软件"USB Copy". 安装后设置拷贝docker文件夹,然后就悲剧了,nas主页抛出提示 一开始也是直接网上搜索标 ...
- 纯文本抽出程序库DMC TEXT FILTER
因需而生,红樱枫为文本转换市场领航 --纯文本抽出程序库DMC TEXT FILTER,从需求中把握平衡 在高度数字化的今天,数字图书馆已经成为非常多人查询资料的有效途径.然而即使在畅通的宽带搜寻中一 ...
- Gtk中的文本视图(GtkTexViewWidget)
Gtk中的文本视图(GtkTexViewWidget) Gtk中的文本视图(GtkTexView Widget) 在本章的Gtk+程序设计教程中,我们将重点介绍 GtkTexView 构件. GtkT ...
随机推荐
- Kubernetes 疑难杂症汇总
1. 部署报错:The requested fsGroup is 123, but the volume local-pv-c7ef339e has GID 1000710000. The volum ...
- 小白学标准库之 flag
Go 提供了解析命令行参数的 flag 包,本文旨在介绍 flag 的使用及内部实现等. 1. flag 包使用及实现 type PropertyOfPod struct { Namespace *s ...
- MySQL 覆盖索引详解
本文转载自:MySQL 覆盖索引详解,作者 Sevn 1. 什么是索引? 索引(在 MySQL 中也叫"键key")是存储引擎快速找到记录的一种数据结构,通俗来说类似书本的目录. ...
- 打 multi-fidelity RL 旗号,但是幼稚监督学习 + 迁移学习
文章名称:Multi-fidelity reinforcement learning framework for shape optimization 链接:https://www.sciencedi ...
- Git | git branch 分支操作
假设我们已经有了稳定的代码,现在我想整一些花活.比较安全的一个方式是,在新的分支上整活. 新建 vga 分支:git branch vga,然后切换到 vga 分支:git switch vga,或者 ...
- ORACLE Enterprise Manager Database Express(OEM-express)(遇到localhost拒绝访问情况)配置端口和启动方法
1.问题 之前一直进不去ORACLE Enterprise Manager Database Express,显示的是localhost拒绝了访问,经过查阅知道是没有配置相应端口. 2.解决方法 转载 ...
- bootstrap : 解决使图片全屏显示有空白边距的问题
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8 ...
- [转帖]Google SRE 薪水,看看同样作为 SRE 的你相差多少
https://zhuanlan.zhihu.com/p/566098252 SRE 是确保所有生产环境(Infra/Server/DBS 等)一直正常运行的人.每个网络科技公司基本都有这个部门.但是 ...
- [转帖]tidb-系统内核调优及对比
一.背景 验证系统调优对性能的影响,用sysbench做了一些简单的测试,具体调整方法可见官方文档 二.特殊说明 1.透明大页查看 # 查看透明大页是否开启,[]在always处表示开启,[]在nev ...
- [转帖]金仓数据库KingbaseES V8R6 索引膨胀
索引膨胀 对于索引,随着业务不断的增删改,会造成膨胀,尤其Btree索引,也会涉及索引分裂.合并等,导致索引访问效率降低.维护成本增加.另外,索引页的复用与HEAP PAGE不一样,因为索引的内容是有 ...