Text node with mark is unchanged in the document node structure but is changed visually in the DOM representation


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.

Screenshot 2022-09-02 at 9.19.09

Screenshot 2022-09-02 at 9.19.34


Screenshot 2022-09-02 at 9.19.42

Screenshot 2022-09-02 at 9.19.51

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;
          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'){
              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(insNodeStartpos<from&&from<insNodeEndpos){ //  the start of the selection in insertion node
            //should set new sel from=from to=insNodeEndpos
          }else if(insNodeStartpos<to&&to<insNodeEndpos){//  the end of the selection in insertion node
            //should set new sel from=insNodeStartpos to=to
          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. Screenshot 2022-09-02 at 9.37.08

Screenshot 2022-09-02 at 9.37.21

Screenshot 2022-09-02 at 9.37.35

This is logging of the textContent prop in the document node on every transaction.

Screenshot 2022-09-02 at 9.38.02

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",

Are there any node views with update methods involved?

This may also be a bug in the library, of course. Could you try reducing this to a minimal script that shows the behavior?

So I created a new project where I could not reproduce the bug. Then downgraded the prosemirror packages versions and the bug was there. The problem was in the packages versions.

And no there are no custom node views in the editor.