Steps to reproduce:
plainRemoval = new ve.dm.Transaction( [ { type: 'replace', remove: [ 'x' ], insert: [] }, { type: 'retain', length: 10 } ] ); insertionWithRef = new ve.dm.Transaction( [ { type: 'replace', remove: [], insert: [ 'y' ] }, { type: 'retain', length: 10 }, { type: 'replace', remove: [], insert: [ 'z' ] }, { type: 'retain', length: 1 } ] ); x = ve.dm.Change.static.rebaseTransactions( plainRemoval, insertionWithRef );
Desired behaviour: x is a successful rebase: the transactions 'obviously' don't conflict.
Observed behaviour: x is [ null, null ] - the transactions conflict.
But we can't just solve this algorithmically on the linearized form by allowing transactions of that "shape", because if we form tx3 from insertionWithRef by replacing 'y' and 'z' with <p> and </o> respectively, then we need the rebase to fail, else plainRemoval.concatRebased(tx3).reversed() is a transaction that removes paragraph tags then adds text where they used to be, which violates VE HTML validity. This shows we need the "entirely before or entirely after" property for rebasing: it is what guarantees the tree branch context at each replace operation cannot be changed by rebasing.
Therefore, we may need to change the use of newFromDocumentInsertion so that references are inserted in a separate transaction.