import { EditorState, Transaction } from "prosemirror-state"; import { HighlightRange, RangeType } from "../range/types"; import { RangeCreateStep } from "../range/RangeCreateStep"; import { getPluginStateOrThrow as getRangePluginStateOrThrow } from "../range/RangePlugin"; import uuidv1 from "uuid/v1"; import { RangeSetAttrsStep } from "../range/RangeSetAttrsStep"; import { RangeDeleteStep } from "../range/RangeDeleteStep"; export function upsertTagToHighlight( editorState: EditorState, highlight: { from: number; to: number }, tagId: string, tr = editorState.tr ): Transaction { const rangePluginState = getRangePluginStateOrThrow(editorState); const existingRange = rangePluginState.sortedRanges.find( (range): range is HighlightRange => range.from === highlight.from && range.to === highlight.to && range.type === RangeType.HIGHLIGHT ); if (existingRange !== undefined) { const tagIds = new Set(existingRange.attrs.tagIds); tagIds.add(tagId); return tr.step( new RangeSetAttrsStep(existingRange.id, existingRange.type, existingRange.attrs, { tagIds: [...tagIds] }) ); } else { return tr.step(new RangeCreateStep({ id: uuidv1(), type: RangeType.HIGHLIGHT, ...highlight, attrs: { tagIds: [tagId] } })); } } export function removeTagFromHighlight( editorState: EditorState, highlight: { from: number; to: number }, tagId: string, tr = editorState.tr ): Transaction { const rangePluginState = getRangePluginStateOrThrow(editorState); const existingRange = rangePluginState.sortedRanges.find( (range): range is HighlightRange => range.from === highlight.from && range.to === highlight.to && range.type === RangeType.HIGHLIGHT ); if (existingRange === undefined) { throw new Error(`Unable to delete range with id=${existingRange}, as it was not found.`); } const tagIds = new Set(existingRange.attrs.tagIds); tagIds.delete(tagId); if (tagIds.size > 0) { return tr.step( new RangeSetAttrsStep(existingRange.id, existingRange.type, existingRange.attrs, { tagIds: [...tagIds] }) ); } else { return tr.step(new RangeDeleteStep(existingRange)); } }