RedGiant
RedGiant

Reputation: 4748

Unable to delete a link clearly in Slate.js editor using the official example

enter image description here

CodeSandbox Example:

https://codesandbox.io/s/slate-2-images-and-links-forked-s09wi

This is basically the withLink() example from the official document.

When you press backspace or cut out to remove the link, the JSON output still contains the link data with empty text. I don't understand why it still remains in the output. Can anyone provide a solution for this?

The withLink example:

const withLinks = editor => {
  const { insertData, insertText, isInline } = editor

  editor.isInline = element => {
    return element.type === 'link' ? true : isInline(element)
  }

  editor.insertText = text => {
    if (text && isUrl(text)) {
      wrapLink(editor, text)
    } else {
      insertText(text)
    }
  }

  editor.insertData = data => {
    const text = data.getData('text/plain')

    if (text && isUrl(text)) {
      wrapLink(editor, text)
    } else {
      insertData(data)
    }
  }

  return editor
}

const unwrapLink = editor => {
  Transforms.unwrapNodes(editor, {
    match: n =>
      !Editor.isEditor(n) && SlateElement.isElement(n) && n.type === 'link',
  })
}

const wrapLink = (editor, url) => {
  if (isLinkActive(editor)) {
    unwrapLink(editor)
  }

  const { selection } = editor
  const isCollapsed = selection && Range.isCollapsed(selection)
  const link: LinkElement = {
    type: 'link',
    url,
    children: isCollapsed ? [{ text: url }] : [],
  }

  if (isCollapsed) {
    Transforms.insertNodes(editor, link)
  } else {
    Transforms.wrapNodes(editor, link, { split: true })
    Transforms.collapse(editor, { edge: 'end' })
  }
}

Upvotes: 3

Views: 2674

Answers (1)

Akrom
Akrom

Reputation: 331

I fixed this issue by adding normalizeNode in withLinks plugin.

const { normalizeNode } = editor
editor.normalizeNode = entry => {
const [node, path] = entry
if (Element.isElement(node) && node.type === 'paragraph') {
  const children = Array.from(Node.children(editor, path))
  for (const [child, childPath] of children) {
    // remove link nodes whose text value is empty string.
    // empty text links happen when you move from link to next line or delete link line.
    if (Element.isElement(child) && child.type === 'link' && child.children[0].text === '') {
      if (children.length === 1) {
        Transforms.removeNodes(editor, { at: path })
        Transforms.insertNodes(editor,
          {
            type: 'paragraph',
            children: [{ text: '' }],
          })
      } else {
        Transforms.removeNodes(editor, { at: childPath })
      }
      return
    }
  }
}
normalizeNode(entry)

}

Upvotes: 3

Related Questions