@portabletext/editor 1.33.2 → 1.33.4

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 (81) hide show
  1. package/lib/_chunks-cjs/behavior.core.cjs +11 -204
  2. package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
  3. package/lib/_chunks-cjs/behavior.markdown.cjs +7 -7
  4. package/lib/_chunks-cjs/behavior.markdown.cjs.map +1 -1
  5. package/lib/_chunks-cjs/plugin.event-listener.cjs +208 -33
  6. package/lib/_chunks-cjs/plugin.event-listener.cjs.map +1 -1
  7. package/lib/_chunks-cjs/selector.get-text-before.cjs +3 -3
  8. package/lib/_chunks-cjs/selector.get-text-before.cjs.map +1 -1
  9. package/lib/_chunks-cjs/selector.is-active-style.cjs +246 -0
  10. package/lib/_chunks-cjs/selector.is-active-style.cjs.map +1 -0
  11. package/lib/_chunks-cjs/selector.is-at-the-start-of-block.cjs +31 -200
  12. package/lib/_chunks-cjs/selector.is-at-the-start-of-block.cjs.map +1 -1
  13. package/lib/_chunks-cjs/util.block-offsets-to-selection.cjs +7 -5
  14. package/lib/_chunks-cjs/util.block-offsets-to-selection.cjs.map +1 -1
  15. package/lib/_chunks-cjs/util.reverse-selection.cjs +0 -116
  16. package/lib/_chunks-cjs/util.reverse-selection.cjs.map +1 -1
  17. package/lib/_chunks-cjs/util.slice-blocks.cjs +138 -1
  18. package/lib/_chunks-cjs/util.slice-blocks.cjs.map +1 -1
  19. package/lib/_chunks-es/behavior.core.js +9 -202
  20. package/lib/_chunks-es/behavior.core.js.map +1 -1
  21. package/lib/_chunks-es/behavior.markdown.js +1 -1
  22. package/lib/_chunks-es/plugin.event-listener.js +205 -31
  23. package/lib/_chunks-es/plugin.event-listener.js.map +1 -1
  24. package/lib/_chunks-es/selector.get-text-before.js +2 -1
  25. package/lib/_chunks-es/selector.get-text-before.js.map +1 -1
  26. package/lib/_chunks-es/selector.is-active-style.js +249 -0
  27. package/lib/_chunks-es/selector.is-active-style.js.map +1 -0
  28. package/lib/_chunks-es/selector.is-at-the-start-of-block.js +20 -189
  29. package/lib/_chunks-es/selector.is-at-the-start-of-block.js.map +1 -1
  30. package/lib/_chunks-es/util.block-offsets-to-selection.js +5 -3
  31. package/lib/_chunks-es/util.block-offsets-to-selection.js.map +1 -1
  32. package/lib/_chunks-es/util.reverse-selection.js +1 -117
  33. package/lib/_chunks-es/util.reverse-selection.js.map +1 -1
  34. package/lib/_chunks-es/util.slice-blocks.js +140 -3
  35. package/lib/_chunks-es/util.slice-blocks.js.map +1 -1
  36. package/lib/index.d.cts +1 -115
  37. package/lib/index.d.ts +1 -115
  38. package/lib/plugins/index.cjs +19 -15
  39. package/lib/plugins/index.cjs.map +1 -1
  40. package/lib/plugins/index.d.cts +1 -115
  41. package/lib/plugins/index.d.ts +1 -115
  42. package/lib/plugins/index.js +9 -5
  43. package/lib/plugins/index.js.map +1 -1
  44. package/lib/selectors/index.cjs +16 -21
  45. package/lib/selectors/index.cjs.map +1 -1
  46. package/lib/selectors/index.d.cts +2 -0
  47. package/lib/selectors/index.d.ts +2 -0
  48. package/lib/selectors/index.js +7 -11
  49. package/lib/selectors/index.js.map +1 -1
  50. package/lib/utils/index.cjs +13 -13
  51. package/lib/utils/index.cjs.map +1 -1
  52. package/lib/utils/index.d.cts +2 -0
  53. package/lib/utils/index.d.ts +2 -0
  54. package/lib/utils/index.js +3 -3
  55. package/package.json +2 -2
  56. package/src/behaviors/behavior.core.annotations.ts +0 -24
  57. package/src/behaviors/behavior.core.decorators.ts +0 -19
  58. package/src/behaviors/behavior.core.insert-break.ts +4 -4
  59. package/src/behaviors/behavior.core.lists.ts +0 -30
  60. package/src/behaviors/behavior.core.ts +2 -17
  61. package/src/behaviors/behavior.default.ts +198 -0
  62. package/src/behaviors/behavior.foundational.ts +12 -12
  63. package/src/behaviors/behavior.markdown-emphasis.ts +4 -0
  64. package/src/converters/converter.text-html.serialize.test.ts +1 -1
  65. package/src/editor/PortableTextEditor.tsx +1 -1
  66. package/src/editor/editor-machine.ts +8 -8
  67. package/src/plugins/plugin.event-listener.tsx +1 -1
  68. package/src/selectors/selector.get-caret-word-selection.ts +9 -0
  69. package/src/selectors/selector.get-selection-text.test.ts +383 -36
  70. package/src/selectors/selector.get-selection-text.ts +13 -73
  71. package/src/utils/util.block-offset.test.ts +312 -0
  72. package/src/utils/util.block-offset.ts +39 -7
  73. package/src/utils/util.block-offsets-to-selection.ts +2 -0
  74. package/src/utils/util.slice-blocks.ts +12 -1
  75. package/lib/_chunks-cjs/selector.get-trimmed-selection.cjs +0 -97
  76. package/lib/_chunks-cjs/selector.get-trimmed-selection.cjs.map +0 -1
  77. package/lib/_chunks-es/selector.get-trimmed-selection.js +0 -100
  78. package/lib/_chunks-es/selector.get-trimmed-selection.js.map +0 -1
  79. package/src/behaviors/behavior.core.deserialize.ts +0 -60
  80. package/src/behaviors/behavior.core.serialize.ts +0 -44
  81. package/src/behaviors/behavior.core.style.ts +0 -19
@@ -1,4 +1,5 @@
1
- import { getBlockStartPoint, reverseSelection, isKeyedSegment } from "./util.reverse-selection.js";
1
+ import { getBlockStartPoint, isKeyedSegment } from "./util.slice-blocks.js";
2
+ import { reverseSelection } from "./util.reverse-selection.js";
2
3
  import { getSelectionText } from "./selector.is-at-the-start-of-block.js";
3
4
  const getBlockTextBefore = ({
4
5
  context
@@ -1 +1 @@
1
- {"version":3,"file":"selector.get-text-before.js","sources":["../../src/selectors/selector.get-text-before.ts"],"sourcesContent":["import type {EditorSelector} from '../editor/editor-selector'\nimport {getBlockStartPoint} from '../utils/util.get-block-start-point'\nimport {isKeyedSegment} from '../utils/util.is-keyed-segment'\nimport {reverseSelection} from '../utils/util.reverse-selection'\nimport {getSelectionText} from './selector.get-selection-text'\n\n/**\n * @public\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 = getBlockStartPoint({\n node: block,\n path: [{_key: block._key}],\n })\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":["getBlockTextBefore","context","selection","point","backward","reverseSelection","anchor","key","isKeyedSegment","path","_key","undefined","block","value","find","startOfBlock","getBlockStartPoint","node","getSelectionText","focus"],"mappings":";;AASO,MAAMA,qBAA6CA,CAAC;AAAA,EAACC;AAAO,MAAM;AACvE,MAAI,CAACA,QAAQC;AACJ,WAAA;AAMT,QAAMC,SAHYF,QAAQC,UAAUE,WAChCC,iBAAiBJ,QAAQC,SAAS,IAClCD,QAAQC,WACYI,QAClBC,MAAMC,eAAeL,MAAMM,KAAK,CAAC,CAAC,IAAIN,MAAMM,KAAK,CAAC,EAAEC,OAAOC,QAE3DC,QAAQL,MACVN,QAAQY,MAAMC,KAAMF,CAAAA,WAAUA,OAAMF,SAASH,GAAG,IAChDI;AAEJ,MAAI,CAACC;AACI,WAAA;AAGT,QAAMG,eAAeC,mBAAmB;AAAA,IACtCC,MAAML;AAAAA,IACNH,MAAM,CAAC;AAAA,MAACC,MAAME,MAAMF;AAAAA,IAAK,CAAA;AAAA,EAAA,CAC1B;AAED,SAAOQ,iBAAiB;AAAA,IACtBjB,SAAS;AAAA,MACP,GAAGA;AAAAA,MACHY,OAAOZ,QAAQY;AAAAA,MACfX,WAAW;AAAA,QACTI,QAAQS;AAAAA,QACRI,OAAOhB;AAAAA,MAAAA;AAAAA,IACT;AAAA,EACF,CACD;AACH;"}
1
+ {"version":3,"file":"selector.get-text-before.js","sources":["../../src/selectors/selector.get-text-before.ts"],"sourcesContent":["import type {EditorSelector} from '../editor/editor-selector'\nimport {getBlockStartPoint} from '../utils/util.get-block-start-point'\nimport {isKeyedSegment} from '../utils/util.is-keyed-segment'\nimport {reverseSelection} from '../utils/util.reverse-selection'\nimport {getSelectionText} from './selector.get-selection-text'\n\n/**\n * @public\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 = getBlockStartPoint({\n node: block,\n path: [{_key: block._key}],\n })\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":["getBlockTextBefore","context","selection","point","backward","reverseSelection","anchor","key","isKeyedSegment","path","_key","undefined","block","value","find","startOfBlock","getBlockStartPoint","node","getSelectionText","focus"],"mappings":";;;AASO,MAAMA,qBAA6CA,CAAC;AAAA,EAACC;AAAO,MAAM;AACvE,MAAI,CAACA,QAAQC;AACJ,WAAA;AAMT,QAAMC,SAHYF,QAAQC,UAAUE,WAChCC,iBAAiBJ,QAAQC,SAAS,IAClCD,QAAQC,WACYI,QAClBC,MAAMC,eAAeL,MAAMM,KAAK,CAAC,CAAC,IAAIN,MAAMM,KAAK,CAAC,EAAEC,OAAOC,QAE3DC,QAAQL,MACVN,QAAQY,MAAMC,KAAMF,CAAAA,WAAUA,OAAMF,SAASH,GAAG,IAChDI;AAEJ,MAAI,CAACC;AACI,WAAA;AAGT,QAAMG,eAAeC,mBAAmB;AAAA,IACtCC,MAAML;AAAAA,IACNH,MAAM,CAAC;AAAA,MAACC,MAAME,MAAMF;AAAAA,IAAK,CAAA;AAAA,EAAA,CAC1B;AAED,SAAOQ,iBAAiB;AAAA,IACtBjB,SAAS;AAAA,MACP,GAAGA;AAAAA,MACHY,OAAOZ,QAAQY;AAAAA,MACfX,WAAW;AAAA,QACTI,QAAQS;AAAAA,QACRI,OAAOhB;AAAAA,MAAAA;AAAAA,IACT;AAAA,EACF,CACD;AACH;"}
@@ -0,0 +1,249 @@
1
+ import { isKeySegment, isPortableTextTextBlock, isPortableTextSpan } from "@sanity/types";
2
+ import { isEmptyTextBlock, isKeyedSegment } from "./util.slice-blocks.js";
3
+ import { getSelectedBlocks, createGuards, isSelectionCollapsed, getFocusTextBlock, getSelectionStartPoint, getSelectionEndPoint, getFocusSpan, isSelectionExpanded } from "./selector.is-at-the-start-of-block.js";
4
+ const getSelectedSpans = ({
5
+ context
6
+ }) => {
7
+ if (!context.selection)
8
+ return [];
9
+ const selectedSpans = [], startPoint = context.selection.backward ? context.selection.focus : context.selection.anchor, endPoint = context.selection.backward ? context.selection.anchor : context.selection.focus, startBlockKey = isKeySegment(startPoint.path[0]) ? startPoint.path[0]._key : void 0, endBlockKey = isKeySegment(endPoint.path[0]) ? endPoint.path[0]._key : void 0;
10
+ if (!startBlockKey || !endBlockKey)
11
+ return selectedSpans;
12
+ const startSpanKey = isKeySegment(startPoint.path[2]) ? startPoint.path[2]._key : void 0, endSpanKey = isKeySegment(endPoint.path[2]) ? endPoint.path[2]._key : void 0;
13
+ for (const block of context.value)
14
+ if (isPortableTextTextBlock(block)) {
15
+ if (block._key === startBlockKey) {
16
+ for (const child of block.children)
17
+ if (isPortableTextSpan(child)) {
18
+ if (startSpanKey && child._key === startSpanKey) {
19
+ if (startPoint.offset < child.text.length && selectedSpans.push({
20
+ node: child,
21
+ path: [{
22
+ _key: block._key
23
+ }, "children", {
24
+ _key: child._key
25
+ }]
26
+ }), startSpanKey === endSpanKey)
27
+ break;
28
+ continue;
29
+ }
30
+ if (endSpanKey && child._key === endSpanKey) {
31
+ endPoint.offset > 0 && selectedSpans.push({
32
+ node: child,
33
+ path: [{
34
+ _key: block._key
35
+ }, "children", {
36
+ _key: child._key
37
+ }]
38
+ });
39
+ break;
40
+ }
41
+ selectedSpans.length > 0 && selectedSpans.push({
42
+ node: child,
43
+ path: [{
44
+ _key: block._key
45
+ }, "children", {
46
+ _key: child._key
47
+ }]
48
+ });
49
+ }
50
+ if (startBlockKey === endBlockKey)
51
+ break;
52
+ continue;
53
+ }
54
+ if (block._key === endBlockKey) {
55
+ for (const child of block.children)
56
+ if (isPortableTextSpan(child)) {
57
+ if (endSpanKey && child._key === endSpanKey) {
58
+ endPoint.offset > 0 && selectedSpans.push({
59
+ node: child,
60
+ path: [{
61
+ _key: block._key
62
+ }, "children", {
63
+ _key: child._key
64
+ }]
65
+ });
66
+ break;
67
+ }
68
+ selectedSpans.push({
69
+ node: child,
70
+ path: [{
71
+ _key: block._key
72
+ }, "children", {
73
+ _key: child._key
74
+ }]
75
+ });
76
+ }
77
+ break;
78
+ }
79
+ if (selectedSpans.length > 0)
80
+ for (const child of block.children)
81
+ isPortableTextSpan(child) && selectedSpans.push({
82
+ node: child,
83
+ path: [{
84
+ _key: block._key
85
+ }, "children", {
86
+ _key: child._key
87
+ }]
88
+ });
89
+ }
90
+ return selectedSpans;
91
+ }, getActiveListItem = ({
92
+ context
93
+ }) => {
94
+ if (!context.selection)
95
+ return;
96
+ const guards = createGuards(context), selectedTextBlocks = getSelectedBlocks({
97
+ context
98
+ }).map((block) => block.node).filter(guards.isTextBlock), firstTextBlock = selectedTextBlocks.at(0);
99
+ if (!firstTextBlock)
100
+ return;
101
+ const firstListItem = firstTextBlock.listItem;
102
+ if (firstListItem && selectedTextBlocks.every((block) => block.listItem === firstListItem))
103
+ return firstListItem;
104
+ }, getActiveStyle = ({
105
+ context
106
+ }) => {
107
+ if (!context.selection)
108
+ return;
109
+ const guards = createGuards(context), selectedTextBlocks = getSelectedBlocks({
110
+ context
111
+ }).map((block) => block.node).filter(guards.isTextBlock), firstTextBlock = selectedTextBlocks.at(0);
112
+ if (!firstTextBlock)
113
+ return;
114
+ const firstStyle = firstTextBlock.style;
115
+ if (firstStyle && selectedTextBlocks.every((block) => block.style === firstStyle))
116
+ return firstStyle;
117
+ }, getTrimmedSelection = ({
118
+ context
119
+ }) => {
120
+ if (!context.selection)
121
+ return context.selection;
122
+ const startPoint = getSelectionStartPoint({
123
+ context
124
+ }), endPoint = getSelectionEndPoint({
125
+ context
126
+ });
127
+ if (!startPoint || !endPoint)
128
+ return context.selection;
129
+ const startBlockKey = isKeyedSegment(startPoint.path[0]) ? startPoint.path[0]._key : null, startChildKey = isKeyedSegment(startPoint.path[2]) ? startPoint.path[2]._key : null, endBlockKey = isKeyedSegment(endPoint.path[0]) ? endPoint.path[0]._key : null, endChildKey = isKeyedSegment(endPoint.path[2]) ? endPoint.path[2]._key : null;
130
+ if (!startBlockKey || !endBlockKey)
131
+ return context.selection;
132
+ let startBlockFound = !1, adjustedStartPoint, trimStartPoint = !1, adjustedEndPoint, trimEndPoint = !1, previousPotentialEndpoint;
133
+ for (const block of context.value)
134
+ if (!(block._key === startBlockKey && (startBlockFound = !0, isPortableTextTextBlock(block) && isEmptyTextBlock(block))) && startBlockFound && isPortableTextTextBlock(block)) {
135
+ if (block._key === endBlockKey && isEmptyTextBlock(block))
136
+ break;
137
+ for (const child of block.children) {
138
+ if (child._key === endChildKey && (!isPortableTextSpan(child) || endPoint.offset === 0)) {
139
+ adjustedEndPoint = previousPotentialEndpoint ? {
140
+ path: [{
141
+ _key: previousPotentialEndpoint.blockKey
142
+ }, "children", {
143
+ _key: previousPotentialEndpoint.span._key
144
+ }],
145
+ offset: previousPotentialEndpoint.span.text.length
146
+ } : void 0, trimEndPoint = !0;
147
+ break;
148
+ }
149
+ if (trimStartPoint) {
150
+ const lonelySpan = isPortableTextSpan(child) && block.children.length === 1;
151
+ (isPortableTextSpan(child) && child.text.length > 0 || lonelySpan) && (adjustedStartPoint = {
152
+ path: [{
153
+ _key: block._key
154
+ }, "children", {
155
+ _key: child._key
156
+ }],
157
+ offset: 0
158
+ }, previousPotentialEndpoint = {
159
+ blockKey: block._key,
160
+ span: child
161
+ }, trimStartPoint = !1);
162
+ continue;
163
+ }
164
+ if (child._key === startChildKey) {
165
+ if (!isPortableTextSpan(child)) {
166
+ trimStartPoint = !0;
167
+ continue;
168
+ }
169
+ if (startPoint.offset === child.text.length) {
170
+ trimStartPoint = !0, previousPotentialEndpoint = child.text.length > 0 ? {
171
+ blockKey: block._key,
172
+ span: child
173
+ } : previousPotentialEndpoint;
174
+ continue;
175
+ }
176
+ }
177
+ previousPotentialEndpoint = isPortableTextSpan(child) && child.text.length > 0 ? {
178
+ blockKey: block._key,
179
+ span: child
180
+ } : previousPotentialEndpoint;
181
+ }
182
+ if (block._key === endBlockKey)
183
+ break;
184
+ }
185
+ const trimmedSelection = context.selection.backward ? {
186
+ anchor: trimEndPoint && adjustedEndPoint ? adjustedEndPoint : endPoint,
187
+ focus: adjustedStartPoint ?? startPoint,
188
+ backward: !0
189
+ } : {
190
+ anchor: adjustedStartPoint ?? startPoint,
191
+ focus: trimEndPoint && adjustedEndPoint ? adjustedEndPoint : endPoint
192
+ };
193
+ if (isSelectionCollapsed({
194
+ context: {
195
+ ...context,
196
+ selection: trimmedSelection
197
+ }
198
+ })) {
199
+ const focusTextBlock = getFocusTextBlock({
200
+ context: {
201
+ ...context,
202
+ selection: trimmedSelection
203
+ }
204
+ });
205
+ if (focusTextBlock && !isEmptyTextBlock(focusTextBlock.node))
206
+ return null;
207
+ }
208
+ return trimmedSelection;
209
+ };
210
+ function isActiveAnnotation(annotation) {
211
+ return (snapshot) => {
212
+ if (!snapshot.context.selection)
213
+ return !1;
214
+ const selectedBlocks = getSelectedBlocks(snapshot), focusSpan = getFocusSpan(snapshot), selectedSpans = isSelectionExpanded(snapshot) ? getSelectedSpans(snapshot) : focusSpan ? [focusSpan] : [];
215
+ if (selectedSpans.length === 0 || selectedSpans.some((span) => !span.node.marks || span.node.marks?.length === 0))
216
+ return !1;
217
+ const selectionMarkDefs = selectedBlocks.flatMap((block) => isPortableTextTextBlock(block.node) ? block.node.markDefs ?? [] : []);
218
+ return selectedSpans.every((span) => (span.node.marks?.flatMap((mark) => {
219
+ const markDef = selectionMarkDefs.find((markDef2) => markDef2._key === mark);
220
+ return markDef ? [markDef._type] : [];
221
+ }) ?? []).includes(annotation));
222
+ };
223
+ }
224
+ function isActiveDecorator(decorator) {
225
+ return (snapshot) => {
226
+ if (isSelectionExpanded(snapshot)) {
227
+ const selectedSpans = getSelectedSpans(snapshot);
228
+ return selectedSpans.length > 0 && selectedSpans.every((span) => span.node.marks?.includes(decorator));
229
+ }
230
+ return snapshot.context.activeDecorators.includes(decorator);
231
+ };
232
+ }
233
+ function isActiveListItem(listItem) {
234
+ return (snapshot) => getActiveListItem(snapshot) === listItem;
235
+ }
236
+ function isActiveStyle(style) {
237
+ return (snapshot) => getActiveStyle(snapshot) === style;
238
+ }
239
+ export {
240
+ getActiveListItem,
241
+ getActiveStyle,
242
+ getSelectedSpans,
243
+ getTrimmedSelection,
244
+ isActiveAnnotation,
245
+ isActiveDecorator,
246
+ isActiveListItem,
247
+ isActiveStyle
248
+ };
249
+ //# sourceMappingURL=selector.is-active-style.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selector.is-active-style.js","sources":["../../src/selectors/selector.get-selected-spans.ts","../../src/selectors/selector.get-active-list-item.ts","../../src/selectors/selector.get-active-style.ts","../../src/selectors/selector.get-trimmed-selection.ts","../../src/selectors/selector.is-active-annotation.ts","../../src/selectors/selector.is-active-decorator.ts","../../src/selectors/selector.is-active-list-item.ts","../../src/selectors/selector.is-active-style.ts"],"sourcesContent":["import {\n isKeySegment,\n isPortableTextSpan,\n isPortableTextTextBlock,\n type KeyedSegment,\n type PortableTextSpan,\n} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\n\n/**\n * @public\n */\nexport const getSelectedSpans: EditorSelector<\n Array<{\n node: PortableTextSpan\n path: [KeyedSegment, 'children', KeyedSegment]\n }>\n> = ({context}) => {\n if (!context.selection) {\n return []\n }\n\n const selectedSpans: Array<{\n node: PortableTextSpan\n path: [KeyedSegment, 'children', KeyedSegment]\n }> = []\n\n const startPoint = context.selection.backward\n ? context.selection.focus\n : context.selection.anchor\n const endPoint = context.selection.backward\n ? context.selection.anchor\n : context.selection.focus\n\n const startBlockKey = isKeySegment(startPoint.path[0])\n ? startPoint.path[0]._key\n : undefined\n const endBlockKey = isKeySegment(endPoint.path[0])\n ? endPoint.path[0]._key\n : undefined\n\n if (!startBlockKey || !endBlockKey) {\n return selectedSpans\n }\n\n const startSpanKey = isKeySegment(startPoint.path[2])\n ? startPoint.path[2]._key\n : undefined\n const endSpanKey = isKeySegment(endPoint.path[2])\n ? endPoint.path[2]._key\n : undefined\n\n for (const block of context.value) {\n if (!isPortableTextTextBlock(block)) {\n continue\n }\n\n if (block._key === startBlockKey) {\n for (const child of block.children) {\n if (!isPortableTextSpan(child)) {\n continue\n }\n\n if (startSpanKey && child._key === startSpanKey) {\n if (startPoint.offset < child.text.length) {\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n }\n\n if (startSpanKey === endSpanKey) {\n break\n }\n\n continue\n }\n\n if (endSpanKey && child._key === endSpanKey) {\n if (endPoint.offset > 0) {\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n }\n break\n }\n\n if (selectedSpans.length > 0) {\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n }\n }\n\n if (startBlockKey === endBlockKey) {\n break\n }\n\n continue\n }\n\n if (block._key === endBlockKey) {\n for (const child of block.children) {\n if (!isPortableTextSpan(child)) {\n continue\n }\n\n if (endSpanKey && child._key === endSpanKey) {\n if (endPoint.offset > 0) {\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n }\n break\n }\n\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n }\n\n break\n }\n\n if (selectedSpans.length > 0) {\n for (const child of block.children) {\n if (!isPortableTextSpan(child)) {\n continue\n }\n\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n }\n }\n }\n\n return selectedSpans\n}\n","import type {PortableTextListBlock} from '@sanity/types'\nimport {createGuards} from '../behavior-actions/behavior.guards'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getSelectedBlocks} from './selectors'\n\n/**\n * @public\n */\nexport const getActiveListItem: EditorSelector<\n PortableTextListBlock['listItem'] | undefined\n> = ({context}) => {\n if (!context.selection) {\n return undefined\n }\n\n const guards = createGuards(context)\n const selectedBlocks = getSelectedBlocks({context}).map((block) => block.node)\n const selectedTextBlocks = selectedBlocks.filter(guards.isTextBlock)\n\n const firstTextBlock = selectedTextBlocks.at(0)\n\n if (!firstTextBlock) {\n return undefined\n }\n\n const firstListItem = firstTextBlock.listItem\n\n if (!firstListItem) {\n return undefined\n }\n\n if (selectedTextBlocks.every((block) => block.listItem === firstListItem)) {\n return firstListItem\n }\n\n return undefined\n}\n","import type {PortableTextTextBlock} from '@sanity/types'\nimport {createGuards} from '../behavior-actions/behavior.guards'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getSelectedBlocks} from './selectors'\n\n/**\n * @public\n */\nexport const getActiveStyle: EditorSelector<PortableTextTextBlock['style']> = ({\n context,\n}) => {\n if (!context.selection) {\n return undefined\n }\n\n const guards = createGuards(context)\n const selectedBlocks = getSelectedBlocks({context}).map((block) => block.node)\n const selectedTextBlocks = selectedBlocks.filter(guards.isTextBlock)\n\n const firstTextBlock = selectedTextBlocks.at(0)\n\n if (!firstTextBlock) {\n return undefined\n }\n\n const firstStyle = firstTextBlock.style\n\n if (!firstStyle) {\n return undefined\n }\n\n if (selectedTextBlocks.every((block) => block.style === firstStyle)) {\n return firstStyle\n }\n\n return undefined\n}\n","import {\n isPortableTextSpan,\n isPortableTextTextBlock,\n type PortableTextSpan,\n} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {EditorSelection, EditorSelectionPoint} from '../types/editor'\nimport {isEmptyTextBlock, isKeyedSegment} from '../utils'\nimport {getSelectionEndPoint} from './selector.get-selection-end-point'\nimport {getSelectionStartPoint} from './selector.get-selection-start-point'\nimport {isSelectionCollapsed} from './selector.is-selection-collapsed'\nimport {getFocusTextBlock} from './selectors'\n\n/**\n * @public\n */\nexport const getTrimmedSelection: EditorSelector<EditorSelection> = ({\n context,\n}) => {\n if (!context.selection) {\n return context.selection\n }\n\n const startPoint = getSelectionStartPoint({context})\n const endPoint = getSelectionEndPoint({context})\n\n if (!startPoint || !endPoint) {\n return context.selection\n }\n\n const startBlockKey = isKeyedSegment(startPoint.path[0])\n ? startPoint.path[0]._key\n : null\n const startChildKey = isKeyedSegment(startPoint.path[2])\n ? startPoint.path[2]._key\n : null\n const endBlockKey = isKeyedSegment(endPoint.path[0])\n ? endPoint.path[0]._key\n : null\n const endChildKey = isKeyedSegment(endPoint.path[2])\n ? endPoint.path[2]._key\n : null\n\n if (!startBlockKey || !endBlockKey) {\n return context.selection\n }\n\n let startBlockFound = false\n let adjustedStartPoint: EditorSelectionPoint | undefined\n let trimStartPoint = false\n let adjustedEndPoint: EditorSelectionPoint | undefined\n let trimEndPoint = false\n let previousPotentialEndpoint:\n | {blockKey: string; span: PortableTextSpan}\n | undefined\n\n for (const block of context.value) {\n if (block._key === startBlockKey) {\n startBlockFound = true\n\n if (isPortableTextTextBlock(block) && isEmptyTextBlock(block)) {\n continue\n }\n }\n\n if (!startBlockFound) {\n continue\n }\n\n if (!isPortableTextTextBlock(block)) {\n continue\n }\n\n if (block._key === endBlockKey && isEmptyTextBlock(block)) {\n break\n }\n\n for (const child of block.children) {\n if (child._key === endChildKey) {\n if (!isPortableTextSpan(child) || endPoint.offset === 0) {\n adjustedEndPoint = previousPotentialEndpoint\n ? {\n path: [\n {_key: previousPotentialEndpoint.blockKey},\n 'children',\n {_key: previousPotentialEndpoint.span._key},\n ],\n offset: previousPotentialEndpoint.span.text.length,\n }\n : undefined\n\n trimEndPoint = true\n break\n }\n }\n\n if (trimStartPoint) {\n const lonelySpan =\n isPortableTextSpan(child) && block.children.length === 1\n\n if (\n (isPortableTextSpan(child) && child.text.length > 0) ||\n lonelySpan\n ) {\n adjustedStartPoint = {\n path: [{_key: block._key}, 'children', {_key: child._key}],\n offset: 0,\n }\n previousPotentialEndpoint = {blockKey: block._key, span: child}\n trimStartPoint = false\n }\n\n continue\n }\n\n if (child._key === startChildKey) {\n if (!isPortableTextSpan(child)) {\n trimStartPoint = true\n continue\n }\n\n if (startPoint.offset === child.text.length) {\n trimStartPoint = true\n previousPotentialEndpoint =\n child.text.length > 0\n ? {blockKey: block._key, span: child}\n : previousPotentialEndpoint\n continue\n }\n }\n\n previousPotentialEndpoint =\n isPortableTextSpan(child) && child.text.length > 0\n ? {blockKey: block._key, span: child}\n : previousPotentialEndpoint\n }\n\n if (block._key === endBlockKey) {\n break\n }\n }\n\n const trimmedSelection = context.selection.backward\n ? {\n anchor: trimEndPoint && adjustedEndPoint ? adjustedEndPoint : endPoint,\n focus: adjustedStartPoint ?? startPoint,\n backward: true,\n }\n : {\n anchor: adjustedStartPoint ?? startPoint,\n focus: trimEndPoint && adjustedEndPoint ? adjustedEndPoint : endPoint,\n }\n\n if (\n isSelectionCollapsed({\n context: {\n ...context,\n selection: trimmedSelection,\n },\n })\n ) {\n const focusTextBlock = getFocusTextBlock({\n context: {\n ...context,\n selection: trimmedSelection,\n },\n })\n\n if (focusTextBlock && !isEmptyTextBlock(focusTextBlock.node)) {\n return null\n }\n }\n\n return trimmedSelection\n}\n","import {isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getSelectedSpans} from './selector.get-selected-spans'\nimport {isSelectionExpanded} from './selector.is-selection-expanded'\nimport {getFocusSpan, getSelectedBlocks} from './selectors'\n\n/**\n * @public\n */\nexport function isActiveAnnotation(\n annotation: string,\n): EditorSelector<boolean> {\n return (snapshot) => {\n if (!snapshot.context.selection) {\n return false\n }\n\n const selectedBlocks = getSelectedBlocks(snapshot)\n const focusSpan = getFocusSpan(snapshot)\n\n const selectedSpans = isSelectionExpanded(snapshot)\n ? getSelectedSpans(snapshot)\n : focusSpan\n ? [focusSpan]\n : []\n\n if (selectedSpans.length === 0) {\n return false\n }\n\n if (\n selectedSpans.some(\n (span) => !span.node.marks || span.node.marks?.length === 0,\n )\n ) {\n return false\n }\n\n const selectionMarkDefs = selectedBlocks.flatMap((block) =>\n isPortableTextTextBlock(block.node) ? (block.node.markDefs ?? []) : [],\n )\n\n return selectedSpans.every((span) => {\n const spanMarkDefs =\n span.node.marks?.flatMap((mark) => {\n const markDef = selectionMarkDefs.find(\n (markDef) => markDef._key === mark,\n )\n\n return markDef ? [markDef._type] : []\n }) ?? []\n\n return spanMarkDefs.includes(annotation)\n })\n }\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {getSelectedSpans} from './selector.get-selected-spans'\nimport {isSelectionExpanded} from './selector.is-selection-expanded'\n\n/**\n * @public\n */\nexport function isActiveDecorator(decorator: string): EditorSelector<boolean> {\n return (snapshot) => {\n if (isSelectionExpanded(snapshot)) {\n const selectedSpans = getSelectedSpans(snapshot)\n\n return (\n selectedSpans.length > 0 &&\n selectedSpans.every((span) => span.node.marks?.includes(decorator))\n )\n }\n\n return snapshot.context.activeDecorators.includes(decorator)\n }\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {getActiveListItem} from './selector.get-active-list-item'\n\n/**\n * @public\n */\nexport function isActiveListItem(listItem: string): EditorSelector<boolean> {\n return (snapshot) => {\n const activeListItem = getActiveListItem(snapshot)\n\n return activeListItem === listItem\n }\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {getActiveStyle} from './selector.get-active-style'\n\n/**\n * @public\n */\nexport function isActiveStyle(style: string): EditorSelector<boolean> {\n return (snapshot) => {\n const activeStyle = getActiveStyle(snapshot)\n\n return activeStyle === style\n }\n}\n"],"names":["getSelectedSpans","context","selection","selectedSpans","startPoint","backward","focus","anchor","endPoint","startBlockKey","isKeySegment","path","_key","undefined","endBlockKey","startSpanKey","endSpanKey","block","value","isPortableTextTextBlock","child","children","isPortableTextSpan","offset","text","length","push","node","getActiveListItem","guards","createGuards","selectedTextBlocks","getSelectedBlocks","map","filter","isTextBlock","firstTextBlock","at","firstListItem","listItem","every","getActiveStyle","firstStyle","style","getTrimmedSelection","getSelectionStartPoint","getSelectionEndPoint","isKeyedSegment","startChildKey","endChildKey","startBlockFound","adjustedStartPoint","trimStartPoint","adjustedEndPoint","trimEndPoint","previousPotentialEndpoint","isEmptyTextBlock","blockKey","span","lonelySpan","trimmedSelection","isSelectionCollapsed","focusTextBlock","getFocusTextBlock","isActiveAnnotation","annotation","snapshot","selectedBlocks","focusSpan","getFocusSpan","isSelectionExpanded","some","marks","selectionMarkDefs","flatMap","markDefs","mark","markDef","find","_type","includes","isActiveDecorator","decorator","activeDecorators","isActiveListItem","isActiveStyle"],"mappings":";;;AAYO,MAAMA,mBAKTA,CAAC;AAAA,EAACC;AAAO,MAAM;AACjB,MAAI,CAACA,QAAQC;AACX,WAAO,CAAE;AAGLC,QAAAA,gBAGD,IAECC,aAAaH,QAAQC,UAAUG,WACjCJ,QAAQC,UAAUI,QAClBL,QAAQC,UAAUK,QAChBC,WAAWP,QAAQC,UAAUG,WAC/BJ,QAAQC,UAAUK,SAClBN,QAAQC,UAAUI,OAEhBG,gBAAgBC,aAAaN,WAAWO,KAAK,CAAC,CAAC,IACjDP,WAAWO,KAAK,CAAC,EAAEC,OACnBC,QACEC,cAAcJ,aAAaF,SAASG,KAAK,CAAC,CAAC,IAC7CH,SAASG,KAAK,CAAC,EAAEC,OACjBC;AAEA,MAAA,CAACJ,iBAAiB,CAACK;AACdX,WAAAA;AAGHY,QAAAA,eAAeL,aAAaN,WAAWO,KAAK,CAAC,CAAC,IAChDP,WAAWO,KAAK,CAAC,EAAEC,OACnBC,QACEG,aAAaN,aAAaF,SAASG,KAAK,CAAC,CAAC,IAC5CH,SAASG,KAAK,CAAC,EAAEC,OACjBC;AAEJ,aAAWI,SAAShB,QAAQiB;AACrBC,QAAAA,wBAAwBF,KAAK,GAIlC;AAAIA,UAAAA,MAAML,SAASH,eAAe;AAChC,mBAAWW,SAASH,MAAMI;AACnBC,cAAAA,mBAAmBF,KAAK,GAI7B;AAAIL,gBAAAA,gBAAgBK,MAAMR,SAASG,cAAc;AAQ/C,kBAPIX,WAAWmB,SAASH,MAAMI,KAAKC,UACjCtB,cAAcuB,KAAK;AAAA,gBACjBC,MAAMP;AAAAA,gBACNT,MAAM,CAAC;AAAA,kBAACC,MAAMK,MAAML;AAAAA,mBAAO,YAAY;AAAA,kBAACA,MAAMQ,MAAMR;AAAAA,gBAAK,CAAA;AAAA,cAAA,CAC1D,GAGCG,iBAAiBC;AACnB;AAGF;AAAA,YAAA;AAGEA,gBAAAA,cAAcI,MAAMR,SAASI,YAAY;AACvCR,uBAASe,SAAS,KACpBpB,cAAcuB,KAAK;AAAA,gBACjBC,MAAMP;AAAAA,gBACNT,MAAM,CAAC;AAAA,kBAACC,MAAMK,MAAML;AAAAA,mBAAO,YAAY;AAAA,kBAACA,MAAMQ,MAAMR;AAAAA,gBAAK,CAAA;AAAA,cAAA,CAC1D;AAEH;AAAA,YAAA;AAGET,0BAAcsB,SAAS,KACzBtB,cAAcuB,KAAK;AAAA,cACjBC,MAAMP;AAAAA,cACNT,MAAM,CAAC;AAAA,gBAACC,MAAMK,MAAML;AAAAA,iBAAO,YAAY;AAAA,gBAACA,MAAMQ,MAAMR;AAAAA,cAAK,CAAA;AAAA,YAAA,CAC1D;AAAA,UAAA;AAIL,YAAIH,kBAAkBK;AACpB;AAGF;AAAA,MAAA;AAGEG,UAAAA,MAAML,SAASE,aAAa;AAC9B,mBAAWM,SAASH,MAAMI;AACnBC,cAAAA,mBAAmBF,KAAK,GAI7B;AAAIJ,gBAAAA,cAAcI,MAAMR,SAASI,YAAY;AACvCR,uBAASe,SAAS,KACpBpB,cAAcuB,KAAK;AAAA,gBACjBC,MAAMP;AAAAA,gBACNT,MAAM,CAAC;AAAA,kBAACC,MAAMK,MAAML;AAAAA,mBAAO,YAAY;AAAA,kBAACA,MAAMQ,MAAMR;AAAAA,gBAAK,CAAA;AAAA,cAAA,CAC1D;AAEH;AAAA,YAAA;AAGFT,0BAAcuB,KAAK;AAAA,cACjBC,MAAMP;AAAAA,cACNT,MAAM,CAAC;AAAA,gBAACC,MAAMK,MAAML;AAAAA,iBAAO,YAAY;AAAA,gBAACA,MAAMQ,MAAMR;AAAAA,cAAK,CAAA;AAAA,YAAA,CAC1D;AAAA,UAAA;AAGH;AAAA,MAAA;AAGF,UAAIT,cAAcsB,SAAS;AACzB,mBAAWL,SAASH,MAAMI;AACnBC,6BAAmBF,KAAK,KAI7BjB,cAAcuB,KAAK;AAAA,YACjBC,MAAMP;AAAAA,YACNT,MAAM,CAAC;AAAA,cAACC,MAAMK,MAAML;AAAAA,eAAO,YAAY;AAAA,cAACA,MAAMQ,MAAMR;AAAAA,YAAK,CAAA;AAAA,UAAA,CAC1D;AAAA,IAAA;AAKAT,SAAAA;AACT,GCvIayB,oBAETA,CAAC;AAAA,EAAC3B;AAAO,MAAM;AACjB,MAAI,CAACA,QAAQC;AACX;AAGF,QAAM2B,SAASC,aAAa7B,OAAO,GAE7B8B,qBADiBC,kBAAkB;AAAA,IAAC/B;AAAAA,EAAQ,CAAA,EAAEgC,IAAKhB,CAAAA,UAAUA,MAAMU,IAAI,EACnCO,OAAOL,OAAOM,WAAW,GAE7DC,iBAAiBL,mBAAmBM,GAAG,CAAC;AAE9C,MAAI,CAACD;AACH;AAGF,QAAME,gBAAgBF,eAAeG;AAErC,MAAKD,iBAIDP,mBAAmBS,MAAOvB,CAAUA,UAAAA,MAAMsB,aAAaD,aAAa;AAC/DA,WAAAA;AAIX,GC5BaG,iBAAiEA,CAAC;AAAA,EAC7ExC;AACF,MAAM;AACJ,MAAI,CAACA,QAAQC;AACX;AAGF,QAAM2B,SAASC,aAAa7B,OAAO,GAE7B8B,qBADiBC,kBAAkB;AAAA,IAAC/B;AAAAA,EAAQ,CAAA,EAAEgC,IAAKhB,CAAAA,UAAUA,MAAMU,IAAI,EACnCO,OAAOL,OAAOM,WAAW,GAE7DC,iBAAiBL,mBAAmBM,GAAG,CAAC;AAE9C,MAAI,CAACD;AACH;AAGF,QAAMM,aAAaN,eAAeO;AAElC,MAAKD,cAIDX,mBAAmBS,MAAOvB,CAAUA,UAAAA,MAAM0B,UAAUD,UAAU;AACzDA,WAAAA;AAIX,GCpBaE,sBAAuDA,CAAC;AAAA,EACnE3C;AACF,MAAM;AACJ,MAAI,CAACA,QAAQC;AACX,WAAOD,QAAQC;AAGjB,QAAME,aAAayC,uBAAuB;AAAA,IAAC5C;AAAAA,EAAAA,CAAQ,GAC7CO,WAAWsC,qBAAqB;AAAA,IAAC7C;AAAAA,EAAAA,CAAQ;AAE3C,MAAA,CAACG,cAAc,CAACI;AAClB,WAAOP,QAAQC;AAGXO,QAAAA,gBAAgBsC,eAAe3C,WAAWO,KAAK,CAAC,CAAC,IACnDP,WAAWO,KAAK,CAAC,EAAEC,OACnB,MACEoC,gBAAgBD,eAAe3C,WAAWO,KAAK,CAAC,CAAC,IACnDP,WAAWO,KAAK,CAAC,EAAEC,OACnB,MACEE,cAAciC,eAAevC,SAASG,KAAK,CAAC,CAAC,IAC/CH,SAASG,KAAK,CAAC,EAAEC,OACjB,MACEqC,cAAcF,eAAevC,SAASG,KAAK,CAAC,CAAC,IAC/CH,SAASG,KAAK,CAAC,EAAEC,OACjB;AAEA,MAAA,CAACH,iBAAiB,CAACK;AACrB,WAAOb,QAAQC;AAGjB,MAAIgD,kBAAkB,IAClBC,oBACAC,iBAAiB,IACjBC,kBACAC,eAAe,IACfC;AAIJ,aAAWtC,SAAShB,QAAQiB;AAC1B,QAAID,EAAML,MAAAA,SAASH,kBACjByC,kBAAkB,IAEd/B,wBAAwBF,KAAK,KAAKuC,iBAAiBvC,KAAK,OAKzDiC,mBAIA/B,wBAAwBF,KAAK,GAIlC;AAAA,UAAIA,MAAML,SAASE,eAAe0C,iBAAiBvC,KAAK;AACtD;AAGSG,iBAAAA,SAASH,MAAMI,UAAU;AAC9BD,YAAAA,MAAMR,SAASqC,gBACb,CAAC3B,mBAAmBF,KAAK,KAAKZ,SAASe,WAAW,IAAG;AACvD8B,6BAAmBE,4BACf;AAAA,YACE5C,MAAM,CACJ;AAAA,cAACC,MAAM2C,0BAA0BE;AAAAA,eACjC,YACA;AAAA,cAAC7C,MAAM2C,0BAA0BG,KAAK9C;AAAAA,YAAAA,CAAK;AAAA,YAE7CW,QAAQgC,0BAA0BG,KAAKlC,KAAKC;AAAAA,UAAAA,IAE9CZ,QAEJyC,eAAe;AACf;AAAA,QAAA;AAIJ,YAAIF,gBAAgB;AAClB,gBAAMO,aACJrC,mBAAmBF,KAAK,KAAKH,MAAMI,SAASI,WAAW;AAGtDH,WAAAA,mBAAmBF,KAAK,KAAKA,MAAMI,KAAKC,SAAS,KAClDkC,gBAEAR,qBAAqB;AAAA,YACnBxC,MAAM,CAAC;AAAA,cAACC,MAAMK,MAAML;AAAAA,eAAO,YAAY;AAAA,cAACA,MAAMQ,MAAMR;AAAAA,YAAAA,CAAK;AAAA,YACzDW,QAAQ;AAAA,aAEVgC,4BAA4B;AAAA,YAACE,UAAUxC,MAAML;AAAAA,YAAM8C,MAAMtC;AAAAA,UAAAA,GACzDgC,iBAAiB;AAGnB;AAAA,QAAA;AAGEhC,YAAAA,MAAMR,SAASoC,eAAe;AAC5B,cAAA,CAAC1B,mBAAmBF,KAAK,GAAG;AACb,6BAAA;AACjB;AAAA,UAAA;AAGF,cAAIhB,WAAWmB,WAAWH,MAAMI,KAAKC,QAAQ;AAC3C2B,6BAAiB,IACjBG,4BACEnC,MAAMI,KAAKC,SAAS,IAChB;AAAA,cAACgC,UAAUxC,MAAML;AAAAA,cAAM8C,MAAMtC;AAAAA,YAAAA,IAC7BmC;AACN;AAAA,UAAA;AAAA,QACF;AAGFA,oCACEjC,mBAAmBF,KAAK,KAAKA,MAAMI,KAAKC,SAAS,IAC7C;AAAA,UAACgC,UAAUxC,MAAML;AAAAA,UAAM8C,MAAMtC;AAAAA,QAAAA,IAC7BmC;AAAAA,MAAAA;AAGR,UAAItC,MAAML,SAASE;AACjB;AAAA,IAAA;AAIE8C,QAAAA,mBAAmB3D,QAAQC,UAAUG,WACvC;AAAA,IACEE,QAAQ+C,gBAAgBD,mBAAmBA,mBAAmB7C;AAAAA,IAC9DF,OAAO6C,sBAAsB/C;AAAAA,IAC7BC,UAAU;AAAA,EAAA,IAEZ;AAAA,IACEE,QAAQ4C,sBAAsB/C;AAAAA,IAC9BE,OAAOgD,gBAAgBD,mBAAmBA,mBAAmB7C;AAAAA,EAC/D;AAEJ,MACEqD,qBAAqB;AAAA,IACnB5D,SAAS;AAAA,MACP,GAAGA;AAAAA,MACHC,WAAW0D;AAAAA,IAAAA;AAAAA,EACb,CACD,GACD;AACA,UAAME,iBAAiBC,kBAAkB;AAAA,MACvC9D,SAAS;AAAA,QACP,GAAGA;AAAAA,QACHC,WAAW0D;AAAAA,MAAAA;AAAAA,IACb,CACD;AAED,QAAIE,kBAAkB,CAACN,iBAAiBM,eAAenC,IAAI;AAClD,aAAA;AAAA,EAAA;AAIJiC,SAAAA;AACT;ACrKO,SAASI,mBACdC,YACyB;AACzB,SAAQC,CAAa,aAAA;AACf,QAAA,CAACA,SAASjE,QAAQC;AACb,aAAA;AAGT,UAAMiE,iBAAiBnC,kBAAkBkC,QAAQ,GAC3CE,YAAYC,aAAaH,QAAQ,GAEjC/D,gBAAgBmE,oBAAoBJ,QAAQ,IAC9ClE,iBAAiBkE,QAAQ,IACzBE,YACE,CAACA,SAAS,IACV,CAAE;AAMR,QAJIjE,cAAcsB,WAAW,KAK3BtB,cAAcoE,KACXb,CAAS,SAAA,CAACA,KAAK/B,KAAK6C,SAASd,KAAK/B,KAAK6C,OAAO/C,WAAW,CAC5D;AAEO,aAAA;AAGT,UAAMgD,oBAAoBN,eAAeO,QAASzD,CAAAA,UAChDE,wBAAwBF,MAAMU,IAAI,IAAKV,MAAMU,KAAKgD,YAAY,CAAA,IAAM,CAAA,CACtE;AAEA,WAAOxE,cAAcqC,MAAOkB,CAAAA,UAExBA,KAAK/B,KAAK6C,OAAOE,QAASE,CAAS,SAAA;AACjC,YAAMC,UAAUJ,kBAAkBK,KAC/BD,CAAAA,aAAYA,SAAQjE,SAASgE,IAChC;AAEA,aAAOC,UAAU,CAACA,QAAQE,KAAK,IAAI,CAAE;AAAA,IACtC,CAAA,KAAK,CAEYC,GAAAA,SAASf,UAAU,CACxC;AAAA,EACH;AACF;AChDO,SAASgB,kBAAkBC,WAA4C;AAC5E,SAAQhB,CAAa,aAAA;AACfI,QAAAA,oBAAoBJ,QAAQ,GAAG;AAC3B/D,YAAAA,gBAAgBH,iBAAiBkE,QAAQ;AAG7C/D,aAAAA,cAAcsB,SAAS,KACvBtB,cAAcqC,MAAOkB,CAASA,SAAAA,KAAK/B,KAAK6C,OAAOQ,SAASE,SAAS,CAAC;AAAA,IAAA;AAItE,WAAOhB,SAASjE,QAAQkF,iBAAiBH,SAASE,SAAS;AAAA,EAC7D;AACF;ACdO,SAASE,iBAAiB7C,UAA2C;AAClE2B,SAAAA,CAAAA,aACiBtC,kBAAkBsC,QAAQ,MAEvB3B;AAE9B;ACNO,SAAS8C,cAAc1C,OAAwC;AAC5DuB,SAAAA,CAAAA,aACczB,eAAeyB,QAAQ,MAEpBvB;AAE3B;"}
@@ -1,4 +1,4 @@
1
- import { isSpan, isKeyedSegment, reverseSelection, spanSelectionPointToBlockOffset, getBlockStartPoint, getBlockEndPoint, blockOffsetToSpanSelectionPoint, isEqualSelectionPoints } from "./util.reverse-selection.js";
1
+ import { isSpan, sliceBlocks, spanSelectionPointToBlockOffset, getBlockStartPoint, getBlockEndPoint, blockOffsetToSpanSelectionPoint, isEqualSelectionPoints } from "./util.slice-blocks.js";
2
2
  import { isPortableTextListBlock, isPortableTextTextBlock, isKeySegment, isPortableTextSpan } from "@sanity/types";
3
3
  function createGuards({
4
4
  schema
@@ -14,94 +14,7 @@ function createGuards({
14
14
  isTextBlock
15
15
  };
16
16
  }
17
- const getSelectedSpans = ({
18
- context
19
- }) => {
20
- if (!context.selection)
21
- return [];
22
- const selectedSpans = [], startPoint = context.selection.backward ? context.selection.focus : context.selection.anchor, endPoint = context.selection.backward ? context.selection.anchor : context.selection.focus, startBlockKey = isKeySegment(startPoint.path[0]) ? startPoint.path[0]._key : void 0, endBlockKey = isKeySegment(endPoint.path[0]) ? endPoint.path[0]._key : void 0;
23
- if (!startBlockKey || !endBlockKey)
24
- return selectedSpans;
25
- const startSpanKey = isKeySegment(startPoint.path[2]) ? startPoint.path[2]._key : void 0, endSpanKey = isKeySegment(endPoint.path[2]) ? endPoint.path[2]._key : void 0;
26
- for (const block of context.value)
27
- if (isPortableTextTextBlock(block)) {
28
- if (block._key === startBlockKey) {
29
- for (const child of block.children)
30
- if (isPortableTextSpan(child)) {
31
- if (startSpanKey && child._key === startSpanKey) {
32
- if (startPoint.offset < child.text.length && selectedSpans.push({
33
- node: child,
34
- path: [{
35
- _key: block._key
36
- }, "children", {
37
- _key: child._key
38
- }]
39
- }), startSpanKey === endSpanKey)
40
- break;
41
- continue;
42
- }
43
- if (endSpanKey && child._key === endSpanKey) {
44
- endPoint.offset > 0 && selectedSpans.push({
45
- node: child,
46
- path: [{
47
- _key: block._key
48
- }, "children", {
49
- _key: child._key
50
- }]
51
- });
52
- break;
53
- }
54
- selectedSpans.length > 0 && selectedSpans.push({
55
- node: child,
56
- path: [{
57
- _key: block._key
58
- }, "children", {
59
- _key: child._key
60
- }]
61
- });
62
- }
63
- if (startBlockKey === endBlockKey)
64
- break;
65
- continue;
66
- }
67
- if (block._key === endBlockKey) {
68
- for (const child of block.children)
69
- if (isPortableTextSpan(child)) {
70
- if (endSpanKey && child._key === endSpanKey) {
71
- endPoint.offset > 0 && selectedSpans.push({
72
- node: child,
73
- path: [{
74
- _key: block._key
75
- }, "children", {
76
- _key: child._key
77
- }]
78
- });
79
- break;
80
- }
81
- selectedSpans.push({
82
- node: child,
83
- path: [{
84
- _key: block._key
85
- }, "children", {
86
- _key: child._key
87
- }]
88
- });
89
- }
90
- break;
91
- }
92
- if (selectedSpans.length > 0)
93
- for (const child of block.children)
94
- isPortableTextSpan(child) && selectedSpans.push({
95
- node: child,
96
- path: [{
97
- _key: block._key
98
- }, "children", {
99
- _key: child._key
100
- }]
101
- });
102
- }
103
- return selectedSpans;
104
- }, getFocusBlock = ({
17
+ const getFocusBlock = ({
105
18
  context
106
19
  }) => {
107
20
  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;
@@ -297,32 +210,6 @@ const getSelectedSpans = ({
297
210
  }
298
211
  if (foundSelectionEndBlock && nextBlock)
299
212
  return nextBlock;
300
- }, getActiveListItem = ({
301
- context
302
- }) => {
303
- if (!context.selection)
304
- return;
305
- const guards = createGuards(context), selectedTextBlocks = getSelectedBlocks({
306
- context
307
- }).map((block) => block.node).filter(guards.isTextBlock), firstTextBlock = selectedTextBlocks.at(0);
308
- if (!firstTextBlock)
309
- return;
310
- const firstListItem = firstTextBlock.listItem;
311
- if (firstListItem && selectedTextBlocks.every((block) => block.listItem === firstListItem))
312
- return firstListItem;
313
- }, getActiveStyle = ({
314
- context
315
- }) => {
316
- if (!context.selection)
317
- return;
318
- const guards = createGuards(context), selectedTextBlocks = getSelectedBlocks({
319
- context
320
- }).map((block) => block.node).filter(guards.isTextBlock), firstTextBlock = selectedTextBlocks.at(0);
321
- if (!firstTextBlock)
322
- return;
323
- const firstStyle = firstTextBlock.style;
324
- if (firstStyle && selectedTextBlocks.every((block) => block.style === firstStyle))
325
- return firstStyle;
326
213
  }, getSelectionEndPoint = ({
327
214
  context
328
215
  }) => {
@@ -382,42 +269,16 @@ const getSelectedSpans = ({
382
269
  });
383
270
  }
384
271
  return inlineObject;
385
- }, getSelectionText = ({
272
+ }, getSelectedSlice = ({
386
273
  context
387
- }) => {
388
- let text = "";
389
- const {
390
- value,
391
- selection
392
- } = context;
393
- if (!value || !selection)
394
- return text;
395
- const forwardSelection = selection.backward ? reverseSelection(selection) : selection;
396
- if (!forwardSelection)
397
- return text;
398
- for (const block of value)
399
- if (!(isKeyedSegment(forwardSelection.anchor.path[0]) && block._key !== forwardSelection.anchor.path[0]._key) && isPortableTextTextBlock(block)) {
400
- for (const child of block.children)
401
- if (isPortableTextSpan(child)) {
402
- if (isKeyedSegment(forwardSelection.anchor.path[2]) && child._key === forwardSelection.anchor.path[2]._key && isKeyedSegment(forwardSelection.focus.path[2]) && child._key === forwardSelection.focus.path[2]._key) {
403
- text = text + child.text.slice(forwardSelection.anchor.offset, forwardSelection.focus.offset);
404
- break;
405
- }
406
- if (isKeyedSegment(forwardSelection.anchor.path[2]) && child._key === forwardSelection.anchor.path[2]._key) {
407
- text = text + child.text.slice(forwardSelection.anchor.offset);
408
- continue;
409
- }
410
- if (isKeyedSegment(forwardSelection.focus.path[2]) && child._key === forwardSelection.focus.path[2]._key) {
411
- text = text + child.text.slice(0, forwardSelection.focus.offset);
412
- break;
413
- }
414
- text.length > 0 && (text = text + child.text);
415
- }
416
- if (isKeyedSegment(forwardSelection.focus.path[0]) && block._key === forwardSelection.focus.path[0]._key)
417
- break;
418
- }
419
- return text;
420
- }, isSelectionCollapsed = ({
274
+ }) => sliceBlocks({
275
+ blocks: context.value,
276
+ selection: context.selection
277
+ }), getSelectionText = ({
278
+ context
279
+ }) => getSelectedSlice({
280
+ context
281
+ }).reduce((text, block) => isPortableTextTextBlock(block) ? text + block.children.reduce((text2, child) => isPortableTextSpan(child) ? text2 + child.text : text2, "") : text, ""), isSelectionCollapsed = ({
421
282
  context
422
283
  }) => context.selection ? JSON.stringify(context.selection.anchor.path) === JSON.stringify(context.selection.focus.path) && context.selection?.anchor.offset === context.selection?.focus.offset : !1, isSelectionExpanded = ({
423
284
  context
@@ -466,7 +327,10 @@ const getSelectedSpans = ({
466
327
  } : blockEndPoint
467
328
  }
468
329
  }
469
- }).split(/\s+/).at(0), caretWordStartOffset = textDirectlyBefore ? {
330
+ }).split(/\s+/).at(0);
331
+ if ((textDirectlyBefore === void 0 || textDirectlyBefore === "") && (textDirectlyAfter === void 0 || textDirectlyAfter === ""))
332
+ return null;
333
+ const caretWordStartOffset = textDirectlyBefore ? {
470
334
  ...selectionStartOffset,
471
335
  offset: selectionStartOffset.offset - textDirectlyBefore.length
472
336
  } : selectionStartOffset, caretWordEndOffset = textDirectlyAfter ? {
@@ -474,10 +338,12 @@ const getSelectedSpans = ({
474
338
  offset: selectionStartOffset.offset + textDirectlyAfter.length
475
339
  } : selectionStartOffset, caretWordStartSelectionPoint = blockOffsetToSpanSelectionPoint({
476
340
  value: context.value,
477
- blockOffset: caretWordStartOffset
341
+ blockOffset: caretWordStartOffset,
342
+ direction: "backward"
478
343
  }), caretWordEndSelectionPoint = blockOffsetToSpanSelectionPoint({
479
344
  value: context.value,
480
- blockOffset: caretWordEndOffset
345
+ blockOffset: caretWordEndOffset,
346
+ direction: "forward"
481
347
  });
482
348
  if (!caretWordStartSelectionPoint || !caretWordEndSelectionPoint)
483
349
  return null;
@@ -492,35 +358,6 @@ const getSelectedSpans = ({
492
358
  }
493
359
  }) ? caretWordSelection : null;
494
360
  };
495
- function isActiveAnnotation(annotation) {
496
- return (snapshot) => {
497
- if (!snapshot.context.selection)
498
- return !1;
499
- const selectedBlocks = getSelectedBlocks(snapshot), focusSpan = getFocusSpan(snapshot), selectedSpans = isSelectionExpanded(snapshot) ? getSelectedSpans(snapshot) : focusSpan ? [focusSpan] : [];
500
- if (selectedSpans.length === 0 || selectedSpans.some((span) => !span.node.marks || span.node.marks?.length === 0))
501
- return !1;
502
- const selectionMarkDefs = selectedBlocks.flatMap((block) => isPortableTextTextBlock(block.node) ? block.node.markDefs ?? [] : []);
503
- return selectedSpans.every((span) => (span.node.marks?.flatMap((mark) => {
504
- const markDef = selectionMarkDefs.find((markDef2) => markDef2._key === mark);
505
- return markDef ? [markDef._type] : [];
506
- }) ?? []).includes(annotation));
507
- };
508
- }
509
- function isActiveDecorator(decorator) {
510
- return (snapshot) => {
511
- if (isSelectionExpanded(snapshot)) {
512
- const selectedSpans = getSelectedSpans(snapshot);
513
- return selectedSpans.length > 0 && selectedSpans.every((span) => span.node.marks?.includes(decorator));
514
- }
515
- return snapshot.context.activeDecorators.includes(decorator);
516
- };
517
- }
518
- function isActiveListItem(listItem) {
519
- return (snapshot) => getActiveListItem(snapshot) === listItem;
520
- }
521
- function isActiveStyle(style) {
522
- return (snapshot) => getActiveStyle(snapshot) === style;
523
- }
524
361
  function isAtTheEndOfBlock(block) {
525
362
  return ({
526
363
  context
@@ -547,8 +384,6 @@ function isAtTheStartOfBlock(block) {
547
384
  }
548
385
  export {
549
386
  createGuards,
550
- getActiveListItem,
551
- getActiveStyle,
552
387
  getCaretWordSelection,
553
388
  getFirstBlock,
554
389
  getFocusBlock,
@@ -563,16 +398,12 @@ export {
563
398
  getPreviousBlock,
564
399
  getPreviousInlineObject,
565
400
  getSelectedBlocks,
566
- getSelectedSpans,
401
+ getSelectedSlice,
567
402
  getSelectionEndBlock,
568
403
  getSelectionEndPoint,
569
404
  getSelectionStartBlock,
570
405
  getSelectionStartPoint,
571
406
  getSelectionText,
572
- isActiveAnnotation,
573
- isActiveDecorator,
574
- isActiveListItem,
575
- isActiveStyle,
576
407
  isAtTheEndOfBlock,
577
408
  isAtTheStartOfBlock,
578
409
  isSelectionCollapsed,