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 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | 17x 17x 17x 17x 17x 165x 165x 165x 27x 6x 135x 135x 135x 135x 110x 30x 30x 80x 135x 135x 50x 50x 50x 50x 5x 5x 85x 35x 35x 35x 35x 35x 50x 40x 40x 40x 40x 40x 10x 5x 5x 5x 15x 15x 15x 12x 12x | import type {CompactSplitOp, OPCODE_SPLIT} from '../codec/compact/types'; import {AbstractOp} from './AbstractOp'; import type {OperationSplit, SlateNode, SlateTextNode, SlateElementNode} from '../types'; import {find, isObjectReference, isArrayReference, type Path, formatJsonPointer} from '@jsonjoy.com/json-pointer'; import {isTextNode, isElementNode} from '../util'; import {OPCODE} from '../constants'; type Composable = string | number | SlateNode; /** * @category JSON Patch Extended */ export class OpSplit extends AbstractOp<'split'> { constructor( path: Path, public readonly pos: number, public readonly props: object | null, ) { super(path); } public op() { return 'split' as const; } public code() { return OPCODE.split; } public apply(doc: unknown) { const ref = find(doc, this.path); Iif (ref.val === undefined) throw new Error('NOT_FOUND'); const tuple = this.split(ref.val); if (isObjectReference(ref)) ref.obj[ref.key] = tuple; else if (isArrayReference(ref)) { ref.obj[ref.key] = tuple[0]; ref.obj.splice(ref.key + 1, 0, tuple[1]); } else doc = tuple; return {doc, old: ref.val}; } private split<T>(node: T): [T | Composable, T | Composable] { if (typeof node === 'string') { const {pos, props} = this; const before = node.slice(0, pos); const after = node.slice(pos); if (!props) return [before, after]; const textNodes: [SlateTextNode, SlateTextNode] = [ { ...props, text: before, }, { ...props, text: after, }, ]; return textNodes; } else if (isTextNode(node)) { const {pos, props} = this; const before = node.text.slice(0, pos); const after = node.text.slice(pos); const textNodes: [SlateTextNode, SlateTextNode] = [ { ...node, ...props, text: before, }, { ...node, ...props, text: after, }, ]; return textNodes; } else if (isElementNode(node)) { const {pos, props} = this; const before = node.children.slice(0, pos); const after = node.children.slice(pos); const elementNodes: [SlateElementNode, SlateElementNode] = [ { ...node, ...props, children: before, }, { ...node, ...props, children: after, }, ]; return elementNodes; } else if (typeof node === 'number') { const {pos} = this; return [pos, node - pos]; } else return [node, node]; } public toJson(parent?: AbstractOp): OperationSplit { const op: OperationSplit = { op: 'split', path: formatJsonPointer(this.path), pos: this.pos, }; if (this.props) op.props = this.props; return op; } public toCompact(parent: undefined | AbstractOp, verbose: boolean): CompactSplitOp { const opcode: OPCODE_SPLIT = verbose ? 'split' : OPCODE.split; return this.props ? [opcode, this.path, this.pos, this.props] : [opcode, this.path, this.pos]; } } |