3

我需要一些帮助来实现实时协作服务器(https://tiptap.dev/suggestions)中的提及。我的代码是这个的修改版本:https ://glitch.com/edit/#!/tiptap-sockets?path=server.js%3A1%3A0

我将这些步骤发送到我的套接字服务器以应用于文档的先前版本

steps.forEach((step) => {
    const result = Step.fromJSON(schema, step).apply(doc)
    doc = result.doc
})

并使用此模式来验证提及:

mention: {
  attrs: {
    id: {},
    label: {},
  },
  group: 'inline',
  inline: true,
  selectable: false,
  atom: true,
  toDOM: node => [
    'span',
    {
      class: 'mention',
      'data-mention-id': node.attrs.id,
    },
    `@${node.attrs.label}`,
  ],
  parseDOM: [
    {
      tag: 'span[data-mention-id]',
      getAttrs: dom => {
        const id = dom.getAttribute('data-mention-id')
        const label = dom.innerText.split('@').join('')
        return { id, label }
      },
    },
  ],
},

当我输入@Philip Isik 时,前端会发送以下步骤,

第 1 步:@philip Isik

第2步: ” ”

这些是服务器接收到的 JSON 格式的上述步骤:

    [ 
        '{"stepType":"replace","from":1,"to":2,"slice":{"content":[{"type":"mention","attrs":{"id":4,"label":"Philip Isik"},"content":[{"type":"text","text":"@Philip Isik"}]}]}}',
        
        '{"stepType":"replace","from":15,"to":15,"slice":{"content":[{"type":"text","text":" "}]}}' 
    ]

在第 1 步之后,循环失败并抛出

RangeError:位置 15 超出范围

所以我在第一步之后检查了内容长度,它说它的长度是 3,而它应该是长度 12(@Philip Isik 的长度)

有谁知道为什么会这样?已经在这 2 天了。任何帮助是极大的赞赏!

TLDR:

  1. 所以我要向服务器发送一个@Name 以应用于当前版本的文档。

  2. 服务器接收到提到的步骤@Name

  3. 现在,当它发送下一步时,发送的步骤是位置 6(@Name 的长度为 5,因此 5+1th=6th pos)

  4. 这就是问题所在,根据tiptap/prose对象,@Name的长度是2,而不是5

  5. 因此,它会引发“位置超出范围错误”

4

1 回答 1

0

尝试添加trim()parseDOM删除空格,因为我看到问题可能与存在相关的尾随空格("text": " ")。

'{"stepType":"replace","from":15,"to":15,"slice":{"content":[{"type":"text","text":" "}]}}'

在 Chrome 浏览器中测试时,像这样带有一些换行符和空格的简单 HTML:

<span data-mention-id="test">
  @Test mention
</span>

最后返回dom.innerText一个尾随空格@Test mention

trim这是添加到的更新架构parseDOM

mention: {
  attrs: {
    id: {},
    label: {},
  },
  group: 'inline',
  inline: true,
  selectable: false,
  atom: true,
  toDOM: node => [
    'span',
    {
      class: 'mention',
      'data-mention-id': node.attrs.id,
    },
    `@${node.attrs.label}`,
  ],
  parseDOM: [
    {
      tag: 'span[data-mention-id]',
      getAttrs: dom => {
        const id = dom.getAttribute('data-mention-id')
        const label = dom.innerText.trim().split('@').join('') // trim removes white space around text
        return { id, label }
      },
    },
  ],
},
于 2021-03-04T22:47:27.917 回答