Ckeditor5: Backspace on a fully selected content or at the beginning of the first block should ensure that paragraph is left

Created on 31 Oct 2016  Â·  15Comments  Â·  Source: ckeditor/ckeditor5

Like in https://github.com/ckeditor/ckeditor5-engine/issues/670.

The paragraph should be left when a full content was selected or backspace was pressed when selection was at the beginning of the first block.

intro typing improvement

Most helpful comment

TL;DR: same thoughts as @Reinmar

MS Word (tested on OSX)

Case A - same as Google Docs
Case B - same as Google Docs

The most intuitive solutions imho:

Case A

We should type in paragraph in both cases. Reasoning: if I decided to discard everything that I had in the editor (by choosing to press Ctrl+A), then also the styling/formatting should be removed and fallback to the default.

For me it is a no-brainer and any other behaviours (especially MS Word/G Docs o.O) are weird.

Case B

I like CKEditor 4 (and TinyMCE) approach. It seems to be quite intuitive. If I have a header as a first element and type something there (<h1>XYZ^</h1>)) then pressing backspace gives me the following results:

  • <h1>XY^</h1>
  • <h1>X^</h1>
  • <h1>^</h1>
  • <p>^</p>
    Note that I'm able to do both using backspace: clear the text and have the header left there and clear the header after pressing backspace one more time.

All 15 comments

I'd love if the functionality of backspace in case of clearing the editor contents was enhanced. Currently when I hit Ctrl+A and then delete everything, an empty header is left. So when I start typing I'm writing in a header, which is a WTF.

The expected result imho is that the editor should in such case leave me with the same state as when I initialise an empty editor, that is with an empty paragraph.

Because we don't how the editor should behave when we press the Backspace key when the whole content in an editor is selected, I checked out how the other editors behave.

I testes few editors:

  • Google Docs,
  • TinyMCE,
  • CKEditor 4,
  • Medium.

Using two scenarios:

  • A: the editor contains a header, paragraph and list. The whole content is selected. We have two cases to check:

    1. typing directly on the selected text,

    2. press Backspace then typing,

  • B: the editor is empty, a selection is marked as a header.

Results

| | A | B |
|-------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------|
| Google Docs | In both cases – text is wrapped in the last element before cleaning the editor (in this case it is a list). | Pressing backspace does nothing. We still will typing as the header. |
| TinyMCE | In both cases, we will type in a paragraph. | After pressing Backspace in the header, we will type in a paragraph. Header disappeared. |
| CKEditor 4 | In both cases, we will type with the styles of the first element (in this case - as the header). But, if the first element will be a list, we will type in a paragraph. | After pressing Backspace in the header, we will type in a paragraph. Header disappeared. |
| Medium | In both cases, we will type with the styles of the first element (even if a list is the first element). | Pressing backspace does nothing. We still will type as the header. |

A

I prefer TinyMCE's behaviour (I selected the entire content, so I don't want styling). Although, I'm not sure whether the same should happen if there's just one block in the content.

B

I prefer the behaviour of TinyMCE and CKEditor 4 (which is derived from Chrome). It allows easily resetting the content to the initial state.

However, I wonder if we don't see this as a more important thing than it really is because we're very frequently clearing editor's content.

WDYT, @fredck @oleq @wwalc?

TL;DR: same thoughts as @Reinmar

MS Word (tested on OSX)

Case A - same as Google Docs
Case B - same as Google Docs

The most intuitive solutions imho:

Case A

We should type in paragraph in both cases. Reasoning: if I decided to discard everything that I had in the editor (by choosing to press Ctrl+A), then also the styling/formatting should be removed and fallback to the default.

For me it is a no-brainer and any other behaviours (especially MS Word/G Docs o.O) are weird.

Case B

I like CKEditor 4 (and TinyMCE) approach. It seems to be quite intuitive. If I have a header as a first element and type something there (<h1>XYZ^</h1>)) then pressing backspace gives me the following results:

  • <h1>XY^</h1>
  • <h1>X^</h1>
  • <h1>^</h1>
  • <p>^</p>
    Note that I'm able to do both using backspace: clear the text and have the header left there and clear the header after pressing backspace one more time.

With B my doubt is that let's say you start writing an article. You type: <h1>XYZ^</h1> and then you realise you don't like this and keep pressing backspace. I'm not 100% sure whether you'd like to be left with a paragraph (and it's hard to control when to release the backspace key).

Regarding A, I'm still unsure what should happen with this: <root><h1>[foo]</h1></root>. This is a slightly similar case to what I described above regarding backspacing in <h1>.


PS. @pomek, I've just realised that this feature is more complex because we can't only implement this behaviour to work in root elements. It also needs to work in such cases:

<paragraph>foo</paragraph>
<image>
  <caption>
     <heading1>[foo</heading1>
     <paragraph>bar]</paragraph>
  </caption>
</image>
<paragraph>foo</paragraph>

In this case, the <caption> element is marked to me a limit element in Schema#limits. So, to correctly implement this feature you need to look for the closest element which is either a root or a limit element.

I can see that we don't have Range#getCommonAncestor() yet and it'd be useful for this. It should use Position#getCommonAncestor( otherPosition ) (which we don't have too :)). You could start from implementing these methods.

As for handling backspace on collapsed selection there's also this case:

image

To solve this case we need to remember to clear entire root's content before inserting a new paragraph.

I talked with @fredck and @wojtekidd and we came to a conclusion what should happen if you have <h1>foo^</h1> and you press delete:

  • if you start with <h1>foo^</h1> and you keep delete pressed for 1 minute – you still end up in <h1>^</h1>,
  • but, if you are in <h1>^</h1> already and you press delete again, then you turn this into a paragraph.

This will allow you to delete the entire content of a heading without turning it into a paragraph which adresses this issue:

With B my doubt is that let's say you start writing an article. You type: <h1>XYZ^</h1> and then you realise you don't like this and keep pressing backspace. I'm not 100% sure whether you'd like to be left with a paragraph (and it's hard to control when to release the backspace key).

However, once you are left with <h1>^</h1> or <listItem>^</listItem> and you press backspace again, then you reset the content to a paragraph.

Regarding A, I'm still unsure what should happen with this: <root><h1>[foo]</h1></root>. This is a slightly similar case to what I described above regarding backspacing in <h1>.

The "press backspace in empty heading/list item which starts the content to convert it to a paragraph" will let you easily end up in a paragraph after doing ctrl+a, backspace, backspace even without special changes for what should happen with ctrl+a, backspace.

However, I can see that in CKEditor 4 we have cases like this one handled:

image

Press backspace and you're immediately left with just a paragraph. The same doesn't work for a heading or block quote but works if a table or a block image start the content.

I think that the lack of consistency comes from the fact that it was implemented as a chain of independent fixes for these separate features instead of being implemented as one consistent algorithm to work in all cases.

Hence, I'd like to work on deleting the whole content anyway. Unconditionally. Previously I was considering treating one block selection differently than two+ blocks, but we tested it with @wwalc and we agreed that you press ctrl+a, delete if you want to start from scratch.

I reported a slightly related scenario in https://github.com/ckeditor/ckeditor5-list/issues/65.

Ok, I was returned to implement this ticket and I would like to know whether I'm following a good way.

  • For scenario 1 – we will type in a paragraph (as CKE4 and Tiny).
  • For scenario 2 – as long as we have the selection inside a heading or other element, backspace will clear text inside the element. But, if we select the empty element (the heading) and press backspace, the element will be removed and paragraph will be inserted.

Am I right?

I prepared few scenarios:

I

User pressed Backspace in the heading element which is not empty.

  • <root><h1>abc^</h1></root> Backspace
  • <root><h1>ab^</h1></root> Backspace
  • <root><h1>a^</h1></root> Backspace
  • <root><h1>^</h1></root> Backspace
  • <root><h1>^</h1></root>

II

User pressed and held Backspace in the heading element which is not empty.

  • <root><h1>abc^</h1></root> Backspace (_repeated until the user released it_)
  • <root><h1>^</h1></root>

III

User pressed Backspace in the heading which is empty element.

  • <root><h1>^</h1></root> Backspace
  • <root><p>^</p></root>

IV

User pressed Backspace in the list which is empty and located inside the blockquote.

  • <root><blockquote><listItem>^</listItem></blockquote></root> Backspace
  • <root><blockquote><p>^</p></blockquote></root> Backspace
  • <root><p>^</p></root>
V

User pressed Backspace in the non-empty list which is located inside the blockquote.

  • <root><blockquote><listItem indent="0">^</listItem><listItem indent="0">List item 2.</listItem></blockquote></root> Backspace
  • What now?

Could you describe what should happen in V?

As for cases IV step 2 – this is beyond the scope of this ticket. Unwrapping the paragraph needs to be done by the block-quote package itself.

As for V – the expected result is <root><blockquote><p>^</p><listItem indent="0">List item 2.</listItem></blockquote></root>. It's simply the result of the same code which handles cases III and IV. No difference here.

As for case I – the last result should be <root><p>^</p></root> because previously the user had <root><h1>^</h1></root> and pressed Backspace.

https://github.com/ckeditor/ckeditor5-typing/issues/61#issuecomment-313302141

My opinion:

A

Both options for me are ok (the first one is simpler):

  1. Remove everything and endup in the first element (header).
  2. Remove everything and endup in a paragraph, except when the whole selection extends through a single block element only. In such case, that element stays.

As for typing, it should behave like Backspace + Typing, so the above backspace rules will apply before the character gets inserted.

B

No-brainer... with Backspace we endup in an empty paragraph.

At this moment I have something like this:

ezgif com-optimize 1

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Reinmar picture Reinmar  Â·  3Comments

wwalc picture wwalc  Â·  3Comments

devaptas picture devaptas  Â·  3Comments

MCMicS picture MCMicS  Â·  3Comments

MansoorJafari picture MansoorJafari  Â·  3Comments