@portabletext/editor 1.40.4 → 1.41.1

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.
@@ -4,7 +4,7 @@ import type {EditorSchema, EditorSelection} from '..'
4
4
  import type {PortableTextSlateEditor} from '../types/editor'
5
5
  import * as utils from '../utils'
6
6
  import {toPortableTextRange} from './ranges'
7
- import {getNodeBlock} from './slate-utils'
7
+ import {getFirstBlock, getLastBlock, getNodeBlock} from './slate-utils'
8
8
  import {fromSlateValue} from './values'
9
9
 
10
10
  export type EventPosition = {
@@ -128,6 +128,32 @@ function getEventPositionBlock({
128
128
  slateEditor: PortableTextSlateEditor
129
129
  event: DragEvent | MouseEvent
130
130
  }): EventPositionBlock | undefined {
131
+ const [firstBlock] = getFirstBlock({editor: slateEditor})
132
+
133
+ if (!firstBlock) {
134
+ return undefined
135
+ }
136
+
137
+ const firstBlockElement = DOMEditor.toDOMNode(slateEditor, firstBlock)
138
+ const firstBlockRect = firstBlockElement.getBoundingClientRect()
139
+
140
+ if (event.pageY < firstBlockRect.top) {
141
+ return 'start'
142
+ }
143
+
144
+ const [lastBlock] = getLastBlock({editor: slateEditor})
145
+
146
+ if (!lastBlock) {
147
+ return undefined
148
+ }
149
+
150
+ const lastBlockElement = DOMEditor.toDOMNode(slateEditor, lastBlock)
151
+ const lastBlockRef = lastBlockElement.getBoundingClientRect()
152
+
153
+ if (event.pageY > lastBlockRef.bottom) {
154
+ return 'end'
155
+ }
156
+
131
157
  const element = DOMEditor.toDOMNode(slateEditor, node)
132
158
  const elementRect = element.getBoundingClientRect()
133
159
  const top = elementRect.top
@@ -182,9 +208,11 @@ function getSlateRangeFromEvent(
182
208
  )
183
209
 
184
210
  if (position) {
185
- domRange = window.document.createRange()
186
- domRange.setStart(position.offsetNode, position.offset)
187
- domRange.setEnd(position.offsetNode, position.offset)
211
+ try {
212
+ domRange = window.document.createRange()
213
+ domRange.setStart(position.offsetNode, position.offset)
214
+ domRange.setEnd(position.offsetNode, position.offset)
215
+ } catch {}
188
216
  }
189
217
  } else if (window.document.caretRangeFromPoint !== undefined) {
190
218
  // Use WebKit-proprietary fallback method
@@ -41,20 +41,29 @@ export function getFocusChild({
41
41
  : [undefined, undefined]
42
42
  }
43
43
 
44
- export function getLastBlock({
44
+ export function getFirstBlock({
45
45
  editor,
46
46
  }: {
47
47
  editor: PortableTextSlateEditor
48
48
  }): [node: Node, path: Path] | [undefined, undefined] {
49
- const lastBlock = Array.from(
50
- Editor.nodes(editor, {
51
- match: (n) => !Editor.isEditor(n),
52
- at: [],
53
- reverse: true,
54
- }),
55
- ).at(0)
49
+ const firstPoint = Editor.start(editor, [])
50
+ const firstBlockPath = firstPoint.path.at(0)
56
51
 
57
- return lastBlock ?? [undefined, undefined]
52
+ return firstBlockPath !== undefined
53
+ ? (Editor.node(editor, [firstBlockPath]) ?? [undefined, undefined])
54
+ : [undefined, undefined]
55
+ }
56
+
57
+ export function getLastBlock({
58
+ editor,
59
+ }: {
60
+ editor: PortableTextSlateEditor
61
+ }): [node: Node, path: Path] | [undefined, undefined] {
62
+ const lastPoint = Editor.end(editor, [])
63
+ const lastBlockPath = lastPoint.path.at(0)
64
+ return lastBlockPath !== undefined
65
+ ? (Editor.node(editor, [lastBlockPath]) ?? [undefined, undefined])
66
+ : [undefined, undefined]
58
67
  }
59
68
 
60
69
  export function getNodeBlock({
@@ -8,6 +8,8 @@ export {blockOffsetsToSelection} from './util.block-offsets-to-selection'
8
8
  export {childSelectionPointToBlockOffset} from './util.child-selection-point-to-block-offset'
9
9
  export {getBlockEndPoint} from './util.get-block-end-point'
10
10
  export {getBlockStartPoint} from './util.get-block-start-point'
11
+ export {getSelectionEndPoint} from './util.get-selection-end-point'
12
+ export {getSelectionStartPoint} from './util.get-selection-start-point'
11
13
  export {getTextBlockText} from './util.get-text-block-text'
12
14
  export {isEmptyTextBlock} from './util.is-empty-text-block'
13
15
  export {isEqualSelectionPoints} from './util.is-equal-selection-points'
@@ -0,0 +1,20 @@
1
+ import type {EditorSelection, EditorSelectionPoint} from '..'
2
+
3
+ /**
4
+ * @public
5
+ */
6
+ export function getSelectionEndPoint<
7
+ TEditorSelection extends NonNullable<EditorSelection> | null,
8
+ TEditorSelectionPoint extends
9
+ EditorSelectionPoint | null = TEditorSelection extends NonNullable<EditorSelection>
10
+ ? EditorSelectionPoint
11
+ : null,
12
+ >(selection: TEditorSelection): TEditorSelectionPoint {
13
+ if (!selection) {
14
+ return null as TEditorSelectionPoint
15
+ }
16
+
17
+ return (
18
+ selection.backward ? selection.anchor : selection.focus
19
+ ) as TEditorSelectionPoint
20
+ }
@@ -0,0 +1,20 @@
1
+ import type {EditorSelection, EditorSelectionPoint} from '..'
2
+
3
+ /**
4
+ * @public
5
+ */
6
+ export function getSelectionStartPoint<
7
+ TEditorSelection extends NonNullable<EditorSelection> | null,
8
+ TEditorSelectionPoint extends
9
+ EditorSelectionPoint | null = TEditorSelection extends NonNullable<EditorSelection>
10
+ ? EditorSelectionPoint
11
+ : null,
12
+ >(selection: TEditorSelection): TEditorSelectionPoint {
13
+ if (!selection) {
14
+ return null as TEditorSelectionPoint
15
+ }
16
+
17
+ return (
18
+ selection.backward ? selection.focus : selection.anchor
19
+ ) as TEditorSelectionPoint
20
+ }