Skip to content

Commit

Permalink
fix: Diff detection
Browse files Browse the repository at this point in the history
  • Loading branch information
areknawo committed Jun 25, 2024
1 parent b174331 commit a5dbae2
Showing 1 changed file with 30 additions and 17 deletions.
47 changes: 30 additions & 17 deletions packages/backend/src/lib/content-processing/diff.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { DocJSON } from "./conversions";
import * as JSONDiff from "jsondiffpatch";
import diff_match_patch, { diff_match_patch as DiffMatchPatch, Diff } from "diff-match-patch";
import { diff_match_patch as DiffMatchPatch, Diff } from "diff-match-patch";

const objectHash = (input: object): string => {
const obj = input as DocJSON;
Expand All @@ -15,7 +15,6 @@ const objectHash = (input: object): string => {
let outputValue = value;
if (key === "width" || key === "aspectRatio" || key === "autoDir" || key === "diff") return;
if (["heading", "paragraph"].includes(obj.type) && key === "id") return;
if (typeof value === "object") {
outputValue = JSON.stringify(input, Object.keys(input).sort());
Expand All @@ -27,6 +26,7 @@ const objectHash = (input: object): string => {
};
const generateDiffDocument = (oldContent: DocJSON, newContent: DocJSON): any => {
const differ = JSONDiff.create({
arrays: { detectMove: false },
propertyFilter(name) {
return name !== "autoDir" && name !== "diff" && name !== "width" && name !== "id";
},
Expand Down Expand Up @@ -117,12 +117,22 @@ const generateDiffDocument = (oldContent: DocJSON, newContent: DocJSON): any =>
arrayDelta: JSONDiff.ArrayDelta
): DocJSON[] => {
const output: DocJSON[] = [];
const unchangedBlocks: DocJSON[] = [];
const maxIndex = Math.max(oldContentLevel.length, newContentLevel.length);

for (let i = 0; i < maxIndex; i++) {
const oldContent = oldContentLevel[i];
const newContent = newContentLevel[i];

if (
(!arrayDelta[`${i}`] && !arrayDelta[`_${i}`]) ||
(!arrayDelta[`_${i}`] && arrayDelta[`${i}`] && !arrayDelta[`${i - 1}`]) ||
(!arrayDelta[`${i}`] && arrayDelta[`_${i}`] && !arrayDelta[`_${i - 1}`])
) {
output.push(...unchangedBlocks);
unchangedBlocks.length = 0;
}

if (oldContent && oldContent.type !== "text" && !oldContent.content) {
oldContent.content = [];
}
Expand All @@ -131,23 +141,33 @@ const generateDiffDocument = (oldContent: DocJSON, newContent: DocJSON): any =>
newContent.content = [];
}

if (!arrayDelta[`${i}`] && !arrayDelta[`_${i}`] && newContent) {
// No change
output.push(newContent);
continue;
}

if (oldContent && arrayDelta[`_${i}`]) {
// Block removed
oldContent.attrs = oldContent.attrs || {};
oldContent.attrs.diff = "removed";
output.push(oldContent);
}

if (newContent && oldContent && arrayDelta[`${i}`] && !Array.isArray(arrayDelta[`${i}`])) {
if (newContent && !arrayDelta[`${i}`]) {
// Block unchanged
if (!arrayDelta[`${i}`] && !arrayDelta[`_${i}`]) {
output.push(newContent);
} else {
unchangedBlocks.push(newContent);
}
}

if (newContent && arrayDelta[`${i}`] && Array.isArray(arrayDelta[`${i}`])) {
// Block added
newContent.attrs = newContent.attrs || {};
newContent.attrs.diff = "added";
output.push(newContent);
}

if (newContent && arrayDelta[`${i}`] && !Array.isArray(arrayDelta[`${i}`])) {
const objectDelta = arrayDelta[`${i}`] as JSONDiff.ObjectDelta;

// Nested change
// Block changed inside
if (newContent.type === "heading" || newContent.type === "paragraph") {
const contentChanged = objectDelta.content && `${objectDelta.content}`;
const textArrayDelta = objectDelta.content as JSONDiff.ArrayDelta;
Expand Down Expand Up @@ -187,13 +207,6 @@ const generateDiffDocument = (oldContent: DocJSON, newContent: DocJSON): any =>
});
}
}

if (newContent && Array.isArray(arrayDelta[`${i}`])) {
// Block added
newContent.attrs = newContent.attrs || {};
newContent.attrs.diff = "added";
output.push(newContent);
}
}

return output;
Expand Down

0 comments on commit a5dbae2

Please sign in to comment.