@portabletext/editor 1.15.3 → 1.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/lib/_chunks-cjs/behavior.core.cjs +25 -25
  2. package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
  3. package/lib/_chunks-cjs/selector.get-text-before.cjs +14 -14
  4. package/lib/_chunks-cjs/selector.get-text-before.cjs.map +1 -1
  5. package/lib/_chunks-cjs/{selectors.cjs → selector.is-selection-collapsed.cjs} +8 -8
  6. package/lib/_chunks-cjs/selector.is-selection-collapsed.cjs.map +1 -0
  7. package/lib/_chunks-es/behavior.core.js +7 -7
  8. package/lib/_chunks-es/behavior.core.js.map +1 -1
  9. package/lib/_chunks-es/selector.get-text-before.js +14 -14
  10. package/lib/_chunks-es/selector.get-text-before.js.map +1 -1
  11. package/lib/_chunks-es/{selectors.js → selector.is-selection-collapsed.js} +8 -8
  12. package/lib/_chunks-es/selector.is-selection-collapsed.js.map +1 -0
  13. package/lib/behaviors/index.cjs +23 -23
  14. package/lib/behaviors/index.cjs.map +1 -1
  15. package/lib/behaviors/index.d.cts +1 -0
  16. package/lib/behaviors/index.d.ts +1 -0
  17. package/lib/behaviors/index.js +8 -8
  18. package/lib/behaviors/index.js.map +1 -1
  19. package/lib/index.cjs +855 -515
  20. package/lib/index.cjs.map +1 -1
  21. package/lib/index.d.cts +4126 -4834
  22. package/lib/index.d.ts +4126 -4834
  23. package/lib/index.js +852 -514
  24. package/lib/index.js.map +1 -1
  25. package/lib/selectors/index.cjs +166 -16
  26. package/lib/selectors/index.cjs.map +1 -1
  27. package/lib/selectors/index.d.cts +54 -5
  28. package/lib/selectors/index.d.ts +54 -5
  29. package/lib/selectors/index.js +154 -3
  30. package/lib/selectors/index.js.map +1 -1
  31. package/package.json +11 -11
  32. package/src/behaviors/behavior.code-editor.ts +5 -9
  33. package/src/behaviors/behavior.core.block-objects.ts +13 -19
  34. package/src/behaviors/behavior.core.lists.ts +11 -17
  35. package/src/behaviors/behavior.links.ts +4 -4
  36. package/src/behaviors/behavior.markdown.ts +16 -21
  37. package/src/editor/Editable.tsx +11 -4
  38. package/src/editor/PortableTextEditor.tsx +2 -3
  39. package/src/editor/{hooks/useSyncValue.test.tsx → __tests__/sync-value.test.tsx} +42 -23
  40. package/src/editor/components/Synchronizer.tsx +53 -80
  41. package/src/editor/editor-machine.ts +129 -80
  42. package/src/editor/editor-provider.tsx +0 -3
  43. package/src/editor/editor-selector.ts +5 -0
  44. package/src/editor/editor-snapshot.ts +1 -0
  45. package/src/editor/get-active-decorators.ts +20 -0
  46. package/src/editor/mutation-machine.ts +100 -0
  47. package/src/editor/plugins/__tests__/withPortableTextMarkModel.test.tsx +21 -15
  48. package/src/editor/plugins/createWithMaxBlocks.ts +1 -1
  49. package/src/editor/plugins/createWithPatches.ts +0 -4
  50. package/src/editor/plugins/createWithPlaceholderBlock.ts +1 -1
  51. package/src/editor/plugins/createWithPortableTextSelections.ts +4 -1
  52. package/src/editor/plugins/createWithUndoRedo.ts +3 -3
  53. package/src/editor/sync-machine.ts +657 -0
  54. package/src/editor/withSyncRangeDecorations.ts +17 -5
  55. package/src/selectors/_exports/index.ts +1 -0
  56. package/src/selectors/index.ts +9 -1
  57. package/src/selectors/selector.get-active-style.ts +37 -0
  58. package/src/selectors/selector.get-selected-spans.ts +136 -0
  59. package/src/selectors/selector.is-active-annotation.ts +49 -0
  60. package/src/selectors/selector.is-active-decorator.ts +21 -0
  61. package/src/selectors/selector.is-active-list-item.ts +13 -0
  62. package/src/selectors/selector.is-active-style.ts +13 -0
  63. package/src/selectors/selector.is-selection-collapsed.ts +12 -0
  64. package/src/selectors/selector.is-selection-expanded.ts +9 -0
  65. package/src/selectors/selectors.ts +0 -11
  66. package/src/utils/weakMaps.ts +0 -3
  67. package/src/utils/withChanges.ts +1 -8
  68. package/lib/_chunks-cjs/selectors.cjs.map +0 -1
  69. package/lib/_chunks-es/selectors.js.map +0 -1
  70. package/src/editor/hooks/useSyncValue.ts +0 -426
@@ -1 +1 @@
1
- {"version":3,"file":"behavior.core.js","sources":["../../src/editor/utils/utils.block-offset.ts","../../src/editor/utils/utils.ts","../../src/utils/is-hotkey.ts","../../src/behaviors/behavior.types.ts","../../src/behaviors/behavior.core.block-objects.ts","../../src/behaviors/behavior.core.decorators.ts","../../src/behaviors/behavior.core.lists.ts","../../src/behaviors/behavior.core.ts"],"sourcesContent":["import {\n isPortableTextSpan,\n isPortableTextTextBlock,\n type KeyedSegment,\n type PortableTextBlock,\n} from '@sanity/types'\nimport type {BlockOffset} from '../../behaviors/behavior.types'\n\nexport function blockOffsetToSpanSelectionPoint({\n value,\n blockOffset,\n}: {\n value: Array<PortableTextBlock>\n blockOffset: BlockOffset\n}) {\n let offsetLeft = blockOffset.offset\n let selectionPoint:\n | {path: [KeyedSegment, 'children', KeyedSegment]; offset: number}\n | undefined\n\n for (const block of value) {\n if (block._key !== blockOffset.path[0]._key) {\n continue\n }\n\n if (!isPortableTextTextBlock(block)) {\n continue\n }\n\n for (const child of block.children) {\n if (!isPortableTextSpan(child)) {\n continue\n }\n\n if (offsetLeft === 0) {\n selectionPoint = {\n path: [...blockOffset.path, 'children', {_key: child._key}],\n offset: 0,\n }\n break\n }\n\n if (offsetLeft <= child.text.length) {\n selectionPoint = {\n path: [...blockOffset.path, 'children', {_key: child._key}],\n offset: offsetLeft,\n }\n break\n }\n\n offsetLeft -= child.text.length\n }\n }\n\n return selectionPoint\n}\n\nexport function spanSelectionPointToBlockOffset({\n value,\n selectionPoint,\n}: {\n value: Array<PortableTextBlock>\n selectionPoint: {\n path: [KeyedSegment, 'children', KeyedSegment]\n offset: number\n }\n}): BlockOffset | undefined {\n let offset = 0\n\n for (const block of value) {\n if (block._key !== selectionPoint.path[0]._key) {\n continue\n }\n\n if (!isPortableTextTextBlock(block)) {\n continue\n }\n\n for (const child of block.children) {\n if (!isPortableTextSpan(child)) {\n continue\n }\n\n if (child._key === selectionPoint.path[2]._key) {\n return {\n path: [{_key: block._key}],\n offset: offset + selectionPoint.offset,\n }\n }\n\n offset += child.text.length\n }\n }\n}\n","import {\n isPortableTextSpan,\n isPortableTextTextBlock,\n type PortableTextBlock,\n type PortableTextTextBlock,\n} from '@sanity/types'\n\nexport function isEmptyTextBlock(block: PortableTextBlock) {\n if (!isPortableTextTextBlock(block)) {\n return false\n }\n\n const onlyText = block.children.every(isPortableTextSpan)\n const blockText = getTextBlockText(block)\n\n return onlyText && blockText === ''\n}\n\nexport function getTextBlockText(block: PortableTextTextBlock) {\n return block.children.map((child) => child.text ?? '').join('')\n}\n","export interface KeyboardEventLike {\n key: string\n keyCode?: number\n altKey: boolean\n ctrlKey: boolean\n metaKey: boolean\n shiftKey: boolean\n}\n\ninterface HotKey {\n keyCode?: number | undefined\n key?: string | undefined\n altKey: boolean | null\n ctrlKey: boolean | null\n metaKey: boolean | null\n shiftKey: boolean | null\n}\n\nconst IS_MAC =\n typeof window !== 'undefined' &&\n /Mac|iPod|iPhone|iPad/.test(window.navigator.userAgent)\n\ntype Modifier = 'altKey' | 'ctrlKey' | 'metaKey' | 'shiftKey'\n\nconst modifiers: Record<string, Modifier | undefined> = {\n alt: 'altKey',\n control: 'ctrlKey',\n meta: 'metaKey',\n shift: 'shiftKey',\n}\n\nconst aliases: Record<string, string | undefined> = {\n add: '+',\n break: 'pause',\n cmd: 'meta',\n command: 'meta',\n ctl: 'control',\n ctrl: 'control',\n del: 'delete',\n down: 'arrowdown',\n esc: 'escape',\n ins: 'insert',\n left: 'arrowleft',\n mod: IS_MAC ? 'meta' : 'control',\n opt: 'alt',\n option: 'alt',\n return: 'enter',\n right: 'arrowright',\n space: ' ',\n spacebar: ' ',\n up: 'arrowup',\n win: 'meta',\n windows: 'meta',\n}\n\nconst keyCodes: Record<string, number | undefined> = {\n 'backspace': 8,\n 'tab': 9,\n 'enter': 13,\n 'shift': 16,\n 'control': 17,\n 'alt': 18,\n 'pause': 19,\n 'capslock': 20,\n 'escape': 27,\n ' ': 32,\n 'pageup': 33,\n 'pagedown': 34,\n 'end': 35,\n 'home': 36,\n 'arrowleft': 37,\n 'arrowup': 38,\n 'arrowright': 39,\n 'arrowdown': 40,\n 'insert': 45,\n 'delete': 46,\n 'meta': 91,\n 'numlock': 144,\n 'scrolllock': 145,\n ';': 186,\n '=': 187,\n ',': 188,\n '-': 189,\n '.': 190,\n '/': 191,\n '`': 192,\n '[': 219,\n '\\\\': 220,\n ']': 221,\n \"'\": 222,\n 'f1': 112,\n 'f2': 113,\n 'f3': 114,\n 'f4': 115,\n 'f5': 116,\n 'f6': 117,\n 'f7': 118,\n 'f8': 119,\n 'f9': 120,\n 'f10': 121,\n 'f11': 122,\n 'f12': 123,\n 'f13': 124,\n 'f14': 125,\n 'f15': 126,\n 'f16': 127,\n 'f17': 128,\n 'f18': 129,\n 'f19': 130,\n 'f20': 131,\n}\n\nexport function isHotkey(hotkey: string, event: KeyboardEventLike): boolean {\n return compareHotkey(parseHotkey(hotkey), event)\n}\n\nfunction parseHotkey(hotkey: string): HotKey {\n // Ensure that all the modifiers are set to false unless the hotkey has them.\n const parsedHotkey: HotKey = {\n altKey: false,\n ctrlKey: false,\n metaKey: false,\n shiftKey: false,\n }\n\n // Special case to handle the `+` key since we use it as a separator.\n const hotkeySegments = hotkey.replace('++', '+add').split('+')\n\n for (const rawHotkeySegment of hotkeySegments) {\n const optional =\n rawHotkeySegment.endsWith('?') && rawHotkeySegment.length > 1\n const hotkeySegment = optional\n ? rawHotkeySegment.slice(0, -1)\n : rawHotkeySegment\n const keyName = toKeyName(hotkeySegment)\n const modifier = modifiers[keyName]\n const alias = aliases[hotkeySegment]\n const code = keyCodes[keyName]\n\n if (\n hotkeySegment.length > 1 &&\n modifier === undefined &&\n alias === undefined &&\n code === undefined\n ) {\n throw new TypeError(`Unknown modifier: \"${hotkeySegment}\"`)\n }\n\n if (hotkeySegments.length === 1 || modifier === undefined) {\n parsedHotkey.key = keyName\n parsedHotkey.keyCode = toKeyCode(hotkeySegment)\n }\n\n if (modifier !== undefined) {\n parsedHotkey[modifier] = optional ? null : true\n }\n }\n\n return parsedHotkey\n}\n\nfunction compareHotkey(\n parsedHotkey: HotKey,\n event: KeyboardEventLike,\n): boolean {\n const matchingModifiers =\n (parsedHotkey.altKey != null\n ? parsedHotkey.altKey === event.altKey\n : true) &&\n (parsedHotkey.ctrlKey != null\n ? parsedHotkey.ctrlKey === event.ctrlKey\n : true) &&\n (parsedHotkey.metaKey != null\n ? parsedHotkey.metaKey === event.metaKey\n : true) &&\n (parsedHotkey.shiftKey != null\n ? parsedHotkey.shiftKey === event.shiftKey\n : true)\n\n if (!matchingModifiers) {\n return false\n }\n\n if (parsedHotkey.keyCode !== undefined && event.keyCode !== undefined) {\n if (parsedHotkey.keyCode === 91 && event.keyCode === 93) {\n return true\n }\n\n return parsedHotkey.keyCode === event.keyCode\n }\n\n return (\n parsedHotkey.keyCode === event.keyCode ||\n parsedHotkey.key === event.key.toLowerCase()\n )\n}\n\nfunction toKeyCode(name: string): number {\n const keyName = toKeyName(name)\n const keyCode = keyCodes[keyName] ?? keyName.toUpperCase().charCodeAt(0)\n\n return keyCode\n}\n\nfunction toKeyName(name: string): string {\n const keyName = name.toLowerCase()\n\n return aliases[keyName] ?? keyName\n}\n","import type {KeyedSegment, PortableTextTextBlock} from '@sanity/types'\nimport type {TextUnit} from 'slate'\nimport type {TextInsertTextOptions} from 'slate/dist/interfaces/transforms/text'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport type {PickFromUnion} from '../type-utils'\nimport type {EditorSelection, PortableTextSlateEditor} from '../types/editor'\n\n/**\n * @alpha\n */\nexport type SyntheticBehaviorEvent =\n | {\n type: 'annotation.add'\n annotation: {\n name: string\n value: {[prop: string]: unknown}\n }\n }\n | {\n type: 'annotation.remove'\n annotation: {\n name: string\n }\n }\n | {\n type: 'annotation.toggle'\n annotation: {\n name: string\n value: {[prop: string]: unknown}\n }\n }\n | {\n type: 'blur'\n }\n | {\n type: 'decorator.add'\n decorator: string\n }\n | {\n type: 'decorator.remove'\n decorator: string\n }\n | {\n type: 'decorator.toggle'\n decorator: string\n }\n | {\n type: 'delete.backward'\n unit: TextUnit\n }\n | {\n type: 'delete.forward'\n unit: TextUnit\n }\n | {\n type: 'focus'\n }\n | {\n type: 'insert.block object'\n placement: 'auto' | 'after' | 'before'\n blockObject: {\n name: string\n value?: {[prop: string]: unknown}\n }\n }\n | {\n type: 'insert.inline object'\n inlineObject: {\n name: string\n value?: {[prop: string]: unknown}\n }\n }\n | {\n type: 'insert.break'\n }\n | {\n type: 'insert.soft break'\n }\n | {\n type: 'insert.text'\n text: string\n options?: TextInsertTextOptions\n }\n | {\n type: 'list item.toggle'\n listItem: string\n }\n | {\n type: 'style.toggle'\n style: string\n }\n\n/**\n * @alpha\n */\nexport type NativeBehaviorEvent =\n | {\n type: 'copy'\n data: DataTransfer\n }\n | {\n type: 'key.down'\n keyboardEvent: Pick<\n KeyboardEvent,\n 'key' | 'code' | 'altKey' | 'ctrlKey' | 'metaKey' | 'shiftKey'\n >\n }\n | {\n type: 'key.up'\n keyboardEvent: Pick<\n KeyboardEvent,\n 'key' | 'code' | 'altKey' | 'ctrlKey' | 'metaKey' | 'shiftKey'\n >\n }\n | {\n type: 'paste'\n data: DataTransfer\n }\n\n/**\n * @alpha\n */\nexport type BehaviorActionIntend =\n | SyntheticBehaviorEvent\n | {\n type: 'insert.span'\n text: string\n annotations?: Array<{\n name: string\n value: {[prop: string]: unknown}\n }>\n decorators?: Array<string>\n }\n | {\n type: 'insert.text block'\n placement: 'auto' | 'after' | 'before'\n textBlock?: {\n children?: PortableTextTextBlock['children']\n }\n }\n | {\n type: 'list item.add'\n listItem: string\n }\n | {\n type: 'list item.remove'\n listItem: string\n }\n | {\n type: 'move.block'\n at: [KeyedSegment]\n to: [KeyedSegment]\n }\n | {\n type: 'move.block down'\n at: [KeyedSegment]\n }\n | {\n type: 'move.block up'\n at: [KeyedSegment]\n }\n | {\n type: 'noop'\n }\n | {\n type: 'delete.block'\n blockPath: [KeyedSegment]\n }\n | {\n type: 'delete.text'\n anchor: BlockOffset\n focus: BlockOffset\n }\n | {\n type: 'effect'\n effect: () => void\n }\n | {\n type: 'reselect'\n }\n | {\n type: 'select'\n selection: EditorSelection\n }\n | {\n type: 'select.previous block'\n }\n | {\n type: 'select.next block'\n }\n | {\n type: 'style.add'\n style: string\n }\n | {\n type: 'style.remove'\n style: string\n }\n | {\n type: 'text block.set'\n at: [KeyedSegment]\n level?: number\n listItem?: string\n style?: string\n }\n | {\n type: 'text block.unset'\n at: [KeyedSegment]\n props: Array<'level' | 'listItem' | 'style'>\n }\n\n/**\n * @alpha\n */\nexport type BehaviorAction = BehaviorActionIntend & {\n editor: PortableTextSlateEditor\n}\n\n/**\n * @alpha\n */\nexport type BehaviorEvent = SyntheticBehaviorEvent | NativeBehaviorEvent\n\n/**\n * @alpha\n */\nexport type Behavior<\n TBehaviorEventType extends BehaviorEvent['type'] = BehaviorEvent['type'],\n TGuardResponse = true,\n> = {\n /**\n * The internal editor event that triggers this behavior.\n */\n on: TBehaviorEventType\n /**\n * Predicate function that determines if the behavior should be executed.\n * Returning a non-nullable value from the guard will pass the value to the\n * actions and execute them.\n */\n guard?: BehaviorGuard<\n PickFromUnion<BehaviorEvent, 'type', TBehaviorEventType>,\n TGuardResponse\n >\n /**\n * Array of behavior action sets.\n */\n actions: Array<BehaviorActionIntendSet<TBehaviorEventType, TGuardResponse>>\n}\n\n/**\n * @alpha\n */\nexport type BehaviorGuard<\n TBehaviorEvent extends BehaviorEvent,\n TGuardResponse,\n> = ({\n context,\n event,\n}: {\n context: EditorContext\n event: TBehaviorEvent\n}) => TGuardResponse | false\n\n/**\n * @alpha\n */\nexport type BehaviorActionIntendSet<\n TBehaviorEventType extends BehaviorEvent['type'] = BehaviorEvent['type'],\n TGuardResponse = true,\n> = (\n {\n context,\n event,\n }: {\n context: EditorContext\n event: PickFromUnion<BehaviorEvent, 'type', TBehaviorEventType>\n },\n guardResponse: TGuardResponse,\n) => Array<BehaviorActionIntend>\n\n/**\n * @alpha\n */\nexport function defineBehavior<\n TAnyBehaviorEventType extends BehaviorEvent['type'],\n TGuardResponse = true,\n>(behavior: Behavior<TAnyBehaviorEventType, TGuardResponse>): Behavior {\n return behavior as unknown as Behavior\n}\n\n/**\n * @alpha\n */\nexport type BlockOffset = {\n path: [KeyedSegment]\n offset: number\n}\n","import {isPortableTextTextBlock} from '@sanity/types'\nimport {isEmptyTextBlock} from '../editor/utils/utils'\nimport {\n getFocusBlockObject,\n getFocusTextBlock,\n getNextBlock,\n getPreviousBlock,\n selectionIsCollapsed,\n} from '../selectors/selectors'\nimport {isHotkey} from '../utils/is-hotkey'\nimport {defineBehavior} from './behavior.types'\n\nconst arrowDownOnLonelyBlockObject = defineBehavior({\n on: 'key.down',\n guard: ({context, event}) => {\n const isArrowDown = isHotkey('ArrowDown', event.keyboardEvent)\n const focusBlockObject = getFocusBlockObject({context})\n const nextBlock = getNextBlock({context})\n\n return isArrowDown && focusBlockObject && !nextBlock\n },\n actions: [() => [{type: 'insert.text block', placement: 'after'}]],\n})\n\nconst arrowUpOnLonelyBlockObject = defineBehavior({\n on: 'key.down',\n guard: ({context, event}) => {\n const isArrowUp = isHotkey('ArrowUp', event.keyboardEvent)\n const focusBlockObject = getFocusBlockObject({context})\n const previousBlock = getPreviousBlock({context})\n\n return isArrowUp && focusBlockObject && !previousBlock\n },\n actions: [\n () => [\n {type: 'insert.text block', placement: 'before'},\n {type: 'select.previous block'},\n ],\n ],\n})\n\nconst breakingBlockObject = defineBehavior({\n on: 'insert.break',\n guard: ({context}) => {\n const focusBlockObject = getFocusBlockObject({context})\n const collapsedSelection = selectionIsCollapsed({context})\n\n return collapsedSelection && focusBlockObject !== undefined\n },\n actions: [() => [{type: 'insert.text block', placement: 'after'}]],\n})\n\nconst deletingEmptyTextBlockAfterBlockObject = defineBehavior({\n on: 'delete.backward',\n guard: ({context}) => {\n const focusTextBlock = getFocusTextBlock({context})\n const selectionCollapsed = selectionIsCollapsed({context})\n const previousBlock = getPreviousBlock({context})\n\n if (!focusTextBlock || !selectionCollapsed || !previousBlock) {\n return false\n }\n\n if (\n isEmptyTextBlock(focusTextBlock.node) &&\n !isPortableTextTextBlock(previousBlock.node)\n ) {\n return {focusTextBlock, previousBlock}\n }\n\n return false\n },\n actions: [\n (_, {focusTextBlock, previousBlock}) => [\n {\n type: 'delete.block',\n blockPath: focusTextBlock.path,\n },\n {\n type: 'select',\n selection: {\n anchor: {path: previousBlock.path, offset: 0},\n focus: {path: previousBlock.path, offset: 0},\n },\n },\n ],\n ],\n})\n\nconst deletingEmptyTextBlockBeforeBlockObject = defineBehavior({\n on: 'delete.forward',\n guard: ({context}) => {\n const focusTextBlock = getFocusTextBlock({context})\n const selectionCollapsed = selectionIsCollapsed({context})\n const nextBlock = getNextBlock({context})\n\n if (!focusTextBlock || !selectionCollapsed || !nextBlock) {\n return false\n }\n\n if (\n isEmptyTextBlock(focusTextBlock.node) &&\n !isPortableTextTextBlock(nextBlock.node)\n ) {\n return {focusTextBlock, nextBlock}\n }\n\n return false\n },\n actions: [\n (_, {focusTextBlock, nextBlock}) => [\n {\n type: 'delete.block',\n blockPath: focusTextBlock.path,\n },\n {\n type: 'select',\n selection: {\n anchor: {path: nextBlock.path, offset: 0},\n focus: {path: nextBlock.path, offset: 0},\n },\n },\n ],\n ],\n})\n\nexport const coreBlockObjectBehaviors = {\n arrowDownOnLonelyBlockObject,\n arrowUpOnLonelyBlockObject,\n breakingBlockObject,\n deletingEmptyTextBlockAfterBlockObject,\n deletingEmptyTextBlockBeforeBlockObject,\n}\n","import {defineBehavior} from './behavior.types'\n\nconst decoratorAdd = defineBehavior({\n on: 'decorator.add',\n actions: [\n ({event}) => [\n event,\n {\n type: 'reselect',\n },\n ],\n ],\n})\n\nconst decoratorRemove = defineBehavior({\n on: 'decorator.remove',\n guard: ({event}) => ({decorator: event.decorator}),\n actions: [\n ({event}) => [\n event,\n {\n type: 'reselect',\n },\n ],\n ],\n})\n\nconst decoratorToggle = defineBehavior({\n on: 'decorator.toggle',\n guard: ({event}) => ({decorator: event.decorator}),\n actions: [\n ({event}) => [\n event,\n {\n type: 'reselect',\n },\n ],\n ],\n})\n\nexport const coreDecoratorBehaviors = {\n decoratorAdd,\n decoratorRemove,\n decoratorToggle,\n}\n","import {createGuards} from '../behavior-actions/behavior.guards'\nimport {isEmptyTextBlock} from '../editor/utils/utils'\nimport {\n getFocusListBlock,\n getFocusSpan,\n getFocusTextBlock,\n getSelectedBlocks,\n selectionIsCollapsed,\n} from '../selectors/selectors'\nimport {isHotkey} from '../utils/is-hotkey'\nimport {defineBehavior} from './behavior.types'\n\nconst MAX_LIST_LEVEL = 10\n\nconst clearListOnBackspace = defineBehavior({\n on: 'delete.backward',\n guard: ({context}) => {\n const selectionCollapsed = selectionIsCollapsed({context})\n const focusTextBlock = getFocusTextBlock({context})\n const focusSpan = getFocusSpan({context})\n\n if (!selectionCollapsed || !focusTextBlock || !focusSpan) {\n return false\n }\n\n const atTheBeginningOfBLock =\n focusTextBlock.node.children[0]._key === focusSpan.node._key &&\n context.selection?.focus.offset === 0\n\n if (atTheBeginningOfBLock && focusTextBlock.node.level === 1) {\n return {focusTextBlock}\n }\n\n return false\n },\n actions: [\n (_, {focusTextBlock}) => [\n {\n type: 'text block.unset',\n props: ['listItem', 'level'],\n at: focusTextBlock.path,\n },\n ],\n ],\n})\n\nconst unindentListOnBackspace = defineBehavior({\n on: 'delete.backward',\n guard: ({context}) => {\n const selectionCollapsed = selectionIsCollapsed({context})\n const focusTextBlock = getFocusTextBlock({context})\n const focusSpan = getFocusSpan({context})\n\n if (!selectionCollapsed || !focusTextBlock || !focusSpan) {\n return false\n }\n\n const atTheBeginningOfBLock =\n focusTextBlock.node.children[0]._key === focusSpan.node._key &&\n context.selection?.focus.offset === 0\n\n if (\n atTheBeginningOfBLock &&\n focusTextBlock.node.level !== undefined &&\n focusTextBlock.node.level > 1\n ) {\n return {focusTextBlock, level: focusTextBlock.node.level - 1}\n }\n\n return false\n },\n actions: [\n (_, {focusTextBlock, level}) => [\n {\n type: 'text block.set',\n level,\n at: focusTextBlock.path,\n },\n ],\n ],\n})\n\nconst clearListOnEnter = defineBehavior({\n on: 'insert.break',\n guard: ({context}) => {\n const selectionCollapsed = selectionIsCollapsed({context})\n const focusListBlock = getFocusListBlock({context})\n\n if (\n !selectionCollapsed ||\n !focusListBlock ||\n !isEmptyTextBlock(focusListBlock.node)\n ) {\n return false\n }\n\n return {focusListBlock}\n },\n actions: [\n (_, {focusListBlock}) => [\n {\n type: 'text block.unset',\n props: ['listItem', 'level'],\n at: focusListBlock.path,\n },\n ],\n ],\n})\n\nconst indentListOnTab = defineBehavior({\n on: 'key.down',\n guard: ({context, event}) => {\n const isTab = isHotkey('Tab', event.keyboardEvent)\n\n if (!isTab) {\n return false\n }\n\n const selectedBlocks = getSelectedBlocks({context})\n const guards = createGuards(context)\n const selectedListBlocks = selectedBlocks.flatMap((block) =>\n guards.isListBlock(block.node)\n ? [\n {\n node: block.node,\n path: block.path,\n },\n ]\n : [],\n )\n\n if (selectedListBlocks.length === selectedBlocks.length) {\n return {selectedListBlocks}\n }\n\n return false\n },\n actions: [\n (_, {selectedListBlocks}) =>\n selectedListBlocks.map((selectedListBlock) => ({\n type: 'text block.set',\n level: Math.min(\n MAX_LIST_LEVEL,\n Math.max(1, selectedListBlock.node.level + 1),\n ),\n at: selectedListBlock.path,\n })),\n ],\n})\n\nconst unindentListOnShiftTab = defineBehavior({\n on: 'key.down',\n guard: ({context, event}) => {\n const isShiftTab = isHotkey('Shift+Tab', event.keyboardEvent)\n\n if (!isShiftTab) {\n return false\n }\n\n const selectedBlocks = getSelectedBlocks({context})\n const guards = createGuards(context)\n const selectedListBlocks = selectedBlocks.flatMap((block) =>\n guards.isListBlock(block.node)\n ? [\n {\n node: block.node,\n path: block.path,\n },\n ]\n : [],\n )\n\n if (selectedListBlocks.length === selectedBlocks.length) {\n return {selectedListBlocks}\n }\n\n return false\n },\n actions: [\n (_, {selectedListBlocks}) =>\n selectedListBlocks.map((selectedListBlock) => ({\n type: 'text block.set',\n level: Math.min(\n MAX_LIST_LEVEL,\n Math.max(1, selectedListBlock.node.level - 1),\n ),\n at: selectedListBlock.path,\n })),\n ],\n})\n\nexport const coreListBehaviors = {\n clearListOnBackspace,\n unindentListOnBackspace,\n clearListOnEnter,\n indentListOnTab,\n unindentListOnShiftTab,\n}\n","import {coreBlockObjectBehaviors} from './behavior.core.block-objects'\nimport {coreDecoratorBehaviors} from './behavior.core.decorators'\nimport {coreListBehaviors} from './behavior.core.lists'\nimport {defineBehavior} from './behavior.types'\n\nconst softReturn = defineBehavior({\n on: 'insert.soft break',\n actions: [() => [{type: 'insert.text', text: '\\n'}]],\n})\n\n/**\n * @alpha\n */\nexport const coreBehaviors = [\n softReturn,\n coreDecoratorBehaviors.decoratorAdd,\n coreDecoratorBehaviors.decoratorRemove,\n coreDecoratorBehaviors.decoratorToggle,\n coreBlockObjectBehaviors.arrowDownOnLonelyBlockObject,\n coreBlockObjectBehaviors.arrowUpOnLonelyBlockObject,\n coreBlockObjectBehaviors.breakingBlockObject,\n coreBlockObjectBehaviors.deletingEmptyTextBlockAfterBlockObject,\n coreBlockObjectBehaviors.deletingEmptyTextBlockBeforeBlockObject,\n coreListBehaviors.clearListOnBackspace,\n coreListBehaviors.unindentListOnBackspace,\n coreListBehaviors.clearListOnEnter,\n coreListBehaviors.indentListOnTab,\n coreListBehaviors.unindentListOnShiftTab,\n]\n\n/**\n * @alpha\n */\nexport const coreBehavior = {\n softReturn,\n decorators: coreDecoratorBehaviors,\n blockObjects: coreBlockObjectBehaviors,\n lists: coreListBehaviors,\n}\n"],"names":["blockOffsetToSpanSelectionPoint","value","blockOffset","offsetLeft","offset","selectionPoint","block","_key","path","isPortableTextTextBlock","child","children","isPortableTextSpan","text","length","spanSelectionPointToBlockOffset","isEmptyTextBlock","onlyText","every","blockText","getTextBlockText","map","join","IS_MAC","window","test","navigator","userAgent","modifiers","alt","control","meta","shift","aliases","add","break","cmd","command","ctl","ctrl","del","down","esc","ins","left","mod","opt","option","return","right","space","spacebar","up","win","windows","keyCodes","isHotkey","hotkey","event","compareHotkey","parseHotkey","parsedHotkey","altKey","ctrlKey","metaKey","shiftKey","hotkeySegments","replace","split","rawHotkeySegment","optional","endsWith","hotkeySegment","slice","keyName","toKeyName","modifier","alias","code","undefined","TypeError","key","keyCode","toKeyCode","toLowerCase","name","toUpperCase","charCodeAt","defineBehavior","behavior","arrowDownOnLonelyBlockObject","on","guard","context","isArrowDown","keyboardEvent","focusBlockObject","getFocusBlockObject","nextBlock","getNextBlock","actions","type","placement","arrowUpOnLonelyBlockObject","isArrowUp","previousBlock","getPreviousBlock","breakingBlockObject","selectionIsCollapsed","deletingEmptyTextBlockAfterBlockObject","focusTextBlock","getFocusTextBlock","selectionCollapsed","node","_","blockPath","selection","anchor","focus","deletingEmptyTextBlockBeforeBlockObject","coreBlockObjectBehaviors","decoratorAdd","decoratorRemove","decorator","decoratorToggle","coreDecoratorBehaviors","MAX_LIST_LEVEL","clearListOnBackspace","focusSpan","getFocusSpan","level","props","at","unindentListOnBackspace","clearListOnEnter","focusListBlock","getFocusListBlock","indentListOnTab","selectedBlocks","getSelectedBlocks","guards","createGuards","selectedListBlocks","flatMap","isListBlock","selectedListBlock","Math","min","max","unindentListOnShiftTab","coreListBehaviors","softReturn","coreBehaviors","coreBehavior","decorators","blockObjects","lists"],"mappings":"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"}
1
+ {"version":3,"file":"behavior.core.js","sources":["../../src/editor/utils/utils.block-offset.ts","../../src/editor/utils/utils.ts","../../src/utils/is-hotkey.ts","../../src/behaviors/behavior.types.ts","../../src/behaviors/behavior.core.block-objects.ts","../../src/behaviors/behavior.core.decorators.ts","../../src/behaviors/behavior.core.lists.ts","../../src/behaviors/behavior.core.ts"],"sourcesContent":["import {\n isPortableTextSpan,\n isPortableTextTextBlock,\n type KeyedSegment,\n type PortableTextBlock,\n} from '@sanity/types'\nimport type {BlockOffset} from '../../behaviors/behavior.types'\n\nexport function blockOffsetToSpanSelectionPoint({\n value,\n blockOffset,\n}: {\n value: Array<PortableTextBlock>\n blockOffset: BlockOffset\n}) {\n let offsetLeft = blockOffset.offset\n let selectionPoint:\n | {path: [KeyedSegment, 'children', KeyedSegment]; offset: number}\n | undefined\n\n for (const block of value) {\n if (block._key !== blockOffset.path[0]._key) {\n continue\n }\n\n if (!isPortableTextTextBlock(block)) {\n continue\n }\n\n for (const child of block.children) {\n if (!isPortableTextSpan(child)) {\n continue\n }\n\n if (offsetLeft === 0) {\n selectionPoint = {\n path: [...blockOffset.path, 'children', {_key: child._key}],\n offset: 0,\n }\n break\n }\n\n if (offsetLeft <= child.text.length) {\n selectionPoint = {\n path: [...blockOffset.path, 'children', {_key: child._key}],\n offset: offsetLeft,\n }\n break\n }\n\n offsetLeft -= child.text.length\n }\n }\n\n return selectionPoint\n}\n\nexport function spanSelectionPointToBlockOffset({\n value,\n selectionPoint,\n}: {\n value: Array<PortableTextBlock>\n selectionPoint: {\n path: [KeyedSegment, 'children', KeyedSegment]\n offset: number\n }\n}): BlockOffset | undefined {\n let offset = 0\n\n for (const block of value) {\n if (block._key !== selectionPoint.path[0]._key) {\n continue\n }\n\n if (!isPortableTextTextBlock(block)) {\n continue\n }\n\n for (const child of block.children) {\n if (!isPortableTextSpan(child)) {\n continue\n }\n\n if (child._key === selectionPoint.path[2]._key) {\n return {\n path: [{_key: block._key}],\n offset: offset + selectionPoint.offset,\n }\n }\n\n offset += child.text.length\n }\n }\n}\n","import {\n isPortableTextSpan,\n isPortableTextTextBlock,\n type PortableTextBlock,\n type PortableTextTextBlock,\n} from '@sanity/types'\n\nexport function isEmptyTextBlock(block: PortableTextBlock) {\n if (!isPortableTextTextBlock(block)) {\n return false\n }\n\n const onlyText = block.children.every(isPortableTextSpan)\n const blockText = getTextBlockText(block)\n\n return onlyText && blockText === ''\n}\n\nexport function getTextBlockText(block: PortableTextTextBlock) {\n return block.children.map((child) => child.text ?? '').join('')\n}\n","export interface KeyboardEventLike {\n key: string\n keyCode?: number\n altKey: boolean\n ctrlKey: boolean\n metaKey: boolean\n shiftKey: boolean\n}\n\ninterface HotKey {\n keyCode?: number | undefined\n key?: string | undefined\n altKey: boolean | null\n ctrlKey: boolean | null\n metaKey: boolean | null\n shiftKey: boolean | null\n}\n\nconst IS_MAC =\n typeof window !== 'undefined' &&\n /Mac|iPod|iPhone|iPad/.test(window.navigator.userAgent)\n\ntype Modifier = 'altKey' | 'ctrlKey' | 'metaKey' | 'shiftKey'\n\nconst modifiers: Record<string, Modifier | undefined> = {\n alt: 'altKey',\n control: 'ctrlKey',\n meta: 'metaKey',\n shift: 'shiftKey',\n}\n\nconst aliases: Record<string, string | undefined> = {\n add: '+',\n break: 'pause',\n cmd: 'meta',\n command: 'meta',\n ctl: 'control',\n ctrl: 'control',\n del: 'delete',\n down: 'arrowdown',\n esc: 'escape',\n ins: 'insert',\n left: 'arrowleft',\n mod: IS_MAC ? 'meta' : 'control',\n opt: 'alt',\n option: 'alt',\n return: 'enter',\n right: 'arrowright',\n space: ' ',\n spacebar: ' ',\n up: 'arrowup',\n win: 'meta',\n windows: 'meta',\n}\n\nconst keyCodes: Record<string, number | undefined> = {\n 'backspace': 8,\n 'tab': 9,\n 'enter': 13,\n 'shift': 16,\n 'control': 17,\n 'alt': 18,\n 'pause': 19,\n 'capslock': 20,\n 'escape': 27,\n ' ': 32,\n 'pageup': 33,\n 'pagedown': 34,\n 'end': 35,\n 'home': 36,\n 'arrowleft': 37,\n 'arrowup': 38,\n 'arrowright': 39,\n 'arrowdown': 40,\n 'insert': 45,\n 'delete': 46,\n 'meta': 91,\n 'numlock': 144,\n 'scrolllock': 145,\n ';': 186,\n '=': 187,\n ',': 188,\n '-': 189,\n '.': 190,\n '/': 191,\n '`': 192,\n '[': 219,\n '\\\\': 220,\n ']': 221,\n \"'\": 222,\n 'f1': 112,\n 'f2': 113,\n 'f3': 114,\n 'f4': 115,\n 'f5': 116,\n 'f6': 117,\n 'f7': 118,\n 'f8': 119,\n 'f9': 120,\n 'f10': 121,\n 'f11': 122,\n 'f12': 123,\n 'f13': 124,\n 'f14': 125,\n 'f15': 126,\n 'f16': 127,\n 'f17': 128,\n 'f18': 129,\n 'f19': 130,\n 'f20': 131,\n}\n\nexport function isHotkey(hotkey: string, event: KeyboardEventLike): boolean {\n return compareHotkey(parseHotkey(hotkey), event)\n}\n\nfunction parseHotkey(hotkey: string): HotKey {\n // Ensure that all the modifiers are set to false unless the hotkey has them.\n const parsedHotkey: HotKey = {\n altKey: false,\n ctrlKey: false,\n metaKey: false,\n shiftKey: false,\n }\n\n // Special case to handle the `+` key since we use it as a separator.\n const hotkeySegments = hotkey.replace('++', '+add').split('+')\n\n for (const rawHotkeySegment of hotkeySegments) {\n const optional =\n rawHotkeySegment.endsWith('?') && rawHotkeySegment.length > 1\n const hotkeySegment = optional\n ? rawHotkeySegment.slice(0, -1)\n : rawHotkeySegment\n const keyName = toKeyName(hotkeySegment)\n const modifier = modifiers[keyName]\n const alias = aliases[hotkeySegment]\n const code = keyCodes[keyName]\n\n if (\n hotkeySegment.length > 1 &&\n modifier === undefined &&\n alias === undefined &&\n code === undefined\n ) {\n throw new TypeError(`Unknown modifier: \"${hotkeySegment}\"`)\n }\n\n if (hotkeySegments.length === 1 || modifier === undefined) {\n parsedHotkey.key = keyName\n parsedHotkey.keyCode = toKeyCode(hotkeySegment)\n }\n\n if (modifier !== undefined) {\n parsedHotkey[modifier] = optional ? null : true\n }\n }\n\n return parsedHotkey\n}\n\nfunction compareHotkey(\n parsedHotkey: HotKey,\n event: KeyboardEventLike,\n): boolean {\n const matchingModifiers =\n (parsedHotkey.altKey != null\n ? parsedHotkey.altKey === event.altKey\n : true) &&\n (parsedHotkey.ctrlKey != null\n ? parsedHotkey.ctrlKey === event.ctrlKey\n : true) &&\n (parsedHotkey.metaKey != null\n ? parsedHotkey.metaKey === event.metaKey\n : true) &&\n (parsedHotkey.shiftKey != null\n ? parsedHotkey.shiftKey === event.shiftKey\n : true)\n\n if (!matchingModifiers) {\n return false\n }\n\n if (parsedHotkey.keyCode !== undefined && event.keyCode !== undefined) {\n if (parsedHotkey.keyCode === 91 && event.keyCode === 93) {\n return true\n }\n\n return parsedHotkey.keyCode === event.keyCode\n }\n\n return (\n parsedHotkey.keyCode === event.keyCode ||\n parsedHotkey.key === event.key.toLowerCase()\n )\n}\n\nfunction toKeyCode(name: string): number {\n const keyName = toKeyName(name)\n const keyCode = keyCodes[keyName] ?? keyName.toUpperCase().charCodeAt(0)\n\n return keyCode\n}\n\nfunction toKeyName(name: string): string {\n const keyName = name.toLowerCase()\n\n return aliases[keyName] ?? keyName\n}\n","import type {KeyedSegment, PortableTextTextBlock} from '@sanity/types'\nimport type {TextUnit} from 'slate'\nimport type {TextInsertTextOptions} from 'slate/dist/interfaces/transforms/text'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport type {PickFromUnion} from '../type-utils'\nimport type {EditorSelection, PortableTextSlateEditor} from '../types/editor'\n\n/**\n * @alpha\n */\nexport type SyntheticBehaviorEvent =\n | {\n type: 'annotation.add'\n annotation: {\n name: string\n value: {[prop: string]: unknown}\n }\n }\n | {\n type: 'annotation.remove'\n annotation: {\n name: string\n }\n }\n | {\n type: 'annotation.toggle'\n annotation: {\n name: string\n value: {[prop: string]: unknown}\n }\n }\n | {\n type: 'blur'\n }\n | {\n type: 'decorator.add'\n decorator: string\n }\n | {\n type: 'decorator.remove'\n decorator: string\n }\n | {\n type: 'decorator.toggle'\n decorator: string\n }\n | {\n type: 'delete.backward'\n unit: TextUnit\n }\n | {\n type: 'delete.forward'\n unit: TextUnit\n }\n | {\n type: 'focus'\n }\n | {\n type: 'insert.block object'\n placement: 'auto' | 'after' | 'before'\n blockObject: {\n name: string\n value?: {[prop: string]: unknown}\n }\n }\n | {\n type: 'insert.inline object'\n inlineObject: {\n name: string\n value?: {[prop: string]: unknown}\n }\n }\n | {\n type: 'insert.break'\n }\n | {\n type: 'insert.soft break'\n }\n | {\n type: 'insert.text'\n text: string\n options?: TextInsertTextOptions\n }\n | {\n type: 'list item.toggle'\n listItem: string\n }\n | {\n type: 'style.toggle'\n style: string\n }\n\n/**\n * @alpha\n */\nexport type NativeBehaviorEvent =\n | {\n type: 'copy'\n data: DataTransfer\n }\n | {\n type: 'key.down'\n keyboardEvent: Pick<\n KeyboardEvent,\n 'key' | 'code' | 'altKey' | 'ctrlKey' | 'metaKey' | 'shiftKey'\n >\n }\n | {\n type: 'key.up'\n keyboardEvent: Pick<\n KeyboardEvent,\n 'key' | 'code' | 'altKey' | 'ctrlKey' | 'metaKey' | 'shiftKey'\n >\n }\n | {\n type: 'paste'\n data: DataTransfer\n }\n\n/**\n * @alpha\n */\nexport type BehaviorActionIntend =\n | SyntheticBehaviorEvent\n | {\n type: 'insert.span'\n text: string\n annotations?: Array<{\n name: string\n value: {[prop: string]: unknown}\n }>\n decorators?: Array<string>\n }\n | {\n type: 'insert.text block'\n placement: 'auto' | 'after' | 'before'\n textBlock?: {\n children?: PortableTextTextBlock['children']\n }\n }\n | {\n type: 'list item.add'\n listItem: string\n }\n | {\n type: 'list item.remove'\n listItem: string\n }\n | {\n type: 'move.block'\n at: [KeyedSegment]\n to: [KeyedSegment]\n }\n | {\n type: 'move.block down'\n at: [KeyedSegment]\n }\n | {\n type: 'move.block up'\n at: [KeyedSegment]\n }\n | {\n type: 'noop'\n }\n | {\n type: 'delete.block'\n blockPath: [KeyedSegment]\n }\n | {\n type: 'delete.text'\n anchor: BlockOffset\n focus: BlockOffset\n }\n | {\n type: 'effect'\n effect: () => void\n }\n | {\n type: 'reselect'\n }\n | {\n type: 'select'\n selection: EditorSelection\n }\n | {\n type: 'select.previous block'\n }\n | {\n type: 'select.next block'\n }\n | {\n type: 'style.add'\n style: string\n }\n | {\n type: 'style.remove'\n style: string\n }\n | {\n type: 'text block.set'\n at: [KeyedSegment]\n level?: number\n listItem?: string\n style?: string\n }\n | {\n type: 'text block.unset'\n at: [KeyedSegment]\n props: Array<'level' | 'listItem' | 'style'>\n }\n\n/**\n * @alpha\n */\nexport type BehaviorAction = BehaviorActionIntend & {\n editor: PortableTextSlateEditor\n}\n\n/**\n * @alpha\n */\nexport type BehaviorEvent = SyntheticBehaviorEvent | NativeBehaviorEvent\n\n/**\n * @alpha\n */\nexport type Behavior<\n TBehaviorEventType extends BehaviorEvent['type'] = BehaviorEvent['type'],\n TGuardResponse = true,\n> = {\n /**\n * The internal editor event that triggers this behavior.\n */\n on: TBehaviorEventType\n /**\n * Predicate function that determines if the behavior should be executed.\n * Returning a non-nullable value from the guard will pass the value to the\n * actions and execute them.\n */\n guard?: BehaviorGuard<\n PickFromUnion<BehaviorEvent, 'type', TBehaviorEventType>,\n TGuardResponse\n >\n /**\n * Array of behavior action sets.\n */\n actions: Array<BehaviorActionIntendSet<TBehaviorEventType, TGuardResponse>>\n}\n\n/**\n * @alpha\n */\nexport type BehaviorGuard<\n TBehaviorEvent extends BehaviorEvent,\n TGuardResponse,\n> = ({\n context,\n event,\n}: {\n context: EditorContext\n event: TBehaviorEvent\n}) => TGuardResponse | false\n\n/**\n * @alpha\n */\nexport type BehaviorActionIntendSet<\n TBehaviorEventType extends BehaviorEvent['type'] = BehaviorEvent['type'],\n TGuardResponse = true,\n> = (\n {\n context,\n event,\n }: {\n context: EditorContext\n event: PickFromUnion<BehaviorEvent, 'type', TBehaviorEventType>\n },\n guardResponse: TGuardResponse,\n) => Array<BehaviorActionIntend>\n\n/**\n * @alpha\n */\nexport function defineBehavior<\n TAnyBehaviorEventType extends BehaviorEvent['type'],\n TGuardResponse = true,\n>(behavior: Behavior<TAnyBehaviorEventType, TGuardResponse>): Behavior {\n return behavior as unknown as Behavior\n}\n\n/**\n * @alpha\n */\nexport type BlockOffset = {\n path: [KeyedSegment]\n offset: number\n}\n","import {isPortableTextTextBlock} from '@sanity/types'\nimport {isEmptyTextBlock} from '../editor/utils/utils'\nimport * as selectors from '../selectors'\nimport {isHotkey} from '../utils/is-hotkey'\nimport {defineBehavior} from './behavior.types'\n\nconst arrowDownOnLonelyBlockObject = defineBehavior({\n on: 'key.down',\n guard: ({context, event}) => {\n const isArrowDown = isHotkey('ArrowDown', event.keyboardEvent)\n const focusBlockObject = selectors.getFocusBlockObject({context})\n const nextBlock = selectors.getNextBlock({context})\n\n return isArrowDown && focusBlockObject && !nextBlock\n },\n actions: [() => [{type: 'insert.text block', placement: 'after'}]],\n})\n\nconst arrowUpOnLonelyBlockObject = defineBehavior({\n on: 'key.down',\n guard: ({context, event}) => {\n const isArrowUp = isHotkey('ArrowUp', event.keyboardEvent)\n const focusBlockObject = selectors.getFocusBlockObject({context})\n const previousBlock = selectors.getPreviousBlock({context})\n\n return isArrowUp && focusBlockObject && !previousBlock\n },\n actions: [\n () => [\n {type: 'insert.text block', placement: 'before'},\n {type: 'select.previous block'},\n ],\n ],\n})\n\nconst breakingBlockObject = defineBehavior({\n on: 'insert.break',\n guard: ({context}) => {\n const focusBlockObject = selectors.getFocusBlockObject({context})\n const collapsedSelection = selectors.isSelectionCollapsed({context})\n\n return collapsedSelection && focusBlockObject !== undefined\n },\n actions: [() => [{type: 'insert.text block', placement: 'after'}]],\n})\n\nconst deletingEmptyTextBlockAfterBlockObject = defineBehavior({\n on: 'delete.backward',\n guard: ({context}) => {\n const focusTextBlock = selectors.getFocusTextBlock({context})\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n const previousBlock = selectors.getPreviousBlock({context})\n\n if (!focusTextBlock || !selectionCollapsed || !previousBlock) {\n return false\n }\n\n if (\n isEmptyTextBlock(focusTextBlock.node) &&\n !isPortableTextTextBlock(previousBlock.node)\n ) {\n return {focusTextBlock, previousBlock}\n }\n\n return false\n },\n actions: [\n (_, {focusTextBlock, previousBlock}) => [\n {\n type: 'delete.block',\n blockPath: focusTextBlock.path,\n },\n {\n type: 'select',\n selection: {\n anchor: {path: previousBlock.path, offset: 0},\n focus: {path: previousBlock.path, offset: 0},\n },\n },\n ],\n ],\n})\n\nconst deletingEmptyTextBlockBeforeBlockObject = defineBehavior({\n on: 'delete.forward',\n guard: ({context}) => {\n const focusTextBlock = selectors.getFocusTextBlock({context})\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n const nextBlock = selectors.getNextBlock({context})\n\n if (!focusTextBlock || !selectionCollapsed || !nextBlock) {\n return false\n }\n\n if (\n isEmptyTextBlock(focusTextBlock.node) &&\n !isPortableTextTextBlock(nextBlock.node)\n ) {\n return {focusTextBlock, nextBlock}\n }\n\n return false\n },\n actions: [\n (_, {focusTextBlock, nextBlock}) => [\n {\n type: 'delete.block',\n blockPath: focusTextBlock.path,\n },\n {\n type: 'select',\n selection: {\n anchor: {path: nextBlock.path, offset: 0},\n focus: {path: nextBlock.path, offset: 0},\n },\n },\n ],\n ],\n})\n\nexport const coreBlockObjectBehaviors = {\n arrowDownOnLonelyBlockObject,\n arrowUpOnLonelyBlockObject,\n breakingBlockObject,\n deletingEmptyTextBlockAfterBlockObject,\n deletingEmptyTextBlockBeforeBlockObject,\n}\n","import {defineBehavior} from './behavior.types'\n\nconst decoratorAdd = defineBehavior({\n on: 'decorator.add',\n actions: [\n ({event}) => [\n event,\n {\n type: 'reselect',\n },\n ],\n ],\n})\n\nconst decoratorRemove = defineBehavior({\n on: 'decorator.remove',\n guard: ({event}) => ({decorator: event.decorator}),\n actions: [\n ({event}) => [\n event,\n {\n type: 'reselect',\n },\n ],\n ],\n})\n\nconst decoratorToggle = defineBehavior({\n on: 'decorator.toggle',\n guard: ({event}) => ({decorator: event.decorator}),\n actions: [\n ({event}) => [\n event,\n {\n type: 'reselect',\n },\n ],\n ],\n})\n\nexport const coreDecoratorBehaviors = {\n decoratorAdd,\n decoratorRemove,\n decoratorToggle,\n}\n","import {createGuards} from '../behavior-actions/behavior.guards'\nimport {isEmptyTextBlock} from '../editor/utils/utils'\nimport * as selectors from '../selectors'\nimport {isHotkey} from '../utils/is-hotkey'\nimport {defineBehavior} from './behavior.types'\n\nconst MAX_LIST_LEVEL = 10\n\nconst clearListOnBackspace = defineBehavior({\n on: 'delete.backward',\n guard: ({context}) => {\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n const focusTextBlock = selectors.getFocusTextBlock({context})\n const focusSpan = selectors.getFocusSpan({context})\n\n if (!selectionCollapsed || !focusTextBlock || !focusSpan) {\n return false\n }\n\n const atTheBeginningOfBLock =\n focusTextBlock.node.children[0]._key === focusSpan.node._key &&\n context.selection?.focus.offset === 0\n\n if (atTheBeginningOfBLock && focusTextBlock.node.level === 1) {\n return {focusTextBlock}\n }\n\n return false\n },\n actions: [\n (_, {focusTextBlock}) => [\n {\n type: 'text block.unset',\n props: ['listItem', 'level'],\n at: focusTextBlock.path,\n },\n ],\n ],\n})\n\nconst unindentListOnBackspace = defineBehavior({\n on: 'delete.backward',\n guard: ({context}) => {\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n const focusTextBlock = selectors.getFocusTextBlock({context})\n const focusSpan = selectors.getFocusSpan({context})\n\n if (!selectionCollapsed || !focusTextBlock || !focusSpan) {\n return false\n }\n\n const atTheBeginningOfBLock =\n focusTextBlock.node.children[0]._key === focusSpan.node._key &&\n context.selection?.focus.offset === 0\n\n if (\n atTheBeginningOfBLock &&\n focusTextBlock.node.level !== undefined &&\n focusTextBlock.node.level > 1\n ) {\n return {focusTextBlock, level: focusTextBlock.node.level - 1}\n }\n\n return false\n },\n actions: [\n (_, {focusTextBlock, level}) => [\n {\n type: 'text block.set',\n level,\n at: focusTextBlock.path,\n },\n ],\n ],\n})\n\nconst clearListOnEnter = defineBehavior({\n on: 'insert.break',\n guard: ({context}) => {\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n const focusListBlock = selectors.getFocusListBlock({context})\n\n if (\n !selectionCollapsed ||\n !focusListBlock ||\n !isEmptyTextBlock(focusListBlock.node)\n ) {\n return false\n }\n\n return {focusListBlock}\n },\n actions: [\n (_, {focusListBlock}) => [\n {\n type: 'text block.unset',\n props: ['listItem', 'level'],\n at: focusListBlock.path,\n },\n ],\n ],\n})\n\nconst indentListOnTab = defineBehavior({\n on: 'key.down',\n guard: ({context, event}) => {\n const isTab = isHotkey('Tab', event.keyboardEvent)\n\n if (!isTab) {\n return false\n }\n\n const selectedBlocks = selectors.getSelectedBlocks({context})\n const guards = createGuards(context)\n const selectedListBlocks = selectedBlocks.flatMap((block) =>\n guards.isListBlock(block.node)\n ? [\n {\n node: block.node,\n path: block.path,\n },\n ]\n : [],\n )\n\n if (selectedListBlocks.length === selectedBlocks.length) {\n return {selectedListBlocks}\n }\n\n return false\n },\n actions: [\n (_, {selectedListBlocks}) =>\n selectedListBlocks.map((selectedListBlock) => ({\n type: 'text block.set',\n level: Math.min(\n MAX_LIST_LEVEL,\n Math.max(1, selectedListBlock.node.level + 1),\n ),\n at: selectedListBlock.path,\n })),\n ],\n})\n\nconst unindentListOnShiftTab = defineBehavior({\n on: 'key.down',\n guard: ({context, event}) => {\n const isShiftTab = isHotkey('Shift+Tab', event.keyboardEvent)\n\n if (!isShiftTab) {\n return false\n }\n\n const selectedBlocks = selectors.getSelectedBlocks({context})\n const guards = createGuards(context)\n const selectedListBlocks = selectedBlocks.flatMap((block) =>\n guards.isListBlock(block.node)\n ? [\n {\n node: block.node,\n path: block.path,\n },\n ]\n : [],\n )\n\n if (selectedListBlocks.length === selectedBlocks.length) {\n return {selectedListBlocks}\n }\n\n return false\n },\n actions: [\n (_, {selectedListBlocks}) =>\n selectedListBlocks.map((selectedListBlock) => ({\n type: 'text block.set',\n level: Math.min(\n MAX_LIST_LEVEL,\n Math.max(1, selectedListBlock.node.level - 1),\n ),\n at: selectedListBlock.path,\n })),\n ],\n})\n\nexport const coreListBehaviors = {\n clearListOnBackspace,\n unindentListOnBackspace,\n clearListOnEnter,\n indentListOnTab,\n unindentListOnShiftTab,\n}\n","import {coreBlockObjectBehaviors} from './behavior.core.block-objects'\nimport {coreDecoratorBehaviors} from './behavior.core.decorators'\nimport {coreListBehaviors} from './behavior.core.lists'\nimport {defineBehavior} from './behavior.types'\n\nconst softReturn = defineBehavior({\n on: 'insert.soft break',\n actions: [() => [{type: 'insert.text', text: '\\n'}]],\n})\n\n/**\n * @alpha\n */\nexport const coreBehaviors = [\n softReturn,\n coreDecoratorBehaviors.decoratorAdd,\n coreDecoratorBehaviors.decoratorRemove,\n coreDecoratorBehaviors.decoratorToggle,\n coreBlockObjectBehaviors.arrowDownOnLonelyBlockObject,\n coreBlockObjectBehaviors.arrowUpOnLonelyBlockObject,\n coreBlockObjectBehaviors.breakingBlockObject,\n coreBlockObjectBehaviors.deletingEmptyTextBlockAfterBlockObject,\n coreBlockObjectBehaviors.deletingEmptyTextBlockBeforeBlockObject,\n coreListBehaviors.clearListOnBackspace,\n coreListBehaviors.unindentListOnBackspace,\n coreListBehaviors.clearListOnEnter,\n coreListBehaviors.indentListOnTab,\n coreListBehaviors.unindentListOnShiftTab,\n]\n\n/**\n * @alpha\n */\nexport const coreBehavior = {\n softReturn,\n decorators: coreDecoratorBehaviors,\n blockObjects: coreBlockObjectBehaviors,\n lists: coreListBehaviors,\n}\n"],"names":["blockOffsetToSpanSelectionPoint","value","blockOffset","offsetLeft","offset","selectionPoint","block","_key","path","isPortableTextTextBlock","child","children","isPortableTextSpan","text","length","spanSelectionPointToBlockOffset","isEmptyTextBlock","onlyText","every","blockText","getTextBlockText","map","join","IS_MAC","window","test","navigator","userAgent","modifiers","alt","control","meta","shift","aliases","add","break","cmd","command","ctl","ctrl","del","down","esc","ins","left","mod","opt","option","return","right","space","spacebar","up","win","windows","keyCodes","isHotkey","hotkey","event","compareHotkey","parseHotkey","parsedHotkey","altKey","ctrlKey","metaKey","shiftKey","hotkeySegments","replace","split","rawHotkeySegment","optional","endsWith","hotkeySegment","slice","keyName","toKeyName","modifier","alias","code","undefined","TypeError","key","keyCode","toKeyCode","toLowerCase","name","toUpperCase","charCodeAt","defineBehavior","behavior","arrowDownOnLonelyBlockObject","on","guard","context","isArrowDown","keyboardEvent","focusBlockObject","selectors","nextBlock","actions","type","placement","arrowUpOnLonelyBlockObject","isArrowUp","previousBlock","breakingBlockObject","deletingEmptyTextBlockAfterBlockObject","focusTextBlock","selectionCollapsed","node","_","blockPath","selection","anchor","focus","deletingEmptyTextBlockBeforeBlockObject","coreBlockObjectBehaviors","decoratorAdd","decoratorRemove","decorator","decoratorToggle","coreDecoratorBehaviors","MAX_LIST_LEVEL","clearListOnBackspace","focusSpan","level","props","at","unindentListOnBackspace","clearListOnEnter","focusListBlock","indentListOnTab","selectedBlocks","guards","createGuards","selectedListBlocks","flatMap","isListBlock","selectedListBlock","Math","min","max","unindentListOnShiftTab","coreListBehaviors","softReturn","coreBehaviors","coreBehavior","decorators","blockObjects","lists"],"mappings":"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"}
@@ -1,18 +1,4 @@
1
1
  import { isPortableTextTextBlock, isPortableTextSpan } from "@sanity/types";
2
- function getStartPoint({
3
- node,
4
- path
5
- }) {
6
- return isPortableTextTextBlock(node) ? {
7
- path: [...path, "children", {
8
- _key: node.children[0]._key
9
- }],
10
- offset: 0
11
- } : {
12
- path,
13
- offset: 0
14
- };
15
- }
16
2
  function isKeyedSegment(segment) {
17
3
  return typeof segment == "object" && segment !== null && "_key" in segment;
18
4
  }
@@ -62,6 +48,20 @@ const getSelectionText = ({
62
48
  }
63
49
  return text;
64
50
  };
51
+ function getStartPoint({
52
+ node,
53
+ path
54
+ }) {
55
+ return isPortableTextTextBlock(node) ? {
56
+ path: [...path, "children", {
57
+ _key: node.children[0]._key
58
+ }],
59
+ offset: 0
60
+ } : {
61
+ path,
62
+ offset: 0
63
+ };
64
+ }
65
65
  var __defProp = Object.defineProperty, __defProps = Object.defineProperties, __getOwnPropDescs = Object.getOwnPropertyDescriptors, __getOwnPropSymbols = Object.getOwnPropertySymbols, __hasOwnProp = Object.prototype.hasOwnProperty, __propIsEnum = Object.prototype.propertyIsEnumerable, __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value, __spreadValues = (a, b) => {
66
66
  for (var prop in b || (b = {}))
67
67
  __hasOwnProp.call(b, prop) && __defNormalProp(a, prop, b[prop]);
@@ -1 +1 @@
1
- {"version":3,"file":"selector.get-text-before.js","sources":["../../src/editor/utils/utils.get-start-point.ts","../../src/editor/utils/utils.is-keyed-segment.ts","../../src/editor/utils/utils.reverse-selection.ts","../../src/selectors/selector.get-selection-text.ts","../../src/selectors/selector.get-text-before.ts"],"sourcesContent":["import {\n isPortableTextTextBlock,\n type KeyedSegment,\n type PortableTextBlock,\n} from '@sanity/types'\nimport type {EditorSelectionPoint} from '../../types/editor'\n\nexport function getStartPoint({\n node,\n path,\n}: {\n node: PortableTextBlock\n path: [KeyedSegment]\n}): EditorSelectionPoint {\n if (isPortableTextTextBlock(node)) {\n return {\n path: [...path, 'children', {_key: node.children[0]._key}],\n offset: 0,\n }\n }\n\n return {\n path,\n offset: 0,\n }\n}\n","import type {KeyedSegment, PathSegment} from '@sanity/types'\n\nexport function isKeyedSegment(segment: PathSegment): segment is KeyedSegment {\n return typeof segment === 'object' && segment !== null && '_key' in segment\n}\n","import type {EditorSelection} from '../../types/editor'\n\nexport function reverseSelection(\n selection: NonNullable<EditorSelection>,\n): NonNullable<EditorSelection> {\n if (selection.backward) {\n return {\n anchor: selection.focus,\n focus: selection.anchor,\n backward: false,\n }\n }\n\n return {\n anchor: selection.focus,\n focus: selection.anchor,\n backward: true,\n }\n}\n","import {isPortableTextSpan, isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {isKeyedSegment} from '../editor/utils/utils.is-keyed-segment'\nimport {reverseSelection} from '../editor/utils/utils.reverse-selection'\n\n/**\n * @alpha\n */\nexport const getSelectionText: EditorSelector<string> = ({context}) => {\n let text = ''\n\n const {value, selection} = context\n\n if (!value || !selection) {\n return text\n }\n\n const forwardSelection = selection.backward\n ? reverseSelection(selection)\n : selection\n\n if (!forwardSelection) {\n return text\n }\n\n for (const block of value) {\n if (\n isKeyedSegment(forwardSelection.anchor.path[0]) &&\n block._key !== forwardSelection.anchor.path[0]._key\n ) {\n continue\n }\n\n if (!isPortableTextTextBlock(block)) {\n continue\n }\n\n for (const child of block.children) {\n if (isPortableTextSpan(child)) {\n if (\n isKeyedSegment(forwardSelection.anchor.path[2]) &&\n child._key === forwardSelection.anchor.path[2]._key &&\n isKeyedSegment(forwardSelection.focus.path[2]) &&\n child._key === forwardSelection.focus.path[2]._key\n ) {\n text =\n text +\n child.text.slice(\n forwardSelection.anchor.offset,\n forwardSelection.focus.offset,\n )\n\n break\n }\n\n if (\n isKeyedSegment(forwardSelection.anchor.path[2]) &&\n child._key === forwardSelection.anchor.path[2]._key\n ) {\n text = text + child.text.slice(forwardSelection.anchor.offset)\n continue\n }\n\n if (\n isKeyedSegment(forwardSelection.focus.path[2]) &&\n child._key === forwardSelection.focus.path[2]._key\n ) {\n text = text + child.text.slice(0, forwardSelection.focus.offset)\n break\n }\n\n if (text.length > 0) {\n text + child.text\n }\n }\n }\n\n if (\n isKeyedSegment(forwardSelection.focus.path[0]) &&\n block._key === forwardSelection.focus.path[0]._key\n ) {\n break\n }\n }\n\n return text\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {getStartPoint} from '../editor/utils/utils.get-start-point'\nimport {isKeyedSegment} from '../editor/utils/utils.is-keyed-segment'\nimport {reverseSelection} from '../editor/utils/utils.reverse-selection'\nimport {getSelectionText} from './selector.get-selection-text'\n\n/**\n * @alpha\n */\nexport const getBlockTextBefore: EditorSelector<string> = ({context}) => {\n if (!context.selection) {\n return ''\n }\n\n const selection = context.selection.backward\n ? reverseSelection(context.selection)\n : context.selection\n const point = selection.anchor\n const key = isKeyedSegment(point.path[0]) ? point.path[0]._key : undefined\n\n const block = key\n ? context.value.find((block) => block._key === key)\n : undefined\n\n if (!block) {\n return ''\n }\n\n const startOfBlock = getStartPoint({node: block, path: [{_key: block._key}]})\n\n return getSelectionText({\n context: {\n ...context,\n value: context.value,\n selection: {\n anchor: startOfBlock,\n focus: point,\n },\n },\n })\n}\n"],"names":["getStartPoint","node","path","isPortableTextTextBlock","_key","children","offset","isKeyedSegment","segment","reverseSelection","selection","backward","anchor","focus","getSelectionText","context","text","value","forwardSelection","block","child","isPortableTextSpan","slice","getBlockTextBefore","point","key","undefined","find","startOfBlock"],"mappings":";AAOO,SAASA,cAAc;AAAA,EAC5BC;AAAAA,EACAC;AAIF,GAAyB;AACnBC,SAAAA,wBAAwBF,IAAI,IACvB;AAAA,IACLC,MAAM,CAAC,GAAGA,MAAM,YAAY;AAAA,MAACE,MAAMH,KAAKI,SAAS,CAAC,EAAED;AAAAA,IAAAA,CAAK;AAAA,IACzDE,QAAQ;AAAA,EAAA,IAIL;AAAA,IACLJ;AAAAA,IACAI,QAAQ;AAAA,EACV;AACF;ACvBO,SAASC,eAAeC,SAA+C;AAC5E,SAAO,OAAOA,WAAY,YAAYA,YAAY,QAAQ,UAAUA;AACtE;ACFO,SAASC,iBACdC,WAC8B;AAC9B,SAAIA,UAAUC,WACL;AAAA,IACLC,QAAQF,UAAUG;AAAAA,IAClBA,OAAOH,UAAUE;AAAAA,IACjBD,UAAU;AAAA,EAAA,IAIP;AAAA,IACLC,QAAQF,UAAUG;AAAAA,IAClBA,OAAOH,UAAUE;AAAAA,IACjBD,UAAU;AAAA,EACZ;AACF;ACVO,MAAMG,mBAA2CA,CAAC;AAAA,EAACC;AAAO,MAAM;AACrE,MAAIC,OAAO;AAEL,QAAA;AAAA,IAACC;AAAAA,IAAOP;AAAAA,EAAAA,IAAaK;AAEvB,MAAA,CAACE,SAAS,CAACP;AACNM,WAAAA;AAGT,QAAME,mBAAmBR,UAAUC,WAC/BF,iBAAiBC,SAAS,IAC1BA;AAEJ,MAAI,CAACQ;AACIF,WAAAA;AAGT,aAAWG,SAASF;AAClB,QACEV,iBAAeW,iBAAiBN,OAAOV,KAAK,CAAC,CAAC,KAC9CiB,MAAMf,SAASc,iBAAiBN,OAAOV,KAAK,CAAC,EAAEE,SAK5CD,wBAAwBgB,KAAK,GAIlC;AAAA,iBAAWC,SAASD,MAAMd;AACpBgB,YAAAA,mBAAmBD,KAAK,GAAG;AAC7B,cACEb,eAAeW,iBAAiBN,OAAOV,KAAK,CAAC,CAAC,KAC9CkB,MAAMhB,SAASc,iBAAiBN,OAAOV,KAAK,CAAC,EAAEE,QAC/CG,eAAeW,iBAAiBL,MAAMX,KAAK,CAAC,CAAC,KAC7CkB,MAAMhB,SAASc,iBAAiBL,MAAMX,KAAK,CAAC,EAAEE,MAC9C;AAEEY,mBAAAA,OACAI,MAAMJ,KAAKM,MACTJ,iBAAiBN,OAAON,QACxBY,iBAAiBL,MAAMP,MACzB;AAEF;AAAA,UAAA;AAGF,cACEC,eAAeW,iBAAiBN,OAAOV,KAAK,CAAC,CAAC,KAC9CkB,MAAMhB,SAASc,iBAAiBN,OAAOV,KAAK,CAAC,EAAEE,MAC/C;AACAY,mBAAOA,OAAOI,MAAMJ,KAAKM,MAAMJ,iBAAiBN,OAAON,MAAM;AAC7D;AAAA,UAAA;AAGF,cACEC,eAAeW,iBAAiBL,MAAMX,KAAK,CAAC,CAAC,KAC7CkB,MAAMhB,SAASc,iBAAiBL,MAAMX,KAAK,CAAC,EAAEE,MAC9C;AACAY,mBAAOA,OAAOI,MAAMJ,KAAKM,MAAM,GAAGJ,iBAAiBL,MAAMP,MAAM;AAC/D;AAAA,UAAA;AAAA,QAIaU;AAKnB,UACET,eAAeW,iBAAiBL,MAAMX,KAAK,CAAC,CAAC,KAC7CiB,MAAMf,SAASc,iBAAiBL,MAAMX,KAAK,CAAC,EAAEE;AAE9C;AAAA,IAAA;AAIGY,SAAAA;AACT;;;;;;;;;AC7EO,MAAMO,qBAA6CA,CAAC;AAAA,EAACR;AAAO,MAAM;AACvE,MAAI,CAACA,QAAQL;AACJ,WAAA;AAMT,QAAMc,SAHYT,QAAQL,UAAUC,WAChCF,iBAAiBM,QAAQL,SAAS,IAClCK,QAAQL,WACYE,QAClBa,MAAMlB,eAAeiB,MAAMtB,KAAK,CAAC,CAAC,IAAIsB,MAAMtB,KAAK,CAAC,EAAEE,OAAOsB,QAE3DP,QAAQM,MACVV,QAAQE,MAAMU,KAAMR,CAAAA,WAAUA,OAAMf,SAASqB,GAAG,IAChDC;AAEJ,MAAI,CAACP;AACI,WAAA;AAGT,QAAMS,eAAe5B,cAAc;AAAA,IAACC,MAAMkB;AAAAA,IAAOjB,MAAM,CAAC;AAAA,MAACE,MAAMe,MAAMf;AAAAA,IAAK,CAAA;AAAA,EAAA,CAAE;AAE5E,SAAOU,iBAAiB;AAAA,IACtBC,SAAS,iCACJA,OADI,GAAA;AAAA,MAEPE,OAAOF,QAAQE;AAAAA,MACfP,WAAW;AAAA,QACTE,QAAQgB;AAAAA,QACRf,OAAOW;AAAAA,MAAAA;AAAAA,IAEX,CAAA;AAAA,EAAA,CACD;AACH;"}
1
+ {"version":3,"file":"selector.get-text-before.js","sources":["../../src/editor/utils/utils.is-keyed-segment.ts","../../src/editor/utils/utils.reverse-selection.ts","../../src/selectors/selector.get-selection-text.ts","../../src/editor/utils/utils.get-start-point.ts","../../src/selectors/selector.get-text-before.ts"],"sourcesContent":["import type {KeyedSegment, PathSegment} from '@sanity/types'\n\nexport function isKeyedSegment(segment: PathSegment): segment is KeyedSegment {\n return typeof segment === 'object' && segment !== null && '_key' in segment\n}\n","import type {EditorSelection} from '../../types/editor'\n\nexport function reverseSelection(\n selection: NonNullable<EditorSelection>,\n): NonNullable<EditorSelection> {\n if (selection.backward) {\n return {\n anchor: selection.focus,\n focus: selection.anchor,\n backward: false,\n }\n }\n\n return {\n anchor: selection.focus,\n focus: selection.anchor,\n backward: true,\n }\n}\n","import {isPortableTextSpan, isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {isKeyedSegment} from '../editor/utils/utils.is-keyed-segment'\nimport {reverseSelection} from '../editor/utils/utils.reverse-selection'\n\n/**\n * @alpha\n */\nexport const getSelectionText: EditorSelector<string> = ({context}) => {\n let text = ''\n\n const {value, selection} = context\n\n if (!value || !selection) {\n return text\n }\n\n const forwardSelection = selection.backward\n ? reverseSelection(selection)\n : selection\n\n if (!forwardSelection) {\n return text\n }\n\n for (const block of value) {\n if (\n isKeyedSegment(forwardSelection.anchor.path[0]) &&\n block._key !== forwardSelection.anchor.path[0]._key\n ) {\n continue\n }\n\n if (!isPortableTextTextBlock(block)) {\n continue\n }\n\n for (const child of block.children) {\n if (isPortableTextSpan(child)) {\n if (\n isKeyedSegment(forwardSelection.anchor.path[2]) &&\n child._key === forwardSelection.anchor.path[2]._key &&\n isKeyedSegment(forwardSelection.focus.path[2]) &&\n child._key === forwardSelection.focus.path[2]._key\n ) {\n text =\n text +\n child.text.slice(\n forwardSelection.anchor.offset,\n forwardSelection.focus.offset,\n )\n\n break\n }\n\n if (\n isKeyedSegment(forwardSelection.anchor.path[2]) &&\n child._key === forwardSelection.anchor.path[2]._key\n ) {\n text = text + child.text.slice(forwardSelection.anchor.offset)\n continue\n }\n\n if (\n isKeyedSegment(forwardSelection.focus.path[2]) &&\n child._key === forwardSelection.focus.path[2]._key\n ) {\n text = text + child.text.slice(0, forwardSelection.focus.offset)\n break\n }\n\n if (text.length > 0) {\n text + child.text\n }\n }\n }\n\n if (\n isKeyedSegment(forwardSelection.focus.path[0]) &&\n block._key === forwardSelection.focus.path[0]._key\n ) {\n break\n }\n }\n\n return text\n}\n","import {\n isPortableTextTextBlock,\n type KeyedSegment,\n type PortableTextBlock,\n} from '@sanity/types'\nimport type {EditorSelectionPoint} from '../../types/editor'\n\nexport function getStartPoint({\n node,\n path,\n}: {\n node: PortableTextBlock\n path: [KeyedSegment]\n}): EditorSelectionPoint {\n if (isPortableTextTextBlock(node)) {\n return {\n path: [...path, 'children', {_key: node.children[0]._key}],\n offset: 0,\n }\n }\n\n return {\n path,\n offset: 0,\n }\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {getStartPoint} from '../editor/utils/utils.get-start-point'\nimport {isKeyedSegment} from '../editor/utils/utils.is-keyed-segment'\nimport {reverseSelection} from '../editor/utils/utils.reverse-selection'\nimport {getSelectionText} from './selector.get-selection-text'\n\n/**\n * @alpha\n */\nexport const getBlockTextBefore: EditorSelector<string> = ({context}) => {\n if (!context.selection) {\n return ''\n }\n\n const selection = context.selection.backward\n ? reverseSelection(context.selection)\n : context.selection\n const point = selection.anchor\n const key = isKeyedSegment(point.path[0]) ? point.path[0]._key : undefined\n\n const block = key\n ? context.value.find((block) => block._key === key)\n : undefined\n\n if (!block) {\n return ''\n }\n\n const startOfBlock = getStartPoint({node: block, path: [{_key: block._key}]})\n\n return getSelectionText({\n context: {\n ...context,\n value: context.value,\n selection: {\n anchor: startOfBlock,\n focus: point,\n },\n },\n })\n}\n"],"names":["isKeyedSegment","segment","reverseSelection","selection","backward","anchor","focus","getSelectionText","context","text","value","forwardSelection","block","path","_key","isPortableTextTextBlock","child","children","isPortableTextSpan","slice","offset","getStartPoint","node","getBlockTextBefore","point","key","undefined","find","startOfBlock"],"mappings":"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"}
@@ -13,12 +13,7 @@ function createGuards({
13
13
  isTextBlock
14
14
  };
15
15
  }
16
- const selectionIsCollapsed = ({
17
- context
18
- }) => {
19
- var _a, _b, _c, _d;
20
- return JSON.stringify((_a = context.selection) == null ? void 0 : _a.anchor.path) === JSON.stringify((_b = context.selection) == null ? void 0 : _b.focus.path) && ((_c = context.selection) == null ? void 0 : _c.anchor.offset) === ((_d = context.selection) == null ? void 0 : _d.focus.offset);
21
- }, getFocusBlock = ({
16
+ const getFocusBlock = ({
22
17
  context
23
18
  }) => {
24
19
  const key = context.selection && isKeySegment(context.selection.focus.path[0]) ? context.selection.focus.path[0]._key : void 0, node = key ? context.value.find((block) => block._key === key) : void 0;
@@ -214,6 +209,11 @@ const selectionIsCollapsed = ({
214
209
  }
215
210
  if (foundSelectionEndBlock && nextBlock)
216
211
  return nextBlock;
212
+ }, isSelectionCollapsed = ({
213
+ context
214
+ }) => {
215
+ var _a, _b, _c, _d;
216
+ return JSON.stringify((_a = context.selection) == null ? void 0 : _a.anchor.path) === JSON.stringify((_b = context.selection) == null ? void 0 : _b.focus.path) && ((_c = context.selection) == null ? void 0 : _c.anchor.offset) === ((_d = context.selection) == null ? void 0 : _d.focus.offset);
217
217
  };
218
218
  export {
219
219
  createGuards,
@@ -230,6 +230,6 @@ export {
230
230
  getSelectedBlocks,
231
231
  getSelectionEndBlock,
232
232
  getSelectionStartBlock,
233
- selectionIsCollapsed
233
+ isSelectionCollapsed
234
234
  };
235
- //# sourceMappingURL=selectors.js.map
235
+ //# sourceMappingURL=selector.is-selection-collapsed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selector.is-selection-collapsed.js","sources":["../../src/behavior-actions/behavior.guards.ts","../../src/selectors/selectors.ts","../../src/selectors/selector.is-selection-collapsed.ts"],"sourcesContent":["import {\n isPortableTextListBlock,\n isPortableTextTextBlock,\n type PortableTextListBlock,\n type PortableTextTextBlock,\n} from '@sanity/types'\nimport type {EditorSchema} from '../editor/define-schema'\n\n/**\n * @alpha\n */\nexport type BehaviorGuards = ReturnType<typeof createGuards>\n\nexport function createGuards({schema}: {schema: EditorSchema}) {\n function isListBlock(block: unknown): block is PortableTextListBlock {\n return isPortableTextListBlock(block) && block._type === schema.block.name\n }\n\n function isTextBlock(block: unknown): block is PortableTextTextBlock {\n return isPortableTextTextBlock(block) && block._type === schema.block.name\n }\n\n return {isListBlock, isTextBlock}\n}\n","import {\n isKeySegment,\n isPortableTextSpan,\n isPortableTextTextBlock,\n type KeyedSegment,\n type PortableTextBlock,\n type PortableTextListBlock,\n type PortableTextObject,\n type PortableTextSpan,\n type PortableTextTextBlock,\n} from '@sanity/types'\nimport {createGuards} from '../behavior-actions/behavior.guards'\nimport type {EditorSelector} from '../editor/editor-selector'\n\n/**\n * @alpha\n */\nexport const getFocusBlock: EditorSelector<\n {node: PortableTextBlock; path: [KeyedSegment]} | undefined\n> = ({context}) => {\n const key = context.selection\n ? isKeySegment(context.selection.focus.path[0])\n ? context.selection.focus.path[0]._key\n : undefined\n : undefined\n\n const node = key\n ? context.value.find((block) => block._key === key)\n : undefined\n\n return node && key ? {node, path: [{_key: key}]} : undefined\n}\n\n/**\n * @alpha\n */\nexport const getFocusListBlock: EditorSelector<\n {node: PortableTextListBlock; path: [KeyedSegment]} | undefined\n> = ({context}) => {\n const guards = createGuards(context)\n const focusBlock = getFocusBlock({context})\n\n return focusBlock && guards.isListBlock(focusBlock.node)\n ? {node: focusBlock.node, path: focusBlock.path}\n : undefined\n}\n\n/**\n * @alpha\n */\nexport const getFocusTextBlock: EditorSelector<\n {node: PortableTextTextBlock; path: [KeyedSegment]} | undefined\n> = ({context}) => {\n const focusBlock = getFocusBlock({context})\n\n return focusBlock && isPortableTextTextBlock(focusBlock.node)\n ? {node: focusBlock.node, path: focusBlock.path}\n : undefined\n}\n\n/**\n * @alpha\n */\nexport const getFocusBlockObject: EditorSelector<\n {node: PortableTextObject; path: [KeyedSegment]} | undefined\n> = ({context}) => {\n const focusBlock = getFocusBlock({context})\n\n return focusBlock && !isPortableTextTextBlock(focusBlock.node)\n ? {node: focusBlock.node, path: focusBlock.path}\n : undefined\n}\n\n/**\n * @alpha\n */\nexport const getFocusChild: EditorSelector<\n | {\n node: PortableTextObject | PortableTextSpan\n path: [KeyedSegment, 'children', KeyedSegment]\n }\n | undefined\n> = ({context}) => {\n const focusBlock = getFocusTextBlock({context})\n\n if (!focusBlock) {\n return undefined\n }\n\n const key = context.selection\n ? isKeySegment(context.selection.focus.path[2])\n ? context.selection.focus.path[2]._key\n : undefined\n : undefined\n\n const node = key\n ? focusBlock.node.children.find((span) => span._key === key)\n : undefined\n\n return node && key\n ? {node, path: [...focusBlock.path, 'children', {_key: key}]}\n : undefined\n}\n\n/**\n * @alpha\n */\nexport const getFocusSpan: EditorSelector<\n | {node: PortableTextSpan; path: [KeyedSegment, 'children', KeyedSegment]}\n | undefined\n> = ({context}) => {\n const focusChild = getFocusChild({context})\n\n return focusChild && isPortableTextSpan(focusChild.node)\n ? {node: focusChild.node, path: focusChild.path}\n : undefined\n}\n\n/**\n * @alpha\n */\nexport const getFirstBlock: EditorSelector<\n {node: PortableTextBlock; path: [KeyedSegment]} | undefined\n> = ({context}) => {\n const node = context.value[0]\n\n return node ? {node, path: [{_key: node._key}]} : undefined\n}\n\n/**\n * @alpha\n */\nexport const getLastBlock: EditorSelector<\n {node: PortableTextBlock; path: [KeyedSegment]} | undefined\n> = ({context}) => {\n const node = context.value[context.value.length - 1]\n ? context.value[context.value.length - 1]\n : undefined\n\n return node ? {node, path: [{_key: node._key}]} : undefined\n}\n\n/**\n * @alpha\n */\nexport const getSelectedBlocks: EditorSelector<\n Array<{node: PortableTextBlock; path: [KeyedSegment]}>\n> = ({context}) => {\n if (!context.selection) {\n return []\n }\n\n const selectedBlocks: Array<{node: PortableTextBlock; path: [KeyedSegment]}> =\n []\n const startKey = context.selection.backward\n ? isKeySegment(context.selection.focus.path[0])\n ? context.selection.focus.path[0]._key\n : undefined\n : isKeySegment(context.selection.anchor.path[0])\n ? context.selection.anchor.path[0]._key\n : undefined\n const endKey = context.selection.backward\n ? isKeySegment(context.selection.anchor.path[0])\n ? context.selection.anchor.path[0]._key\n : undefined\n : isKeySegment(context.selection.focus.path[0])\n ? context.selection.focus.path[0]._key\n : undefined\n\n if (!startKey || !endKey) {\n return selectedBlocks\n }\n\n for (const block of context.value) {\n if (block._key === startKey) {\n selectedBlocks.push({node: block, path: [{_key: block._key}]})\n\n if (startKey === endKey) {\n break\n }\n continue\n }\n\n if (block._key === endKey) {\n selectedBlocks.push({node: block, path: [{_key: block._key}]})\n break\n }\n\n if (selectedBlocks.length > 0) {\n selectedBlocks.push({node: block, path: [{_key: block._key}]})\n }\n }\n\n return selectedBlocks\n}\n\n/**\n * @alpha\n */\nexport const getSelectionStartBlock: EditorSelector<\n | {\n node: PortableTextBlock\n path: [KeyedSegment]\n }\n | undefined\n> = ({context}) => {\n if (!context.selection) {\n return undefined\n }\n\n const key = context.selection.backward\n ? isKeySegment(context.selection.focus.path[0])\n ? context.selection.focus.path[0]._key\n : undefined\n : isKeySegment(context.selection.anchor.path[0])\n ? context.selection.anchor.path[0]._key\n : undefined\n\n const node = key\n ? context.value.find((block) => block._key === key)\n : undefined\n\n return node && key ? {node, path: [{_key: key}]} : undefined\n}\n\n/**\n * @alpha\n */\nexport const getSelectionEndBlock: EditorSelector<\n | {\n node: PortableTextBlock\n path: [KeyedSegment]\n }\n | undefined\n> = ({context}) => {\n if (!context.selection) {\n return undefined\n }\n\n const key = context.selection.backward\n ? isKeySegment(context.selection.anchor.path[0])\n ? context.selection.anchor.path[0]._key\n : undefined\n : isKeySegment(context.selection.focus.path[0])\n ? context.selection.focus.path[0]._key\n : undefined\n\n const node = key\n ? context.value.find((block) => block._key === key)\n : undefined\n\n return node && key ? {node, path: [{_key: key}]} : undefined\n}\n\n/**\n * @alpha\n */\nexport const getPreviousBlock: EditorSelector<\n {node: PortableTextBlock; path: [KeyedSegment]} | undefined\n> = ({context}) => {\n let previousBlock: {node: PortableTextBlock; path: [KeyedSegment]} | undefined\n const selectionStartBlock = getSelectionStartBlock({context})\n\n if (!selectionStartBlock) {\n return undefined\n }\n\n let foundSelectionStartBlock = false\n\n for (const block of context.value) {\n if (block._key === selectionStartBlock.node._key) {\n foundSelectionStartBlock = true\n break\n }\n\n previousBlock = {node: block, path: [{_key: block._key}]}\n }\n\n if (foundSelectionStartBlock && previousBlock) {\n return previousBlock\n }\n\n return undefined\n}\n\n/**\n * @alpha\n */\nexport const getNextBlock: EditorSelector<\n {node: PortableTextBlock; path: [KeyedSegment]} | undefined\n> = ({context}) => {\n let nextBlock: {node: PortableTextBlock; path: [KeyedSegment]} | undefined\n const selectionEndBlock = getSelectionEndBlock({context})\n\n if (!selectionEndBlock) {\n return undefined\n }\n\n let foundSelectionEndBlock = false\n\n for (const block of context.value) {\n if (block._key === selectionEndBlock.node._key) {\n foundSelectionEndBlock = true\n continue\n }\n\n if (foundSelectionEndBlock) {\n nextBlock = {node: block, path: [{_key: block._key}]}\n break\n }\n }\n\n if (foundSelectionEndBlock && nextBlock) {\n return nextBlock\n }\n\n return undefined\n}\n","import type {EditorSelector} from '../editor/editor-selector'\n\n/**\n * @alpha\n */\nexport const isSelectionCollapsed: EditorSelector<boolean> = ({context}) => {\n return (\n JSON.stringify(context.selection?.anchor.path) ===\n JSON.stringify(context.selection?.focus.path) &&\n context.selection?.anchor.offset === context.selection?.focus.offset\n )\n}\n"],"names":["createGuards","schema","isListBlock","block","isPortableTextListBlock","_type","name","isTextBlock","isPortableTextTextBlock","getFocusBlock","context","key","selection","isKeySegment","focus","path","_key","undefined","node","value","find","getFocusListBlock","guards","focusBlock","getFocusTextBlock","getFocusBlockObject","getFocusChild","children","span","getFocusSpan","focusChild","isPortableTextSpan","getFirstBlock","getLastBlock","length","getSelectedBlocks","selectedBlocks","startKey","backward","anchor","endKey","push","getSelectionStartBlock","getSelectionEndBlock","getPreviousBlock","previousBlock","selectionStartBlock","foundSelectionStartBlock","getNextBlock","nextBlock","selectionEndBlock","foundSelectionEndBlock","isSelectionCollapsed","JSON","stringify","offset"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: !0 });
3
- var selectors = require("../_chunks-cjs/selectors.cjs"), behavior_core = require("../_chunks-cjs/behavior.core.cjs"), types = require("@sanity/types"), selector_getTextBefore = require("../_chunks-cjs/selector.get-text-before.cjs");
3
+ var selector_isSelectionCollapsed = require("../_chunks-cjs/selector.is-selection-collapsed.cjs"), behavior_core = require("../_chunks-cjs/behavior.core.cjs"), types = require("@sanity/types"), selector_getTextBefore = require("../_chunks-cjs/selector.get-text-before.cjs");
4
4
  function createCodeEditorBehaviors(config) {
5
5
  return [behavior_core.defineBehavior({
6
6
  on: "key.down",
@@ -9,9 +9,9 @@ function createCodeEditorBehaviors(config) {
9
9
  event
10
10
  }) => {
11
11
  var _a;
12
- const isMoveUpShortcut = behavior_core.isHotkey(config.moveBlockUpShortcut, event.keyboardEvent), firstBlock = selectors.getFirstBlock({
12
+ const isMoveUpShortcut = behavior_core.isHotkey(config.moveBlockUpShortcut, event.keyboardEvent), firstBlock = selector_isSelectionCollapsed.getFirstBlock({
13
13
  context
14
- }), selectedBlocks = selectors.getSelectedBlocks({
14
+ }), selectedBlocks = selector_isSelectionCollapsed.getSelectedBlocks({
15
15
  context
16
16
  }), blocksAbove = (firstBlock == null ? void 0 : firstBlock.node._key) !== ((_a = selectedBlocks[0]) == null ? void 0 : _a.node._key);
17
17
  return !isMoveUpShortcut || !blocksAbove ? !1 : {
@@ -31,9 +31,9 @@ function createCodeEditorBehaviors(config) {
31
31
  event
32
32
  }) => {
33
33
  var _a;
34
- const isMoveDownShortcut = behavior_core.isHotkey(config.moveBlockDownShortcut, event.keyboardEvent), lastBlock = selectors.getLastBlock({
34
+ const isMoveDownShortcut = behavior_core.isHotkey(config.moveBlockDownShortcut, event.keyboardEvent), lastBlock = selector_isSelectionCollapsed.getLastBlock({
35
35
  context
36
- }), selectedBlocks = selectors.getSelectedBlocks({
36
+ }), selectedBlocks = selector_isSelectionCollapsed.getSelectedBlocks({
37
37
  context
38
38
  }), blocksBelow = (lastBlock == null ? void 0 : lastBlock.node._key) !== ((_a = selectedBlocks[selectedBlocks.length - 1]) == null ? void 0 : _a.node._key);
39
39
  return !isMoveDownShortcut || !blocksBelow ? !1 : {
@@ -56,7 +56,7 @@ function createLinkBehaviors(config) {
56
56
  event
57
57
  }) => {
58
58
  var _a;
59
- const selectionCollapsed = selectors.selectionIsCollapsed({
59
+ const selectionCollapsed = selector_isSelectionCollapsed.isSelectionCollapsed({
60
60
  context
61
61
  }), text = event.data.getData("text/plain"), url = looksLikeUrl(text) ? text : void 0, annotation = url !== void 0 ? (_a = config.linkAnnotation) == null ? void 0 : _a.call(config, {
62
62
  url,
@@ -79,9 +79,9 @@ function createLinkBehaviors(config) {
79
79
  event
80
80
  }) => {
81
81
  var _a;
82
- const focusSpan = selectors.getFocusSpan({
82
+ const focusSpan = selector_isSelectionCollapsed.getFocusSpan({
83
83
  context
84
- }), selectionCollapsed = selectors.selectionIsCollapsed({
84
+ }), selectionCollapsed = selector_isSelectionCollapsed.isSelectionCollapsed({
85
85
  context
86
86
  });
87
87
  if (!focusSpan || !selectionCollapsed)
@@ -133,11 +133,11 @@ function createMarkdownBehaviors(config) {
133
133
  var _a, _b, _c;
134
134
  if (event.text !== " ")
135
135
  return !1;
136
- const selectionCollapsed = selectors.selectionIsCollapsed({
136
+ const selectionCollapsed = selector_isSelectionCollapsed.isSelectionCollapsed({
137
137
  context
138
- }), focusTextBlock = selectors.getFocusTextBlock({
138
+ }), focusTextBlock = selector_isSelectionCollapsed.getFocusTextBlock({
139
139
  context
140
- }), focusSpan = selectors.getFocusSpan({
140
+ }), focusSpan = selector_isSelectionCollapsed.getFocusSpan({
141
141
  context
142
142
  });
143
143
  if (!selectionCollapsed || !focusTextBlock || !focusSpan)
@@ -196,9 +196,9 @@ function createMarkdownBehaviors(config) {
196
196
  const hrCharacter = event.text === "-" ? "-" : event.text === "*" ? "*" : event.text === "_" ? "_" : void 0;
197
197
  if (hrCharacter === void 0)
198
198
  return !1;
199
- const hrObject = (_a = config.horizontalRuleObject) == null ? void 0 : _a.call(config, context), focusBlock = selectors.getFocusTextBlock({
199
+ const hrObject = (_a = config.horizontalRuleObject) == null ? void 0 : _a.call(config, context), focusBlock = selector_isSelectionCollapsed.getFocusTextBlock({
200
200
  context
201
- }), selectionCollapsed = selectors.selectionIsCollapsed({
201
+ }), selectionCollapsed = selector_isSelectionCollapsed.isSelectionCollapsed({
202
202
  context
203
203
  });
204
204
  if (!hrObject || !focusBlock || !selectionCollapsed)
@@ -244,7 +244,7 @@ function createMarkdownBehaviors(config) {
244
244
  event
245
245
  }) => {
246
246
  var _a, _b;
247
- const text = event.data.getData("text/plain"), hrRegExp = /^(---)$|(___)$|(\*\*\*)$/gm, hrCharacters = (_a = text.match(hrRegExp)) == null ? void 0 : _a[0], hrObject = (_b = config.horizontalRuleObject) == null ? void 0 : _b.call(config, context), focusBlock = selectors.getFocusBlock({
247
+ const text = event.data.getData("text/plain"), hrRegExp = /^(---)$|(___)$|(\*\*\*)$/gm, hrCharacters = (_a = text.match(hrRegExp)) == null ? void 0 : _a[0], hrObject = (_b = config.horizontalRuleObject) == null ? void 0 : _b.call(config, context), focusBlock = selector_isSelectionCollapsed.getFocusBlock({
248
248
  context
249
249
  });
250
250
  return !hrCharacters || !hrObject || !focusBlock ? !1 : {
@@ -288,11 +288,11 @@ function createMarkdownBehaviors(config) {
288
288
  var _a, _b, _c;
289
289
  if (event.text !== " ")
290
290
  return !1;
291
- const selectionCollapsed = selectors.selectionIsCollapsed({
291
+ const selectionCollapsed = selector_isSelectionCollapsed.isSelectionCollapsed({
292
292
  context
293
- }), focusTextBlock = selectors.getFocusTextBlock({
293
+ }), focusTextBlock = selector_isSelectionCollapsed.getFocusTextBlock({
294
294
  context
295
- }), focusSpan = selectors.getFocusSpan({
295
+ }), focusSpan = selector_isSelectionCollapsed.getFocusSpan({
296
296
  context
297
297
  });
298
298
  if (!selectionCollapsed || !focusTextBlock || !focusSpan)
@@ -354,11 +354,11 @@ function createMarkdownBehaviors(config) {
354
354
  context
355
355
  }) => {
356
356
  var _a, _b;
357
- const selectionCollapsed = selectors.selectionIsCollapsed({
357
+ const selectionCollapsed = selector_isSelectionCollapsed.isSelectionCollapsed({
358
358
  context
359
- }), focusTextBlock = selectors.getFocusTextBlock({
359
+ }), focusTextBlock = selector_isSelectionCollapsed.getFocusTextBlock({
360
360
  context
361
- }), focusSpan = selectors.getFocusSpan({
361
+ }), focusSpan = selector_isSelectionCollapsed.getFocusSpan({
362
362
  context
363
363
  });
364
364
  if (!selectionCollapsed || !focusTextBlock || !focusSpan)
@@ -386,11 +386,11 @@ function createMarkdownBehaviors(config) {
386
386
  var _a, _b, _c, _d, _e;
387
387
  if (event.text !== " ")
388
388
  return !1;
389
- const selectionCollapsed = selectors.selectionIsCollapsed({
389
+ const selectionCollapsed = selector_isSelectionCollapsed.isSelectionCollapsed({
390
390
  context
391
- }), focusTextBlock = selectors.getFocusTextBlock({
391
+ }), focusTextBlock = selector_isSelectionCollapsed.getFocusTextBlock({
392
392
  context
393
- }), focusSpan = selectors.getFocusSpan({
393
+ }), focusSpan = selector_isSelectionCollapsed.getFocusSpan({
394
394
  context
395
395
  });
396
396
  if (!selectionCollapsed || !focusTextBlock || !focusSpan)