All files / src/pages/AcquirerPortal/LegalDocuments/LegalDocumentDetail contentDirty.ts

90% Statements 9/10
100% Branches 7/7
100% Functions 3/3
88.88% Lines 8/9

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36            7x 22x                     7x 22x 19x 19x                     7x 10x    
import {
  RawDraftContentState,
  convertFromRaw,
  convertToRaw,
} from "draft-js";
 
const isRawDraftContent = (value: unknown): value is RawDraftContentState =>
  !!value &&
  typeof value === "object" &&
  Array.isArray((value as RawDraftContentState).blocks);
 
// `convertToRaw` renumbers a document's `entityMap` keys canonically ("0","1",…)
// in encounter order, and rewrites each `entityRange.key` to match. Server-stored
// content may carry non-canonical keys (authored/migrated/restored elsewhere), so
// a raw-vs-raw JSON compare against the editor's `convertToRaw` output reports a
// no-op mount echo as a change on any document that contains a link or image.
// Normalising both sides through convertFromRaw→convertToRaw compares canonical
// content only, so entity-key renumbering never reads as an edit.
export const normalizeRawContent = (content: unknown): unknown => {
  if (!isRawDraftContent(content)) return content ?? null;
  try {
    return convertToRaw(convertFromRaw(content));
  } catch {
    // Malformed raw (e.g. an entityRange referencing a missing key) — fall back
    // to the value as-is rather than throwing during a keystroke.
    return content;
  }
};
 
// Structural equality of two Draft.js raw contents. Used to tell a genuine edit
// from the editor merely re-emitting its initial state on mount — the latter must
// not count as a change, otherwise just opening the editor looks "dirty".
export const rawContentEquals = (a: unknown, b: unknown): boolean =>
  JSON.stringify(normalizeRawContent(a)) ===
  JSON.stringify(normalizeRawContent(b));