Tablecell, AppendTransaction, setNodeMarkup and Undo

HI Marjin, First of all, thank you for the solidly engineered prosemirror. We are building our product around this editor. I had a quick question regarding tables, I am setting a custom attribute in tablecell based on content within the cell, using appendTransaction & setNodeMarkup. The attribute of course gets set (has no change in the document in UI). However when user does UNDO the attribute doesn’t get reverted. Is this expected? Do you have any recommendations to work around this?

Thank you!!

That should only happen if the transaction to which your update is appeneded has addToHistory set to false. If it behaves differently, can you reduce the problem to as small a script/schema as possible so that I can take a look?

Hi Marijn, Following is the Schema

table_cell: {
  content: 'block+',
  attrs: {
    colspan: {default: 1},
    rowspan: {default: 1},
    colwidth: {default: [180]},
    hasComment: {default: false}
  tableRole: "cell",
  isolating: true,
  parseDOM: [{tag: "td", getAttrs: dom => getCellAttrs(dom, extraAttrs)}],
  toDOM(node) { return ["td", setCellAttrs(node, extraAttrs), 0] }

Following is the plugin for append transaction:

get plugins() {
  return [
    new Plugin({
      appendTransaction(transaction, oldState, newState) {
        const { tr, schema } = newState
        // Init new transaction.
        let newTrans = tr

        if (transaction[0].docChanged) {
          const { selection, schema } = newState
          // get the cursor position
          const currentPos = selection.$cursor
              ? selection.$cursor.pos
              : selection.$to.pos;
          // Get table cell nodes 
          // `findParentNodeClosestToPos` from prosemirror-utils
          const cell = findParentNodeClosestToPos(
                    (node) => { return node.type === schema.nodes.table_cell }
          if (cell) {
            const { pos, node: { attrs } } = cell        
            // Check hasComment attr value from node attribute
            if (attrs && !attrs.hasComment) {
              newTrans = tr.setNodeMarkup(
                pos, null, { ...attrs, hasComment: true } // Set hasComment attr to true
        // Append the new transaction with the existing list.
        return newTrans

That’s not a self-contained script, nor has it been reduced to the minimum needed to reproduce the issue.

In any case, an appendTransaction function that always appends a transaction, like the plugin you shows does, would just immediately lock up the editor or cause a stack overflow, so that’s something to keep in mind.

Thank you for the point on AppendTransaction,… let me do a quick plugin approach and revert. Happy holidays!