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));
|