@atlaskit/editor-plugin-show-diff
Version:
ShowDiff plugin for @atlaskit/editor-core
55 lines (54 loc) • 1.7 kB
JavaScript
/**
* Finds the position range (outer bounds) of the top-level block (direct child of doc) that
* contains the range [from, to]. Shared with the `smart` diff type so its block grouping is
* identical to the `block` diff type by construction.
*/
export function getTopLevelBlockAt(doc, from, to) {
return {
from: doc.resolve(from).before(1),
to: doc.resolve(to).after(1)
};
}
/**
* Groups all changes that fall within the same top-level block (direct child of doc)
* and merges them into a single change spanning the full block in both old and new doc.
*/
export function groupChangesByBlock(changes, docA, docB) {
const groups = new Map();
for (const change of changes) {
const blockA = getTopLevelBlockAt(docA, change.fromA, change.toA);
const blockB = getTopLevelBlockAt(docB, change.fromB, change.toB);
if (!groups.has(blockB.from)) {
groups.set(blockB.from, {
fromB: blockB.from,
toB: blockB.to,
fromA: blockA ? blockA.from : change.fromA,
toA: blockA ? blockA.to : change.toA,
changed: []
});
}
const group = groups.get(blockB.from);
if (group) {
group.changed = [...group.changed, ...change.inserted, ...change.deleted];
}
}
return Array.from(groups.values()).sort((a, b) => a.fromB - b.fromB).map(({
fromA,
toA,
fromB,
toB,
changed
}) => ({
fromA,
toA,
fromB,
toB,
/**
* We add all changes (both deleted and inserted) as that will
* inform the calculateDiffDecorations function that changes should be rendered
* (even if the change is only one of the two).
*/
deleted: changed,
inserted: changed
}));
}