壹 ❀ 引

在本周迭代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标签,要做的只是将<>转义为&lt;&gt;即可。

<p>听风是风</p>
// 转为
&lt;p&gt;听风是风&lt;/p&gt;

代码块是支持语言切换的,我们前面说了只有纯文本只有这个问题,所以只有当前语言类型是纯文本,就需要做标签转义,我大概定义了这样的一个方法:

transformHtmlToText = (code, lang) => {
return lang === 'PlainText' ? code.replace(/</g, '&lt;').replace(/>/g, '&gt;') : code;
}

如果只是作为展示,这样貌似也没什么问题了,取到textarea的值转义后传给highlightjs作为展示。但比较尴尬的是,代码块是支持用户操作的,用户可能会进行代码编辑或者语言切换,以语言切换为例,假设我们一开始的语言是纯文本,且做了转义:

// 此时语言是纯文本
&lt;p&gt;听风是风&lt;/p&gt;;

现在用户进行了编辑,删除了部分代码,同时把语言切成了java,那么问题来了,用户编辑删除时操作的是<p>听风是风</p>还是&lt;p&gt;听风是风&lt;/p&gt,切换语言后我是不是应该将&lt;p&gt;听风是风&lt;/p&gt中的&lt;再反向转义成<呢?

首先第一个问题我们已经很清楚了,在前面的原理分析中我们已经得知了操作的其实是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修复的思考的更多相关文章

  1. Java将Excel中科学计数法解析成数字

    需要注意的是一般的科学表达式是1.8E12 1.8E-12 而在Excel中的科学表达式是1.8E+12 1.8E-12 我写的科学计数法的正则表达式是(-?\d+\.?\d*)[Ee]{1}[\+- ...

  2. 写一个将当前页面 URL 中的 get 参数解析成一个对象的方法。

    function getQuery () { var args = {}; var query = window.location.search.substring(1); var pairs = q ...

  3. WordPress中默认文本编辑器替换成百度UEditor编辑器

    1.下载 下载地址: http://pan.baidu.com/s/1geNk19L 2.解压放到plugins目录下 3.插件启用

  4. WebApi 中FromUri参数自动解析成实体的要求

    条件一:类属性名称必须和参数名称相同(不分大小写) 条件二:API参数必须以[FromUri]来修饰(数组也需要添加,否则参数传递不了) 条件三:属性类型为“类”的,如果使用类名(导航属性在本类的名称 ...

  5. xml解析用正则解决没有标签的文本的解析不出异常

    如  <q>sasas<w>eqwe</w>ddas</q> package com.people.xmlToSql; import java.io.F ...

  6. ibtais中把clob数据类型转换成string并展示到前台

    1,在xml中定义一个resultMap <resultMap class="com.aa.bb" id="clobToString"> <r ...

  7. 记一次工作中的小BUG

    今天在调试代码的时候总是遇到一个bug,百思不得其解!先上bug图 我用的webapi 集成的swagger,错误提示是路由名称冲突,可我仔细检查了下并没有冲突的路由地址啊!于是上网查找资料,有位网友 ...

  8. 解决黑群晖"抱歉,您所指定的页面不存在"-记一次黑群晖修复案例

    起因 搞了一个usb外接硬盘准备备份数,刚好看到群晖有个工具软件"USB Copy". 安装后设置拷贝docker文件夹,然后就悲剧了,nas主页抛出提示 一开始也是直接网上搜索标 ...

  9. 纯文本抽出程序库DMC TEXT FILTER

    因需而生,红樱枫为文本转换市场领航 --纯文本抽出程序库DMC TEXT FILTER,从需求中把握平衡 在高度数字化的今天,数字图书馆已经成为非常多人查询资料的有效途径.然而即使在畅通的宽带搜寻中一 ...

  10. Gtk中的文本视图(GtkTexViewWidget)

    Gtk中的文本视图(GtkTexViewWidget) Gtk中的文本视图(GtkTexView Widget) 在本章的Gtk+程序设计教程中,我们将重点介绍 GtkTexView 构件. GtkT ...

随机推荐

  1. Angular系列教程之MVC模式和MVVM模式

    .markdown-body { line-height: 1.75; font-weight: 400; font-size: 16px; overflow-x: hidden; color: rg ...

  2. 【Linux】字符驱动之sysfs接口实现

    [来源]https://blog.csdn.net/qq_20553613/article/details/104556269

  3. 【C++】为什么含有纯虚函数的类无法定义对象

    纯虚函数的地址为空,无法分配内存,纯虚成员函数对类是没有意义的,失去了普通类的数据和方法绑定于同一对象中的意义,因此无法构造对象,只能由其派生类继承这些成员函数并实现,才能构造派生类对象. 纯虚成员函 ...

  4. JDBC针对SQLServer的sendStringParametersAsUnicode=false的验证

    JDBC针对SQLServer的sendStringParametersAsUnicode=false的验证 背景 部分客户的SQLServer数据库出现了大量死锁的情况. 虽然部分客户并没有反馈死锁 ...

  5. [转帖]【VIM】多行缩进空格与删除

    向前或向后缩进一个TAB 按ctrl + v组合键进入Visual Line模式,可使用方向键选择多行: 按<或>,进行向前或向后缩进tab. 缩进n个TAB,按n+<或> 多 ...

  6. [转帖]clickHouse单机模式安装部署(RPM安装)

    关于版本和系统的选择 操作系统:Centos-7 ClickHouse: rpm 在安装,20.x 安装前的准备 CentOS7 打开文件数限 在 /etc/security/limits.conf ...

  7. [转帖]调优"四剑客"的实战演练,福尔摩斯•K带你轻松优化性能

     前言 天下武功,唯快不破.在侦探的世界中,破案效率永远是衡量一名侦探能力的不二法门.作为推理界冉冉升起的新星,大侦探福尔摩斯·K凭借着冷静的头脑.严谨的思维,为我们展现了一场场华丽而热血的推理盛宴. ...

  8. Docker 镜像减少体积的思路和方法

    Docker 镜像减少体积的思路和方法 背景 有一个项目感觉镜像有点大 这边同事喊着一起帮忙处理一下. 今天基本上就在客户现场进行处理了. 想着应该把自己想到的东西整理一下. 整体思路 1. 清理do ...

  9. [转帖]如何通过shell脚本对一个文件中的所有数值相加并求和

    https://developer.aliyun.com/article/886170?spm=a2c6h.24874632.expert-profile.255.7c46cfe9h5DxWK 1.背 ...

  10. [转帖]Linux使用Stress-ng测试CPU、内存、磁盘I/O满载情况教程与范例

    https://www.xiaoyuanjiu.com/108301.html 介绍如何在 Linux 系统上使用 stress-ng 负载测试工具,产生 CPU.内存等资源满载的状况. stress ...