They both independently scan from one side of the document. So if you are for example comparing the content “abc” to “abbc”, the scan from the start will find the first difference at 2 (c vs b after “ab”), and the scan from the end will find the first difference at 1/2 (a vs b before “bc”). Those overlap.
This subtle detail confused me a good bit as well.
I ended up writing the function below for our application to get a more or less guaranteed-to-be-correct diff range for the updated document (latest state), for example in an appendTransaction context.
/**
* Get start and end diff position values for two states (old, new).
* @param {EditorState} oldState - last PM state
* @param {EditorState} newState - current PM state
* @returns {object} - { start, end }
*/
function getDiffRange (oldState, newState) {
// https://prosemirror.net/docs/ref/#model.Fragment.findDiffStart
const start = oldState.doc.content.findDiffStart(newState.doc.content)
// Important: diffEnd value is {a,b} object since end pos will differ.
// https://prosemirror.net/docs/ref/#model.Fragment.findDiffEnd
let { a, b } = oldState.doc.content.findDiffEnd(newState.doc.content)
// WARNING: diffEnd may be lower than diffStart.
// If so, add overlap to get correct range.
// https://discuss.prosemirror.net/t/overlap-handling-of-finddiffstart-and-finddiffend/2856
const overlap = start - Math.min(a, b)
if (overlap > 0) b += overlap
return { start, end: b }
}
I think this is the correct approach, please let me know if I misunderstood anything.