Skip to content

Commit 5801c83

Browse files
checkbox diff handling
1 parent 3c67632 commit 5801c83

2 files changed

Lines changed: 42 additions & 0 deletions

File tree

src/render-html-diff.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,27 @@ function hasShallowDifference(
311311
return false;
312312
}
313313

314+
function nodesStructurallyEqual(beforeNode: Node, afterNode: Node): boolean {
315+
if (beforeNode.type !== afterNode.type) return false;
316+
if (beforeNode.type === "text" && afterNode.type === "text") {
317+
return beforeNode.value === afterNode.value;
318+
}
319+
if (beforeNode.type === "element" && afterNode.type === "element") {
320+
if (beforeNode.tagName !== afterNode.tagName) return false;
321+
if (!shallowAttributesEqual(beforeNode, afterNode)) return false;
322+
if (beforeNode.children.length !== afterNode.children.length) return false;
323+
for (let i = 0; i < beforeNode.children.length; i++) {
324+
const beforeChild = beforeNode.children[i]!;
325+
const afterChild = afterNode.children[i]!;
326+
if (!nodesStructurallyEqual(beforeChild, afterChild)) {
327+
return false;
328+
}
329+
}
330+
return true;
331+
}
332+
return false;
333+
}
334+
314335
function renderHtmlDiffInternal(args: {
315336
beforeHtml: string;
316337
afterHtml: string;
@@ -355,6 +376,9 @@ function renderHtmlDiffInternal(args: {
355376
getAttribute(beforeNode, "data-diff-mode");
356377

357378
if (mode === "element") {
379+
if (nodesStructurallyEqual(beforeNode, afterNode)) {
380+
continue;
381+
}
358382
const clone = cloneElement(beforeNode);
359383
setDiffStatus(clone, "removed");
360384
setAttribute(clone, "contenteditable", "false");

src/test-cases.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,24 @@ export const testCasesBySection: Record<string, TestCase[]> = {
9191
<div><div class="card" data-diff-key="complex" data-diff-mode="element" data-diff-status="removed" contenteditable="false">Old content here</div><div class="card" data-diff-key="complex" data-diff-mode="element" data-diff-status="added">New content here</div></div>
9292
`,
9393
},
94+
{
95+
name: "should not duplicate identical element-mode nodes",
96+
beforeHtml: dedent`
97+
<li data-diff-key="item-1" data-diff-mode="element">
98+
<p><input type="checkbox"></input> nice</p>
99+
</li>
100+
`,
101+
afterHtml: dedent`
102+
<li data-diff-key="item-1" data-diff-mode="element">
103+
<p><input type="checkbox"></input> nice</p>
104+
</li>
105+
`,
106+
expectedHtml: dedent`
107+
<li data-diff-key="item-1" data-diff-mode="element">
108+
<p><input type="checkbox"></input> nice</p>
109+
</li>
110+
`,
111+
},
94112
{
95113
name: "should handle element diffing with existing classes",
96114
beforeHtml: dedent`

0 commit comments

Comments
 (0)