Hi, I’m trying to create an inline math node by modifying the footnotes example. The original source code for footnotes is here. For the most part, my math node is unchanged from the footnotes node; there are two exceptions:
-
Instead of focus shifting from the outer editor only when the inner editor is clicked upon, now clicks and arrow navigation keys can trigger the focus.
-
Instead of footnotes being inserted into the outer editor by a menu click and the inner editor content initialization dependent on current selection, the math nodes are inserted via an input rule that initializes content based on matching regex. I’ve tried to implement that below.
new InputRule(/(?:\$)([^\$]+)(?:\$)$/, (state, match, start, end) => {
const attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs
const [matchedText, content] = match;
const {tr} = state;
if (matchedText) {
// Create new Math node with content.
const node = type.create(attrs, schema.text(content));
tr.replaceWith(start, end, node);
const cpos = tr.doc.resolve(tr.selection.anchor - tr.selection.$anchor.nodeBefore.nodeSize);
tr.setSelection(new NodeSelection(cpos));
}
return tr
})
The main problem with this implementation is that after the new math node is placed into the outer editor, and no new edits are made in the inner editor, any neighboring edit in the outer editor deletes the content of the inner editor. I’ve found that this problem does not occur if I make an edit in the inner editor directly after its initialization.
Using the prosemirror-devtools, I’ve found this problem is due to a single transaction which both inserts the new edit in the outer editor, and deletes content in the inner editor.
Since this problem does not occur if an edit is made in the inner editor directly after its initialization, I believe this is a problem with how I am creating a nodeview with an editor using inputrules. What is a correct way to do this?
My intuition says that, while new edits in the inner editor are synced to the outer editor via the dispatchInner function,
dispatchInner(tr) {
let {state, transactions} = this.innerView.state.applyTransaction(tr)
this.innerView.updateState(state)
if (!tr.getMeta("fromOutside")) {
let outerTr = this.outerView.state.tr, offsetMap = StepMap.offset(this.getPos() + 1)
for (let i = 0; i < transactions.length; i++) {
let steps = transactions[i].steps
for (let j = 0; j < steps.length; j++)
outerTr.step(steps[j].map(offsetMap))
}
if (outerTr.docChanged) this.outerView.dispatch(outerTr)
}
}
the initial edits made during node creation in inputrules aren’t synced and thus are deleted.