Avoid deleting block-level atoms with backspace #6

Closed
hubgit wants to merge 1 commit from patch-1 into master
hubgit commented 2018-09-25 17:57:00 +02:00 (Migrated from github.com)

Pressing backspace at the start of a block which is after a block marked as an "atom" will delete the preceding block. This is undesirable, so this change prevents atomic blocks from being deleted with backspace (they will be selected, instead).

I'm not 100% sure of the side-effects of this change, so please advise if there might be a better alternative solution.

Pressing backspace at the start of a block which is after a block marked as an "atom" will delete the preceding block. This is undesirable, so this change prevents atomic blocks from being deleted with backspace (they will be selected, instead). I'm not 100% sure of the side-effects of this change, so please advise if there might be a better alternative solution.
marijnh commented 2018-09-25 19:59:23 +02:00 (Migrated from github.com)

This behavior was intentional. It may be undesirable to you, but just dropping it isn't something I'm interested in merging.

This behavior was intentional. It may be undesirable to you, but just dropping it isn't something I'm interested in merging.
hubgit commented 2018-09-25 23:19:39 +02:00 (Migrated from github.com)

Would before.isAtom && !before.type.spec.isolating be acceptable instead, so blocks marked as isolating would be protected from deletion in this way? (feel free to say no, as it's easy enough to add this behaviour elsewhere).

I can work around this by creating an ignoreAtomBlockNodeBackward backspace key handler, but it would be useful to know why the existing behaviour is intentional.

Would `before.isAtom && !before.type.spec.isolating` be acceptable instead, so blocks marked as `isolating` would be protected from deletion in this way? (feel free to say no, as it's easy enough to add this behaviour elsewhere). I can work around this by creating an `ignoreAtomBlockNodeBackward` backspace key handler, but it would be useful to know why the existing behaviour is intentional.
marijnh commented 2018-09-26 11:36:30 +02:00 (Migrated from github.com)

I would suggest putting another command in front of joinBackward that detects this situation and does whatever you want to happen there.

I would suggest putting another command in front of `joinBackward` that detects this situation and does whatever you want to happen there.
hubgit commented 2018-09-26 14:35:19 +02:00 (Migrated from github.com)

That's what I've ended up doing, yes - posted here for reference:

// Copied from prosemirror-commands
const findCutBefore = ($pos) => {
  if (!$pos.parent.type.spec.isolating) {
    for (let i = $pos.depth - 1; i >= 0; i--) {
      if ($pos.index(i) > 0) return $pos.doc.resolve($pos.before(i + 1))
      if ($pos.node(i).type.spec.isolating) break
    }
  }
  return null
}

// Ignore atom blocks (as backspace handler), instead of deleting them.
// Adapted from selectNodeBackward in prosemirror-commands
export const ignoreAtomBlockNodeBackward = (state, dispatch, view) => {
  const { $cursor } = state.selection as TextSelection

  if (!$cursor) return false

  // ignore empty blocks
  if ($cursor.parent.content.size === 0) return false

  // handle cursor at start of textblock
  if (
    view ? !view.endOfTextblock('backward', state) : $cursor.parentOffset > 0
  ) {
    return false
  }

  const $cut = findCutBefore($cursor)

  if (!$cut) return false

  const node = $cut.nodeBefore

  if (!node) return false

  return node.isBlock && node.isAtom
}
That's what I've ended up doing, yes - posted here for reference: ```js // Copied from prosemirror-commands const findCutBefore = ($pos) => { if (!$pos.parent.type.spec.isolating) { for (let i = $pos.depth - 1; i >= 0; i--) { if ($pos.index(i) > 0) return $pos.doc.resolve($pos.before(i + 1)) if ($pos.node(i).type.spec.isolating) break } } return null } // Ignore atom blocks (as backspace handler), instead of deleting them. // Adapted from selectNodeBackward in prosemirror-commands export const ignoreAtomBlockNodeBackward = (state, dispatch, view) => { const { $cursor } = state.selection as TextSelection if (!$cursor) return false // ignore empty blocks if ($cursor.parent.content.size === 0) return false // handle cursor at start of textblock if ( view ? !view.endOfTextblock('backward', state) : $cursor.parentOffset > 0 ) { return false } const $cut = findCutBefore($cursor) if (!$cut) return false const node = $cut.nodeBefore if (!node) return false return node.isBlock && node.isAtom } ```

Pull request closed

Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
prosemirror/prosemirror-commands!6
No description provided.