From f9e3813b08b3586134f58cd89eb666d7670d94c5 Mon Sep 17 00:00:00 2001 From: "Fabien \"egg\" O'Carroll" Date: Thu, 20 Apr 2023 10:19:55 +0100 Subject: [PATCH] Updated diff generation to treat cards atomically Rather than displaying changes inside cards, we want to show a complete replacement of the card. The current html diffing library is not capable of supporting this so we have to use the approach here. First we find all cards with changes in them, and then pull out the changes into two duplicated version of the card, once for removals and one for additions. --- .../app/components/modal-post-history.js | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/ghost/admin/app/components/modal-post-history.js b/ghost/admin/app/components/modal-post-history.js index 0b0a144521..f4e06b4c9a 100644 --- a/ghost/admin/app/components/modal-post-history.js +++ b/ghost/admin/app/components/modal-post-history.js @@ -94,6 +94,46 @@ export default ModalComponent.extend({ }; }, + calculateHTMLDiff(previousHTML, currentHTML) { + const result = diff(previousHTML, currentHTML); + const div = document.createElement('div'); + div.innerHTML = result; + const cards = div.querySelectorAll('div[data-kg-card]'); + for (const card of cards) { + const hasChanges = !!card.querySelectorAll('del').length || !!card.querySelectorAll('ins').length; + if (hasChanges) { + const delCard = card.cloneNode(true); + const insCard = card.cloneNode(true); + + const ins = document.createElement('ins'); + const del = document.createElement('del'); + + delCard.querySelectorAll('ins').forEach((el) => { + el.remove(); + }); + insCard.querySelectorAll('del').forEach((el) => { + el.remove(); + }); + delCard.querySelectorAll('del').forEach((el) => { + el.parentNode.appendChild(el.firstChild); + el.remove(); + }); + insCard.querySelectorAll('ins').forEach((el) => { + el.parentNode.appendChild(el.firstChild); + el.remove(); + }); + + ins.appendChild(insCard); + del.appendChild(delCard); + + card.parentNode.appendChild(del); + card.parentNode.appendChild(ins); + card.remove(); + } + } + return div.innerHTML; + }, + updateDiff() { if (this.comparisonEditor && this.selectedEditor) { let comparisonState = this.comparisonEditor.editorInstance.parseEditorState(this.comparisonRevision.lexical); @@ -111,7 +151,7 @@ export default ModalComponent.extend({ let updateIfBothDone = () => { if (previousDone && currentDone) { - this.set('diffHtml', diff(previous.innerHTML, current.innerHTML)); + this.set('diffHtml', this.calculateHTMLDiff(previous.innerHTML, current.innerHTML)); this.set('selectedHTML', current.innerHTML); } };