UNPKG

@portabletext/editor

Version:

Portable Text Editor made in React

78 lines (75 loc) 2.19 kB
import type {Path, PortableTextBlock} from '@sanity/types' import {isEqual} from 'lodash' import type {EditorSelection, EditorSelectionPoint} from '../types/editor' export function normalizePoint( point: EditorSelectionPoint, value: PortableTextBlock[], ): EditorSelectionPoint | null { if (!point || !value) { return null } const newPath: Path = [] let newOffset: number = point.offset || 0 const blockKey = typeof point.path[0] === 'object' && '_key' in point.path[0] && point.path[0]._key const childKey = typeof point.path[2] === 'object' && '_key' in point.path[2] && point.path[2]._key const block: PortableTextBlock | undefined = value.find( (blk) => blk._key === blockKey, ) if (block) { newPath.push({_key: block._key}) } else { return null } if (block && point.path[1] === 'children') { if ( !block.children || (Array.isArray(block.children) && block.children.length === 0) ) { return null } const child = Array.isArray(block.children) && block.children.find((cld) => cld._key === childKey) if (child) { newPath.push('children') newPath.push({_key: child._key}) newOffset = child.text && child.text.length >= point.offset ? point.offset : (child.text && child.text.length) || 0 } else { return null } } return {path: newPath, offset: newOffset} } export function normalizeSelection( selection: EditorSelection, value: PortableTextBlock[] | undefined, ): EditorSelection | null { if (!selection || !value || value.length === 0) { return null } let newAnchor: EditorSelectionPoint | null = null let newFocus: EditorSelectionPoint | null = null const {anchor, focus} = selection if ( anchor && value.find((blk) => isEqual({_key: blk._key}, anchor.path[0])) ) { newAnchor = normalizePoint(anchor, value) } if (focus && value.find((blk) => isEqual({_key: blk._key}, focus.path[0]))) { newFocus = normalizePoint(focus, value) } if (newAnchor && newFocus) { return {anchor: newAnchor, focus: newFocus, backward: selection.backward} } return null }