写点什么

感谢 Fluent Editor 开源富文本首位贡献者!

作者:OpenTiny社区
  • 2024-08-28
    广东
  • 本文字数:2932 字

    阅读完需:约 10 分钟

感谢 Fluent Editor 开源富文本首位贡献者!

本文由体验技术团队 Kagol 原创。


2024 年 8 月 20 日,刚开源一周的富文本 Fluent Editor 迎来了第一位贡献者:zzxming


1、Bug 描述

zzxming 同学修复了 Fluent Editor 富文本表格模块的一个隐藏 Bug:


fix: table module can't save background color #10


缺陷描述:通过表格右键菜单设置单元格背景色之后,生成的 delta 中缺失单元格背景色信息,导致通过 setContents 方法设置的富文本表格单元格丢失了背景色。


这样描述可能比较绕口,zzxming 同学非常贴心地做了一个 Demo 用于复现该问题:


最小可复现 Demo:https://stackblitz.com/edit/vitejs-vite-quwkzn?file=src%2FApp.vue&terminal=dev

2、Bug 复现步骤

第一步:在表格单元格中右键,给单元格设置一个背景色。


第二步:通过 editor.getContents() 获取到的对应的 delta。

const delta = {      "ops": [          {              "attributes": {                  "table-col": {                      "width": "100"                  }              },              "insert": "\n"          },          {              "attributes": {                  "table-cell-line": {                      "rowspan": "1",                      "colspan": "1",                      "row": "row-xapy",                      "cell": "cell-e89w"                  },                  "row": "row-xapy",                  "cell": "cell-e89w",                  "rowspan": "1",                  "colspan": "1"              },              "insert": "\n"          }      ]  }
复制代码


可以看到 delta 没有携带单元格背景色信息。


第三步:将 delta 通过 setContents 方法回填到富文本中,单元格没有背景色。

editor.setContents(delta)
复制代码



3、解决方案

修改文件:packages/fluent-editor/src/table/formats/table.ts


修复该问题主要分成以下步骤:


  • 把 delta 中的 cell-bg 设置到 qlbt-cell-line 节点的 data-cell-bg 属性中

  • 从 qlbt-cell-line 节点中拿到 data-cell-bg 的值,回填到单元格背景色

  • 将 DOM 节点中的 data-cell-bg 值,保存到 delta 中

3.1 将 delta 中 cell-bg 信息设置到 DOM 节点中

将 delta 信息设置到 DOM 节点中,一般是在 blot 的 static create 方法中进行。


static create(value) {  const node = super.create(value);
...
- CELL_ATTRIBUTES.forEach((attrName) => {- node.setAttribute(`data-${attrName}`, value[attrName] || CELL_DEFAULT[attrName]);+ [...CELL_ATTRIBUTES, 'cell-bg'].forEach((attrName) => {+ const keyValue = value[attrName] || CELL_DEFAULT[attrName];+ keyValue && node.setAttribute(`data-${attrName}`, keyValue); });
...
return node;}
复制代码


先从 delta(value) 中拿到 cell-bg 信息,然后设置到 DOM 节点的 data-cell-bg 属性中。


value 的结构:


{  rowspan: '1',  colspan: '1',  row: 'row-xapy',  cell: 'cell-e89w',  cell-bg: '#ffff00'}
复制代码

3.2 回填 cell-bg 到单元格背景色

zzxming 同学不仅修复了这个 Bug,还做了一个小重构,将设置单元格背景色这个功能抽成了一个函数 setCellBg,并且加了详细的注释,点赞👍


/** this method is for TableCellLine to change cell background color  *  if use `format('cell-bg', value)` will loop trigger  *  TableCellLine.optimize -> TableCell.format -> TableCellLine.optimize ... */setCellBg(value?: string) {  if (value) {    this.domNode.style.backgroundColor = value  } else {    this.domNode.style.backgroundColor = 'initial'  }}
复制代码


在 TableCellLine 类的 optimize 方法中调用该函数,以便把 delta 中的 cell-bg 颜色设置到表格单元格。

3.3 将 cell-bg 信息保存到 delta 中

将 DOM 的信息保存到 delta 中,一般是在 blot 的 static format 方法中进行。


在 TableCellLine 类的 static format 方法中调用了 reduceFormats 函数,给该函数传入 cell-bg 信息。


static formats(domNode) {  const formats = {};  if (formats['list']) {    formats['list'] = domNode.classList.item(0);  }-  return reduceFormats(domNode, formats);+  return reduceFormats(domNode, formats, ['cell-bg']);}
复制代码


在 reduceFormats 中获取到 DOM 中的 data-cell-bg,并设置到 delta 数据中。


- function reduceFormats(domNode, formats) {-   return CELL_ATTRIBUTES.concat(CELL_IDENTITY_KEYS).reduce((tableFormats, attribute) => {+ function reduceFormats(domNode:HTMLElement, formats:Record<string, any>, extraFormat: string[] = []) {+   return [...CELL_ATTRIBUTES, ...CELL_IDENTITY_KEYS, ...extraFormat].reduce((tableFormats, attribute) => {    if (domNode.hasAttribute(`data-${attribute}`)) {      tableFormats[attribute] = domNode.getAttribute(`data-${attribute}`) || undefined;    }    return tableFormats;  }, formats);}
复制代码


该问题已解决,可以通过以下链接进行验证:



详见 zzxming 同学提交的 PR:


fix: table module can't save background color #10

3.4 优化点

这里其实有个优化点(欢迎 PR 👏):


目前 zzxming 同学在 static create 和 reduceFormats 方法中传入 cell-bg 都是直接增加的,其实可以放到 CELL_ATTRIBUTES 常量数组中,合理利用现有的代码😋。


- export const CELL_ATTRIBUTES = ['rowspan', 'colspan'];+ export const CELL_ATTRIBUTES = ['rowspan', 'colspan', 'cell-bg'];
复制代码




感谢 zzxming 同学对 Fluent Editor 的贡献,目前已发布 v3.18.3 版本,欢迎朋友们使用 Fluent Editor,感兴趣也欢迎一起参与共建。


往期文章推荐:


关于 OpenTiny

官网:https://opentiny.design

TinyVue 源码:https://github.com/opentiny/tiny-vue (欢迎 Star ⭐)

TinyEngine 源码:https://github.com/opentiny/tiny-engine (欢迎 Star ⭐)

B 站:https://space.bilibili.com/15284299

欢迎加入 OpenTiny 开源社区。添加微信小助手 opentiny-official 一起参与交流前端技术~


(温馨提示:OpenTiny CCF 开源创新大赛也在持续报名中,欢迎大家一起报名参赛,赢取 10W 奖金:https://www.gitlink.org.cn/competitions/track1_openTiny

用户头像

OpenTiny 企业级web前端开发解决方案 2023-06-06 加入

官网:opentiny.design 我们是华为云的 OpenTiny 开源社区,会定期为大家分享一些团队内部成员的技术文章或华为云社区优质博文,涉及领域主要涵盖了前端、后台的技术等。

评论

发布
暂无评论
感谢 Fluent Editor 开源富文本首位贡献者!_富文本_OpenTiny社区_InfoQ写作社区