Hosted ongabo.esvia theHypermedia Protocol

Project: Introducing list node typeThis project explains the problems with our current list implementation and proposes additions to editor schema that should handle lists better.

Problem

Our current list implementation is in blockGroup wrapper node and is achieved with listType attribute. This was originally done to allow different node types in list items, but it introduces several structural and behavioral problems in prosemirror/tiptap, especially on copy paste.

  1. Invalid document structures during copy / paste

    • Copying nested lists produces slices with invalid structure, where a blockContainer has a single blockGroup child.

    • In our schema a blockContainer node must have a blockContent child (paragraph, heading, etc.)

    • BlockNote plugins like UniqueID throw errors because of invalid structure

  2. Paste behavior depends on context

    • When pasting a list in between text it fails to correctly split the text and merge first and last nodes of the slice with the split text.

    • Because of that we either have to lose list items or add more custom complex paste handling.

  3. Copy pasting lists cause insertion of empty content

    • Because the lists are defined in blockGroup, it has to be inserted in a blockContainer node.

    • It's hence required to add an empty blockContainer node with an empty paragraph to insert the pasted list somewhere with a valid structure.

  4. Increasing paste handling complexity

    • We currently rely on several transformPasted hooks and handlePaste plugins. We used to have more but I recently refactored the code to have as little as possible custom paste handling, but there are always new edge cases that need to be handled as well. For example, nested lists, inline paste, markdown paste

Solution

Create dedicated node types:

  • list (attrs: type = ordered | unordered)

  • listItem (this can have a blockContent child, which is all the block types in our schema, so we can still have different node types in a list)

Example structure would be:

list(type=unordered)
  listItem
    paragraph
      list(type=ordered)
        listItem
          heading
        listItem
          image

This way HTML <ul><li> tags map directly to editor nodes, so paste should produce correct slices.

Rabbit Holes

  • Editor blocks to document blocks conversion and document blocks need to be adapted.

  • Markdown import/export need to be adapted.

  • Introducing wrapper nodes that actually have visual differences.

Do you like what you are reading? Subscribe to receive updates.

Unsubscribe anytime