In a particular circumstence, i had to insertText in a pararaph node generated by the toDom of a certain custom node:
const nodeStartPos = vm.findNodePosition(doc, oldEditorParagraph);
tr = tr.insertText(textContent, nodeStartPos + 1, nodeStartPos + 1 + oldEditorParagraph.content.size);
const textNode = tr.doc.content.content[0].content.content[0].content.content[0].content.content[0];
const textNodeStartPos = vm.findNodePosition(tr.doc, textNode);
const newSelection = TextSelection.create(tr.doc, textNodeStartPos + textNode.text.length);
tr = tr.setSelection(newSelection);
view.updateState(view.state.apply(tr));
I noticed that after calling tr.insertText(), the previous selection is lost, that’s why i’m trying to reset it with tr.setSelection(newSelection) to get the selection back at the end of the newly inserted text.
I wonder what should be the second parameter value passed to TextSelection.create() (which is the $head parameter). I have been trying many expressions , finally i came with this textNodeStartPos + textNode.text.length which i think the most logical but it’s not working neither.
The problem is that i never get the selection back.
Another better solution is to force the paragraph inside the editorTitleHeader node to have a text node as content initially even when it’s empty. If so, it won’t be needed to insert text, just to update the pre-existing text node text property. I couldn’t do that throught the node’s definition.
Any clue please?
Here are my custom nodes (if needed)
const editorTitleHeader = {
name: 'editorTitleHeader',
inlineContent: true,
content: 'paragraph',
isTextblock: true,
attrs: {
'data-before-content': { default: 'Untitled item' },
},
parseDOM: [
{
tag: 'editor-title-header[data-before-content]',
getAttrs(dom) {
return true;
},
},
],
toDOM(node) {
const inner = document.createElement('editor-title-header');
inner.classList.add('editorTitleHeaderCls');
let textContent = '';
if (
node.content &&
node.content.content &&
node.content.content[0] &&
node.content.content[0].content &&
node.content.content[0].content.content &&
node.content.content[0].content.content[0] &&
node.content.content[0].content.content[0].text
) {
textContent = node.content.content[0].content.content[0].text;
}
inner.textContent = textContent;
return inner;
},
};
const editorTitle = {
name: 'editorTitle',
content: 'editorTitleHeader',
isTextblock: true,
attrs: {
class: { default: 'editorTitleCls' },
},
parseDOM: [
{
tag: 'div[class]',
getAttrs(dom) {
return dom.getAttribute('class') == 'editorTitleCls';
},
},
],
toDOM(node) {
return ['div', { class: 'editorTitleCls' }, 0];
},
persistContent(newState) {
proseMirrorOnChangeHandler(null, newState, mySchema, props);
},
};
I tired to reproduce the selection bug in this codesandbox but it seems that the stopEvent of the editorTitleView class isn’t working in that demo which prevents the ‘input’ listener from being triggered (i dunno why , in my app it all works fine)