喜报!Fluent Editor 开源富文本迎来了第一位贡献者!

你好,我是 Kagol,个人公众号:前端开源星球

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

喜报!Fluent Editor 开源富文本迎来了第一位贡献者!

1 Bug 描述

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

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

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

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

最小可复现 Demo

2 Bug 复现步骤

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

喜报!Fluent Editor 开源富文本迎来了第一位贡献者!

第二步:通过 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 没有携带单元格背景色信息。

喜报!Fluent Editor 开源富文本迎来了第一位贡献者!

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

editor.setContents(delta) 

喜报!Fluent Editor 开源富文本迎来了第一位贡献者!

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,感兴趣也欢迎一起参与共建。

往期文章推荐:

联系我们

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

官网:https://opentiny.design/tiny-vue

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

个人博客:https://kagol.github.io/blogs

小助手微信:opentiny-official

公众号:OpenTiny

发表评论

评论已关闭。

相关文章