Reset (some) node attributes when split (paragraph)

Hi,

Is there a way to reset all or some node attribute when the node is split?

My issue concerns paragraphs with id attribute (use for internal links). When the cursor is not at the end of a paragraph & user hit ENTER, the paragraph is split but both (new & old) paragraph keep the original id attribute …

Any way to prevent this behavior? (it does not happen when cursor is at the end).

Thx !

You could write your own command to handle enter, which reassigns an id to the split-off part of the node, but there’s many things in ProseMirror that can cause nodes to be copied or split (copy/paste, drag/drop, various commands that change document structure), so maintaining unique ids is usually done with an appendTransaction hook that checks for duplicated or missing ids, and reassigns them.

1 Like

Something similar to this works like a charm :

const anchorNodeName = ['paragraph', 'heading']

const pluginDef: PluginSpec = {

  appendTransaction(_: [Transaction], __: EditorState, state: EditorState): Transaction | null | undefined | void {
    let documentIds: Record<string, boolean> = {}
    let transaction: Transaction | undefined

    // Check for duplicated anchor IDs
    state.doc.descendants((node, pos) => {
      if (anchorNodeName.includes(node.type.name) && node.attrs?.id) {
        let anchorId = node.attrs.id

        // Replace or delete if
        if (documentIds[anchorId]) {

          if (!transaction) {
            transaction = state.tr
          }

          anchorId = nanoid()
          transaction.setNodeMarkup(pos, node.type, assign({}, node.attrs, {
            id: anchorId // new id for header
          }))
        }

        documentIds[anchorId] = true
      }
    })
    return transaction
  }
}

export default function() {
  return new Plugin(pluginDef)
}

Thx @marijn

1 Like