Insert match in toDOM

Hello ProseMirror community,

I’m trying to fix a bug in the Nextcloud Text app: its ListItem node defines an input rule /^\s*([-+*])\s[^\s[]$/ to start a list item, which results in the first key after /^\s*([-+*])\s being eaten. That’s rather annoying.

My idea was to catch the entered key (as a regex match) and insert it as text content of the node in toDOM. But apparently that doesn’t work as expected.

Catching the key works as expected:

export default class ListItem extends TiptapListItem {
	[...]
	get schema() {
		return {
			attrs: {
				done: {
					default: false,
				},
				type: {
					default: TYPES.BULLET,
				},
				appendix: {
					default: '',
				},
			},
			[...]
		}
	}

	[...]

	inputRules({ type }) {
		return [
			[...],
			wrappingInputRule(/^\s*([-+*])\s([^\s[])$/, type, (match) => {
				return { appendix: match[2] }
			}),
		]
	}

With this code, node.atts.appendix contains the single character at the end of the regex (e.g. t if I entered * t).

But I fail to add node.attrs.appendix (match[2] from the input rule) as content in toDOM():

	get schema() {
		return {
			[...],
			toDOM: node => {
				if (node.attrs.type === TYPES.BULLET) {
					return [
						'li',
						{ contentEditable: true },
						`$(node.attrs.appendix)`,
					]
				}
			},
			[...]
		}
	}

With the code above, when entering * t, I indeed get a list item with t as content, but the cursor immediately jumps up one line and everything behaves rather weird.

I’m pretty new to prosemirror and still struggeling to find my way through. Any hint about what I’m doing wrong would be highly appreciated :slight_smile:

Cheers jonas

toDOM is definitely not the place to insert a character—that is responsible for rendering nodes of the given type, not updating/creating them. I suppose you’ll need to write logic similar to what’s in wappingInputRule, but which inserts the character in the transaction triggered by the input rule.

Could this just be solved with a simpler matching regex? For bullet lists, I’m just using

wrappingInputRule(/^([-+*])\s$/, enumListType)

Hey @bhl, thanks for the suggestion. Unfortunately it’s not an option for the Nextcloud Text app. It already uses rule /^\s*([-+*])\s(\[(x|X)\])\s$/ for checkboxes, so the simple rule /^([-+*])\s$/ would conflict with that one.

Thanks @marijn, that’s good to know. Do you by chance have a link to a simple example how to alter the transaction triggered by the input rule?

You can only really do that when the input rule is custom-written.

Perfect, thanks for the hint, @marijn. I came up with a working solution now:

Don’t hesitate to tell me if you see a problem with the code :wink: