Hosted onnoosphere.hyper.mediavia theHypermedia Protocol

What’s done

Added 2 node types called listGroup and listContainer:

  • listGroup maps to <ul><ol> and <blockquote> tags and listContainer maps to <li>

  • listGroup can contain only listContainers as children

  • listContainer is similar to blockContainer, as the first child is mandatory and it can be any blockContent, and the second optional child can be a listGroup or a blockGroup to create indentation

Schema

blockGroup: content: 'blockContainer+

listGroup: content: 'listContainer+

blockContainer and listContainer: content: 'blockContent (blockGroup | listGroup)? (block content + optional group)

Complexity

When interacting with a list, we constantly need to convert between group and container types

  • Input rules such as “*” and “1”: Create listGroup with listContainer inside previous blockContainer

  • Tab: If inside of a blockContainer but sinking into a listGroup, we need to manually build a listContainer from that blockContainer and insert it. SinkListItem command results in an invalid structure and error.

  • Shift Tab: Same as tab, need to manually build and insert instead of liftListItem command.

  • Backspace: Same as shift tab if at the start of list/block container or in an empty container

So the problem is that when converting node types, instead of just using the inbuilt lift or sink commands, we need to correctly calculate and track previous and current group positions and depths, check for siblings inside the current group, check for empty nodes, etc.

Therefore, every command that touches groups/containers needs awareness of both node types:

  • updateGroup.ts: used to update listType and listLevel attributes of blockGroup. Now needs to correctly convert between node types

  • nestBlock.ts: has custom sink and lift list item commands. Used with tab, shift-tab, backspace and delete keys

  • splitBlock.ts: used with enter key. Command to split text node and insert it as a next node while respecting the group type and depth

  • mergeBlocks.ts: used with backspace and delete keys. Command to merge the current block with the previous. Needs to respect container type and depth.

Pros and cons

Dedicated list node types:

Pros:

  1. Semantically Correct

    • Straight mapping to HTML tags (exclusively <ul> and <ol>)

    • Easier to debug invalid slices on paste

  2. Copy/Paste

    • ProseMirror default paste handling shouldn’t result in infinite indentation

    • Reduces ambiguity when parsing HTML

  3. Future Flexibility

Cons:

  1. Needs to change 7 commands to account for new node types

  2. Needs thorough testing

  3. Requires a lot of time

  4. Risk of introducing bugs

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

Unsubscribe anytime