import { Path, Node, Element, Text, Operation, Editor, InsertTextOperation, RemoveTextOperation, InsertNodeOperation, RemoveNodeOperation, SplitNodeOperation, MergeNodeOperation, MoveNodeOperation, SetNodeOperation, } from 'slate'; import { slateType } from '../src/SlateType'; export const makeOp = { insertText: ( path: Path, offset: number, text: string ): InsertTextOperation => { return { type: 'insert_text', path, offset, text, }; }, removeText: ( path: Path, offset: number, text: string ): RemoveTextOperation => { return { type: 'remove_text', path, offset, text, }; }, insertNode: (path: Path, node: Node): InsertNodeOperation => { return { type: 'insert_node', path, node, }; }, removeNode: (path: Path, node: Node): RemoveNodeOperation => { return { type: 'remove_node', path, node, }; }, splitNode: (path: Path, position: number): SplitNodeOperation => { return { type: 'split_node', path, position, target: null, properties: {}, }; }, mergeNode: (path: Path, position: number): MergeNodeOperation => { return { type: 'merge_node', path, position, target: null, properties: {}, }; }, moveNode: (path: Path, newPath: Path): MoveNodeOperation => { return { type: 'move_node', path, newPath, }; }, setNode: (path: Path, newProperties: Partial<Node>): SetNodeOperation => { return { type: 'set_node', path, properties: {}, newProperties, }; }, }; export const applyOp = ( snapshot: Editor, ops: Operation[] | Operation ): Editor => { slateType.normalize(ops).forEach((op) => { checkOp(snapshot, op); slateType.apply(snapshot, op); }); return snapshot; }; const checkOp = (snapshot: Editor, op: Operation) => { switch (op.type) { case 'remove_text': { const leaf = Node.leaf(snapshot, op.path); const textToRemove = leaf.text.slice( op.offset, op.offset + op.text.length ); expect(textToRemove).toBe(op.text); break; } case 'merge_node': { const prev = Node.get(snapshot, Path.previous(op.path)); const prevLen = Text.isText(prev) ? prev.text.length : prev.children.length; expect(prevLen).toBe(op.position); break; } case 'remove_node': { // op.node needs to be checked break; } default: return; } }; export const initialDoc: Element = { children: [ { type: 'Paragraph', children: [{ text: 'AB', italic: true }, { text: 'CD' }, { text: 'EF' }], }, { type: 'NumberedList', children: [{ text: 'GH', bold: true }, { text: 'IJ' }, { text: 'KL' }], }, { type: 'BulletedList', children: [{ text: 'MN' }, { text: 'OPQ' }, { text: 'RST' }], }, ], };