UNPKG

14.5 kBSource Map (JSON)View Raw
1{"version":3,"file":"index.js","sources":["../src/history.ts","../src/history-editor.ts","../src/with-history.ts"],"sourcesContent":["import { isPlainObject } from 'is-plain-object'\nimport { Operation, Range } from 'slate'\n\ninterface Batch {\n operations: Operation[]\n selectionBefore: Range | null\n}\n\n/**\n * `History` objects hold all of the operations that are applied to a value, so\n * they can be undone or redone as necessary.\n */\n\nexport interface History {\n redos: Batch[]\n undos: Batch[]\n}\n\n// eslint-disable-next-line no-redeclare\nexport const History = {\n /**\n * Check if a value is a `History` object.\n */\n\n isHistory(value: any): value is History {\n return (\n isPlainObject(value) &&\n Array.isArray(value.redos) &&\n Array.isArray(value.undos) &&\n (value.redos.length === 0 ||\n Operation.isOperationList(value.redos[0].operations)) &&\n (value.undos.length === 0 ||\n Operation.isOperationList(value.undos[0].operations))\n )\n },\n}\n","import { BaseEditor, Editor } from 'slate'\nimport { History } from './history'\n\n/**\n * Weakmaps for attaching state to the editor.\n */\n\nexport const HISTORY = new WeakMap<Editor, History>()\nexport const SAVING = new WeakMap<Editor, boolean | undefined>()\nexport const MERGING = new WeakMap<Editor, boolean | undefined>()\n\n/**\n * `HistoryEditor` contains helpers for history-enabled editors.\n */\n\nexport interface HistoryEditor extends BaseEditor {\n history: History\n undo: () => void\n redo: () => void\n writeHistory: (stack: 'undos' | 'redos', batch: any) => void\n}\n\n// eslint-disable-next-line no-redeclare\nexport const HistoryEditor = {\n /**\n * Check if a value is a `HistoryEditor` object.\n */\n\n isHistoryEditor(value: any): value is HistoryEditor {\n return History.isHistory(value.history) && Editor.isEditor(value)\n },\n\n /**\n * Get the merge flag's current value.\n */\n\n isMerging(editor: HistoryEditor): boolean | undefined {\n return MERGING.get(editor)\n },\n\n /**\n * Get the saving flag's current value.\n */\n\n isSaving(editor: HistoryEditor): boolean | undefined {\n return SAVING.get(editor)\n },\n\n /**\n * Redo to the previous saved state.\n */\n\n redo(editor: HistoryEditor): void {\n editor.redo()\n },\n\n /**\n * Undo to the previous saved state.\n */\n\n undo(editor: HistoryEditor): void {\n editor.undo()\n },\n\n /**\n * Apply a series of changes inside a synchronous `fn`, without merging any of\n * the new operations into previous save point in the history.\n */\n\n withoutMerging(editor: HistoryEditor, fn: () => void): void {\n const prev = HistoryEditor.isMerging(editor)\n MERGING.set(editor, false)\n fn()\n MERGING.set(editor, prev)\n },\n\n /**\n * Apply a series of changes inside a synchronous `fn`, without saving any of\n * their operations into the history.\n */\n\n withoutSaving(editor: HistoryEditor, fn: () => void): void {\n const prev = HistoryEditor.isSaving(editor)\n SAVING.set(editor, false)\n fn()\n SAVING.set(editor, prev)\n },\n}\n","import { Editor, Operation, Path, Range, Transforms } from 'slate'\n\nimport { HistoryEditor } from './history-editor'\n\n/**\n * The `withHistory` plugin keeps track of the operation history of a Slate\n * editor as operations are applied to it, using undo and redo stacks.\n *\n * If you are using TypeScript, you must extend Slate's CustomTypes to use\n * this plugin.\n *\n * See https://docs.slatejs.org/concepts/11-typescript to learn how.\n */\n\nexport const withHistory = <T extends Editor>(editor: T) => {\n const e = editor as T & HistoryEditor\n const { apply } = e\n e.history = { undos: [], redos: [] }\n\n e.redo = () => {\n const { history } = e\n const { redos } = history\n\n if (redos.length > 0) {\n const batch = redos[redos.length - 1]\n\n if (batch.selectionBefore) {\n Transforms.setSelection(e, batch.selectionBefore)\n }\n\n HistoryEditor.withoutSaving(e, () => {\n Editor.withoutNormalizing(e, () => {\n for (const op of batch.operations) {\n e.apply(op)\n }\n })\n })\n\n history.redos.pop()\n e.writeHistory('undos', batch)\n }\n }\n\n e.undo = () => {\n const { history } = e\n const { undos } = history\n\n if (undos.length > 0) {\n const batch = undos[undos.length - 1]\n\n HistoryEditor.withoutSaving(e, () => {\n Editor.withoutNormalizing(e, () => {\n const inverseOps = batch.operations.map(Operation.inverse).reverse()\n\n for (const op of inverseOps) {\n e.apply(op)\n }\n if (batch.selectionBefore) {\n Transforms.setSelection(e, batch.selectionBefore)\n }\n })\n })\n\n e.writeHistory('redos', batch)\n history.undos.pop()\n }\n }\n\n e.apply = (op: Operation) => {\n const { operations, history } = e\n const { undos } = history\n const lastBatch = undos[undos.length - 1]\n const lastOp =\n lastBatch && lastBatch.operations[lastBatch.operations.length - 1]\n let save = HistoryEditor.isSaving(e)\n let merge = HistoryEditor.isMerging(e)\n\n if (save == null) {\n save = shouldSave(op, lastOp)\n }\n\n if (save) {\n if (merge == null) {\n if (lastBatch == null) {\n merge = false\n } else if (operations.length !== 0) {\n merge = true\n } else {\n merge = shouldMerge(op, lastOp)\n }\n }\n\n if (lastBatch && merge) {\n lastBatch.operations.push(op)\n } else {\n const batch = {\n operations: [op],\n selectionBefore: e.selection,\n }\n e.writeHistory('undos', batch)\n }\n\n while (undos.length > 100) {\n undos.shift()\n }\n\n history.redos = []\n }\n\n apply(op)\n }\n\n e.writeHistory = (stack: 'undos' | 'redos', batch: any) => {\n e.history[stack].push(batch)\n }\n\n return e\n}\n\n/**\n * Check whether to merge an operation into the previous operation.\n */\n\nconst shouldMerge = (op: Operation, prev: Operation | undefined): boolean => {\n if (\n prev &&\n op.type === 'insert_text' &&\n prev.type === 'insert_text' &&\n op.offset === prev.offset + prev.text.length &&\n Path.equals(op.path, prev.path)\n ) {\n return true\n }\n\n if (\n prev &&\n op.type === 'remove_text' &&\n prev.type === 'remove_text' &&\n op.offset + op.text.length === prev.offset &&\n Path.equals(op.path, prev.path)\n ) {\n return true\n }\n\n return false\n}\n\n/**\n * Check whether an operation needs to be saved to the history.\n */\n\nconst shouldSave = (op: Operation, prev: Operation | undefined): boolean => {\n if (op.type === 'set_selection') {\n return false\n }\n\n return true\n}\n"],"names":["History","isHistory","value","isPlainObject","Array","isArray","redos","undos","length","Operation","isOperationList","operations","HISTORY","WeakMap","SAVING","MERGING","HistoryEditor","isHistoryEditor","history","Editor","isEditor","isMerging","editor","get","isSaving","redo","undo","withoutMerging","fn","prev","set","withoutSaving","withHistory","e","apply","batch","selectionBefore","Transforms","setSelection","withoutNormalizing","_iterator","_createForOfIteratorHelper","_step","s","n","done","op","err","f","pop","writeHistory","inverseOps","map","inverse","reverse","_iterator2","_step2","lastBatch","lastOp","save","merge","shouldSave","shouldMerge","push","selection","shift","stack","type","offset","text","Path","equals","path"],"mappings":"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"}
\No newline at end of file