Delete selection spanning to the beginning of the next text block

If we select the whole paragraph and delete it, the next text block gets merged into the current block.

output

The expectation (at least to me) is that it should remove the whole heading and leave only one paragraph in the blockquote.

<doc>
  <blockquote>
    <p>foo[C]</p>
  </blockquote>
  <p>baz</p>
</doc>

However, due to the fact that mouse selection must start & end inside text blocks, the selection range is actually

<doc>
  <blockquote>
    <p>foo</p>
    <h1>[S]bar</h1>
  </blockquote>
  <p>[E]baz</p>
</doc>

, which trigger the merging between the heading and the last paragraph.

Here is another example when the whole blockquote will be removed.

<doc>
  <blockquote>
    <h1>[S]foo</h1>
  </blockquote>
  <p>[E]bar</p>
</doc>

After searching the forum I found this commit and the post. However, in our case, it goes into the last tr.delete(from, to) in deleteRange.

Fundamentally, I guess people could have different expectation when the whole text block is selected vs. only part of the block is selected. In the latter case, it feel more acceptable if the following text block is merged to the current block. For the former case, the desired behavior - at least for us - is to remove the blocks if the whole texts are covered. Whether the deletion should “penetrate” the container blocks could be another factor.

So my questions are:

  1. what is the targeted behavior that we can reason about? In certain cases we can rely on it to delete the current text block, but in other cases we can’t.
  2. I understand that you may not want to update the implementation in the library (or you do?), so, if we want to implement a custom behavior, what is the proper algorithm to do this, like the one in deleteRange?

The conceptual model of such changes is that they delete the tokens between the start and end of the selection (and then do some fitting to make sure that the resulting document is still coherent). So here the opening token for the list item isn’t affected, and so the text after the deletion ends up in that item.

That being said, the “range” variants of replacement and deletion (replaceRange, replaceRangeWith, deleteRange) perform some “do what I mean” magic to the affected ranges. In this case it could be argued that the user intention is likely to affect the entire list item, and not the paragraph after it. This patch adds some logic to make it work like that.

Thanks for the fix and the explanation. That works perfectly!