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:
Semantically Correct
Straight mapping to HTML tags (exclusively <ul> and <ol>)
Easier to debug invalid slices on paste
Copy/Paste
ProseMirror default paste handling shouldn’t result in infinite indentation
Reduces ambiguity when parsing HTML
Future Flexibility
We can add list-specific attributes without affecting regular groups
Can add list-specific commands/plugins
Cons:
Needs to change 7 commands to account for new node types
Needs thorough testing
Requires a lot of time
Risk of introducing bugs