Hello.
So I have marks that represent user’s deleted and inserted text. I have implemented logic that prevents deletion of nodes with deletion mark when the user is trying to replace a selection that is inside nodes with deletion and insertion marks at the same time.
or
In both cases I want to leave the node with the deletion mark unchanged and change only the node with insertion mark.
My approach is using the handleTextInput function. I change the selection and then replace the insertion node with the input text.
handleTextInput(this, view, from, to, text) {
let delNode:any
let delNodeStartpos:any
let delNodeEndpos:any
let insNode:any
let insNodeStartpos:any
let insNodeEndpos:any
let textnodeWithNoMarks = false;
view.state.doc.nodesBetween(from,to,(node,pos)=>{
let deleteMarkInNode = node.marks.find((mark)=>mark.type.name=="deletion")?node:undefined;
let insertionMarkInNode = node.marks.find((mark)=>mark.type.name=="insertion")?node:undefined;
if(node.type.name == 'text'){
if(deleteMarkInNode&&!delNode){
delNode = deleteMarkInNode
delNodeStartpos = pos
delNodeEndpos = pos+node.nodeSize
}else if(insertionMarkInNode&&!insNode){
insNode = insertionMarkInNode
insNodeStartpos = pos
insNodeEndpos = pos+node.nodeSize
}else if(node.marks.length == 0){
textnodeWithNoMarks = true;
}
}
})
if(!textnodeWithNoMarks&&delNode&&insNode){
if(insNodeStartpos<from&&from<insNodeEndpos){ // the start of the selection in insertion node
//should set new sel from=from to=insNodeEndpos
view.dispatch(view.state.tr.setSelection(TextSelection.between(view.state.tr.doc.resolve(from),view.state.tr.doc.resolve(insNodeEndpos),-1)).replaceSelectionWith(schema.text(text)))
}else if(insNodeStartpos<to&&to<insNodeEndpos){// the end of the selection in insertion node
//should set new sel from=insNodeStartpos to=to
view.dispatch(view.state.tr.setSelection(TextSelection.between(view.state.tr.doc.resolve(insNodeStartpos),view.state.tr.doc.resolve(to),1)).replaceSelectionWith(schema.text(text)))
}
return true;
}
return false;
}
So this works and the node structure is changed accordingly - the node with the deletion mark is not change and the node with the insertion mark is changed. But in the DOM structure both the nodes change.
This is logging of the textContent prop in the document node on every transaction.
I am using Yjs(y-prosemirror) for collaboration, and when I try this with two browsers the problem is displayed only on the person who is making the change.On the other browser the deletion node is not changed in the DOM. After refresh or typing in the deletion node the node is back to normal.
So the node changes only in the DOM for some reason. Is there a way to trigger render on all nodes.
PM versions :
"prosemirror-collab": "^1.2.2",
"prosemirror-commands": "1.1.10",
"prosemirror-dropcursor": "^1.3.5",
"prosemirror-example-setup": "^1.1.2",
"prosemirror-gapcursor": "^1.2.0",
"prosemirror-highlightjs": "^0.2.0",
"prosemirror-history": "^1.2.0",
"prosemirror-inputrules": "^1.1.3",
"prosemirror-keymap": "1.1.4",
"prosemirror-markdown": "^1.7.1",
"prosemirror-menu": "^1.1.4",
"prosemirror-model": "^1.14.3",
"prosemirror-paste-rules": "^1.0.2",
"prosemirror-schema-basic": "^1.1.2",
"prosemirror-schema-list": "^1.1.6",
"prosemirror-state": "1.3.4",
"prosemirror-tables": "^1.1.1",
"prosemirror-transform": "1.3.2",
"prosemirror-view": "1.20.1",