UNPKG

@atlaskit/editor-plugin-show-diff

Version:

ShowDiff plugin for @atlaskit/editor-core

50 lines (47 loc) 2.04 kB
import { Transform } from '@atlaskit/editor-prosemirror/transform'; /** * Returns a copy of the document with all marks removed from all text. * This normalises mark fragmentation — e.g. annotation marks reordering can split * a single text run into many text nodes, making structural comparison unreliable. * After stripping, ProseMirror will merge adjacent text nodes so childCounts are stable. */ function stripMarks(doc) { const tr = new Transform(doc); tr.removeMark(0, doc.content.size); return tr.doc; } /** * Returns true if both (mark-stripped) nodes have the same block tree structure (node type and child count at every level) */ function isBlockStructureEqual(node1, node2) { if (node1.type !== node2.type || node1.childCount !== node2.childCount) { return false; } for (let i = 0; i < node1.childCount; i++) { if (!isBlockStructureEqual(node1.child(i), node2.child(i))) { return false; } } return true; } /** * Looser equality for "safe diff" cases: same full text content and same block structure * (e.g. text moved across text-node boundaries). Used when strict areNodesEqualIgnoreAttrs fails. * This is safe because we ensure decorations get applied to valid positions. * * Marks are intentionally ignored — two documents that differ only in mark application * (e.g. bold/italic boundaries or annotation mark ordering) are considered equal here. * Both documents are mark-stripped before comparison so that mark-driven text fragmentation * does not produce false inequalities. */ export function areDocsEqualByBlockStructureAndText(doc1, doc2) { if (doc1.textContent !== doc2.textContent) { return false; } // Strip marks before comparing so that mark-driven text fragmentation // (e.g. annotation mark reordering producing different childCounts) does not // cause false inequalities. const stripped1 = stripMarks(doc1); const stripped2 = stripMarks(doc2); return doc1.nodeSize === doc2.nodeSize && isBlockStructureEqual(stripped1, stripped2); }