Combine Multiple transactions into one history step [SOLVED]

So I have a code which applies alignment classes (text-left, text-right etc …) to the selection by looping through the nodes. It works well except that the line view.dispatch(view.state.tr.setNodeMarkup(pos, null, attrs )); produces multiple history steps.

How would I go about it if I wanted all the changes to be included in just one history step ? Thank you !

export function alignSelection(view, classKey, classes){
    const selection = view.state.selection;

    view.state.doc.nodesBetween(selection.from, selection.to, (node, pos) => {

        if(!classes[classKey]){
            console.error(classes);
            throw 'Class does not exist with a key: '+classKey;
        }

        if(node.type.spec.canTakeAligment){
            // remove alignment classes
            let className = '';
            if(node.attrs.class){
                className = node.attrs.class;
                Object.keys(classes).forEach(key =>{
                    className = className.replace(classes[key], '');
                });
            }
            className = className.trim();
            className += ' '+classes[classKey];
            className = className.trim();

            let attrs = { ...node.attrs, 'class': className};
            view.dispatch(view.state.tr.setNodeMarkup(pos, null, attrs ));
        }
    });
}

Combine the changes into a single transaction.

Is this what you mean ? I have now added every change as a step to a transaction and dispatch that transaction only once. Seems to work fine …

export function alignSelection(view, classKey, classes){
    console.log('alignSelection');
    const selection = view.state.selection;

    let transaction = view.state.tr;
    view.state.doc.nodesBetween(selection.from, selection.to, (node, pos) => {

        if(!classes[classKey]){
            console.error(classes);
            throw 'Class does not exist with a key: '+classKey;
        }

        if(node.type.spec.canTakeAligment){
            // remove alignment classes
            let className = '';
            if(node.attrs.class){
                className = node.attrs.class;
                Object.keys(classes).forEach(key =>{
                    className = className.replace(classes[key], '');
                });
            }
            className = className.trim();
            className += ' '+classes[classKey];
            className = className.trim();

            let attrs = { ...node.attrs, 'class': className};
            const type = node.type
            let newNode = type.create(attrs, null, node.marks)

            transaction.step(
                new ReplaceAroundStep(pos, pos + node.nodeSize, pos + 1, pos + node.nodeSize - 1, new Slice(Fragment.from(newNode), 0, 0), 1, true)
            )
        }
    });

    if(transaction.docChanged){
        view.dispatch(transaction);
    }
}

Indeed.

1 Like