I know this should be simple, creating wrapping input rules, I just can’t seem to get it to work and could use advice on what I messed up. From my code (names changed to keep it simple), the following rule should look for the word ‘run’ and change the node’s “type” attribute to “New Type”. Since each of my types has its own css and margins, that should change how the paragraph looks to the user.
I do pass in my schema properly and the plugin returned by the inputRules is properly being called when text is entered (I added some breakpoints in the editor js code to make sure it is firing properly), but I think the findWrapping function is failing.
export function myInputRule(nodeType) {
return wrappingInputRule(/^(\[Rr\]\[Uu\]\[Nn\])$/, nodeType, {type: “New Type”})
}
export function buildMyInputRules(schema) {
let nodeType, rules=\[\]
if (nodeType = schema.nodes.myNodeType) rules.push(myInputRule(nodeType))
return inputRules({rules})
}
My goal here is that for any text entered at the start of any myNodeType node, if it matches ‘run’, it should change the “type” attribute of that node. Of course not happening (hence this post!)
Is your node type a type that actually wraps textblocks (the way blockquotes and lists do in the basic schema) or are you maybe looking for textblockTypeInputRule instead?
My custom nodes are all defined as content: “text*”, a very simple structure. So I do believe it is mynode->textnode as the hierarchy within a node. I guess all typical top level nodes in PM contain text blocks inside them, that is what ends up having the underlying contents.
So, not sure which wrapper to use, what I know right now is that it isn’t working to change the attribute of the containing node.
I changed the inputrule type to a textblockTypeInputRule (as suggested as an alternative) and while it did change the node attribute properly to the new paragraph type, it deleted the text that was typed. I do not want the text to go away (as might be wanted with some input rules that are really just shortcuts), so how do I change the block type and keep the typed text, which is really a trigger looking for text that always starts certain specialized node types in my system? I don’t see any parameters for that, and even the rules in the core such as smartquotes just use set replacement text but without a node type.
Update: As marijn suggested, I decided to create my own input rule instead of using the built in wrappers (they both seem to replace the text with an empty paragraph), and in it I call tr.setNodeMarkup to change the attributes properly. I could have probably called setBlockType or others, but in this case I just want different attributes.
However, it seems the final matching character that triggers the rule is NOT retained, so if I was matching the word “WORK”, changing the block attributes with that match, the resulting paragraph would just contain “WOR”.
How do I get the input rules to keep all the typed characters?
The rule fires on the text that is typed, before it is added to the actual document. If you want to preserve it, you’ll have to explicitly insert the part that isn’t there yet from the rule’s code (or, probably easier, take the whole content of the match and make that the content of the block).