1.一个页面两个相同数据编辑器,导致selection异常处理

  1. // 取到当前focus node block节点
  2. const parentEl = native.focusNode.parentElement
  3. // 找到focus node block节点的编辑器div
  4. const editorDom = this.closest(parentEl, "div[data-slate-editor='true']")
  5. debug.update('onNativeSelectionChange', {
  6. anchorOffset: native.anchorOffset,
  7. })
  8. const isCurrentEditor = editorDom === this.props.editor.el
  9. if (activeElement !== this.ref.current) {
  10. // The editor can't focus when readOnly 不是当前的editor触发的时候就 return
  11. if (!this.props.selectionChangeable || !isCurrentEditor) {
  12. return
  13. }
  14. }

2.node和text节点attributes添加属性(为协同版本对比提供)

  1. // constants/data-attributes.js
  2. VERSION_COMPARE_TYPE: 'data-version-compare-type',
  3. // node.js
  4. // 如果node.data中有versionCompareType字段,说明要显示对比样式,attributes添加versionCompareType字段
  5. if (node.data && node.data.get('versionCompareType')) {
  6. attributes[DATA_ATTRS.VERSION_COMPARE_TYPE] = node.data.get('versionCompareType')
  7. }
  8. // text.js
  9. const attributes = {
  10. [DATA_ATTRS.OBJECT]: node.object,
  11. [DATA_ATTRS.KEY]: node.key,
  12. }
  13. // 如果node.data中有versionCompareType字段,说明要显示对比样式,attributes添加versionCompareType字段
  14. if (node.data && node.data.get('versionCompareType')) {
  15. attributes[DATA_ATTRS.VERSION_COMPARE_TYPE] = node.data.get('versionCompareType')
  16. }

3.被移除节点前后都有文本,如果前面文本和被移除文本不是在一个块,anchor移到后面的文本上去

  1. removeNode(path) {
  2. let value = this
  3. let { document } = value
  4. const node = document.assertNode(path)
  5. const isText = node.object === 'text'
  6. const first = isText ? node : node.getFirstText() || node
  7. const last = isText ? node : node.getLastText() || node
  8. const prev = document.getPreviousText(first.key)
  9. const prevParent = prev ? document.getClosestBlock(prev.key) : null
  10. const currentParent = document.getClosestBlock(node.key)
  11. const next = document.getNextText(last.key)
  12. document = document.removeNode(path)
  13. value = value.set('document', document)
  14. value = value.mapRanges((range) => {
  15. const { anchor, focus } = range
  16. if (node.hasNode(anchor.key)) {
  17. if (isText) {
  18. if (prev) {
  19. // 被移除节点前后都有文本,如果前面文本和被移除文本不是在一个块,anchor移到后面的文本上去
  20. if (next) {
  21. if (prevParent === currentParent) {
  22. range = range.moveAnchorTo(prev.key, prev.text.length)
  23. } else {
  24. range = range.moveAnchorTo(next.key, 0)
  25. }
  26. }
  27. // 只有前面有文本 anchor移到前面的文本上去
  28. else {
  29. range = range.moveAnchorTo(prev.key, prev.text.length)
  30. }
  31. } else if (next) {
  32. range = range.moveAnchorTo(next.key, 0)
  33. } else {
  34. range = range.unset()
  35. }
  36. } else {
  37. range = prev
  38. ? range.moveAnchorTo(prev.key, prev.text.length)
  39. : next
  40. ? range.moveAnchorTo(next.key, 0)
  41. : range.unset()
  42. }
  43. }
  44. if (node.hasNode(focus.key)) {
  45. if (isText) {
  46. if (prev) {
  47. if (next) {
  48. if (prevParent === currentParent) {
  49. range = range.moveFocusTo(prev.key, prev.text.length)
  50. } else {
  51. range = range.moveFocusTo(next.key, 0)
  52. }
  53. } else {
  54. range = range.moveFocusTo(prev.key, prev.text.length)
  55. }
  56. } else if (next) {
  57. range = range.moveFocusTo(next.key, 0)
  58. } else {
  59. range = range.unset()
  60. }
  61. } else {
  62. range = prev
  63. ? range.moveFocusTo(prev.key, prev.text.length)
  64. : next
  65. ? range.moveFocusTo(next.key, 0)
  66. : range.unset()
  67. }
  68. }
  69. range = range.updatePoints((point) => point.setPath(null))
  70. return range
  71. })
  72. return value
  73. }

4.取消捕获异常,避免上层组件捕获不到错误

5.html serialize 忽略未知mark

6.两个text节点不在同一个块中 不取前一个mark 避免相邻块 后一个在开始位置输入,带上前面样式的问题

  1. const currentBlock = this.getClosestBlock(path)
  2. const previousBlock = this.getClosestBlock(this.getPath(previousText.key))
  3. // 两个text节点不在同一个块中 不取前一个mark 避免相邻块 后一个在开始位置输入,带上前面样式的问题
  4. if (previousBlock !== currentBlock) {
  5. return text.marks
  6. }
  7. return previousText.marks

7.导入石墨文档多个mark的style不能解析问题

将style中的所有mark,分别解析,进行递归解析

8.修复一直按住删除键时,光标异常的问题

9.safari 下获取焦点滚动的问题

10.解决从word复制内容出来的时候,text节点的内容是多个回车符的问题。原来的是匹配一个回车符

11.修复视频复制异常的问题,

因为视频前后都有一个空block节点,导致复制到了一个空block节点

12.解决react版本升级导致API废弃的bug

  1. // unstable_flushControlled 在 reactDOM 16.13上已经删除了,替换为 flushSync API
  2. const flushControlled = ReactDOM.flushSync

13.解决IOS删除最后一个时,没有添加空block节点的bug

  1. // IOS删除最后一个字符导致 DOM结构出问题
  2. if (Hotkeys.isDeleteBackward(event) && IS_IOS) {
  3. const size = value.document.nodes.size
  4. // 不是最后一个block,不是最后一个offset,因为value.document.getTexts()耗时
  5. if (size === 1 && start.offset === 1) {
  6. if (value.document.getTexts().get(0) === 1) {
  7. // deleteCharBackward 就会新增一个空block节点
  8. return editor.deleteCharBackward()
  9. }
  10. }
  11. }

14. 避免回车换行光标异常

  1. const ops = editor.operations
  2. // 避免回车换行光标异常
  3. if (ops.size > 0 && ops.last().type === 'split_node') {
  4. debug(`onSelect ops.size > 0 && ops.last().type === 'split_node'`)
  5. return
  6. }