Sounds like you just need to change the attributes, which you can do with setNodeType (pass null for the node type to preserve the existing type, but provide a new set of attributes). Lifting and then wrapping is very unlikely to work – the content of the node may not even be allowed as content of the parent node.
I don’t think that setNodeType solve the problem in this case.
I tried:
let {from, to, $from, $to} = state.selection
let tr=state.tr;
state.doc.nodesBetween(from, to, (node, pos, parent, index) => {
if (node.type == schema.nodes.align) {
tr=tr.setNodeType(pos, schema.nodes.align, { alignment: alignment })
} else {
tr = wrapTr(tr, state.doc.resolve(pos), state.doc.resolve(pos+node.nodeSize), schema.nodes.align, { alignment: alignment})
}
return false;
})
But this does not behave well when aligning a centered/righted block to the left.
The issue is that when aligning to the left (for example a centered block), I have to remove the alignment - that is lift
(using the code above, to left align a centered block, all lines in it will now behave as one block, for example centering one of those lines will center all of them)
Oh, I hadn’t seen that you are using wrapping nodes to do alignment. I’d have done it with an attribute. But if you do use a node, yes, you will have to lift to remove it.
The issue is that unlike center and right which wrap their content, there actually shouldn’t be any left aligned nodes - that is aligning to the left needs to be a lift out of the align attribute node.
The reason is that if you align to the left on any line of for example a centered block, it should move the entire centered block to the left, but if you align to the center on any line of a left aligned block it should only center that line.
Basically aligning to the left needs to removes alignment from the entire centered/righted block, where as aligning a left (unaligned) line to the center/right wraps just that line.
So unless I’m missing something I have to lift which I am not able to successfully achieve