Slate: Blocks should have a way of expressing that mergeBlock or splitBlock cannot occur between its children and an outside block

Created on 20 Feb 2018  路  5Comments  路  Source: ianstormtaylor/slate

Do you want to request a _feature_ or report a _bug_?

Feature

What's the current behavior?

Several bug reports have been popping up that effectively have a root cause of mergeNode being applied to nodes that should not be mergable. In almost every report, it in some way involves the contents of a Table Cell being merged with some other block the reporter does not expect

What's the expected behavior?

The reports tend to recommend not merging the blocks in these situations, but often merging blocks is the correct behavior and the merging of a table cell is a corner case.

It is tempting to say that "we should not merge blocks if they have two different parents" but one case where that falls apart is lists. It is desirable behavior that we can merge a block following a list item to that list item with delete.

The reason the Table Cell is expected to not merge is that a Table is seen as some isolated container that should have an impermeable barrier with other content in the document that is not within the table. IE, when we paste a table, the first block of the table should not be merged with the block preceding the paste region.

Tables and their contents are not the only block where this is a desirable. For instance, some editors (like Confluence) have a Title block where one cannot split the block, or merge blocks with it via delete or paste. The content of the Title Block is effectively within that title block and cant cross that boundary.

Given that there are a couple of cases where we do not want merge or split to cross some arbitrary block barrier, it would be nice if there was a way to express to slate that a block is a boundary where merge with external blocks cannot occur. This would solve a lot of corner cases with pasting, drag and drop, and delete range, and it would allow for blocks where the contents are more "securely" contained.

Something that comes to mind is maybe a boolean flag like isVoid except the flag is checked before mergeNode changes are applied.

discussion

All 5 comments

This sounds like a great idea to me. I'd be open to a PR that implemented this in the Schema, and then had the transform code using change.value.schema to check whether a node is mergeable. This would pave the way to moving the isVoid code into the schema as well.

The idea of moving it into the schema is really cool! If nobody else picks this up I think I can explore this next month :)

An question:
Why we want to concat two blocks (if two blocks have different types) after delete?

There are certain block types like paragraph and quote, or list item and paragraph that contextually make sense to merge together. Most editors (that I've seen) have this merging behavior.

Hey guys wanted to give an update. I've not had much time to dive into this, but I did get as far as to identify a bunch of use cases for this behavior, write the corresponding tests, and then get an isAtomic property defined on the schema for a given block type. The isAtomic name is being used also for decorations to define a similar concept, so we're in a good position where we are using consistent terminology.

It's still pretty far from working. Hopefully I'll have time this month!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Slapbox picture Slapbox  路  3Comments

ianstormtaylor picture ianstormtaylor  路  3Comments

yalu picture yalu  路  3Comments

adrianclay picture adrianclay  路  3Comments

ianstormtaylor picture ianstormtaylor  路  3Comments