@portabletext/editor 1.16.3 → 1.17.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.
- package/README.md +134 -118
- package/lib/_chunks-cjs/behavior.core.cjs +5 -12
- package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
- package/lib/_chunks-cjs/selector.get-text-before.cjs +3 -10
- package/lib/_chunks-cjs/selector.get-text-before.cjs.map +1 -1
- package/lib/_chunks-cjs/selector.is-selection-collapsed.cjs +1 -4
- package/lib/_chunks-cjs/selector.is-selection-collapsed.cjs.map +1 -1
- package/lib/_chunks-es/behavior.core.js +5 -12
- package/lib/_chunks-es/behavior.core.js.map +1 -1
- package/lib/_chunks-es/selector.get-text-before.js +3 -10
- package/lib/_chunks-es/selector.get-text-before.js.map +1 -1
- package/lib/_chunks-es/selector.is-selection-collapsed.js +1 -4
- package/lib/_chunks-es/selector.is-selection-collapsed.js.map +1 -1
- package/lib/behaviors/index.cjs +319 -37
- package/lib/behaviors/index.cjs.map +1 -1
- package/lib/behaviors/index.d.cts +46 -0
- package/lib/behaviors/index.d.ts +46 -0
- package/lib/behaviors/index.js +321 -38
- package/lib/behaviors/index.js.map +1 -1
- package/lib/index.cjs +532 -881
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +2 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +532 -881
- package/lib/index.js.map +1 -1
- package/lib/selectors/index.cjs +7 -19
- package/lib/selectors/index.cjs.map +1 -1
- package/lib/selectors/index.js +7 -19
- package/lib/selectors/index.js.map +1 -1
- package/package.json +3 -3
- package/src/behaviors/behavior.emoji-picker.ts +410 -0
- package/src/behaviors/index.ts +4 -0
- package/src/editor/create-editor.ts +2 -0
package/README.md
CHANGED
|
@@ -9,20 +9,8 @@
|
|
|
9
9
|
|
|
10
10
|
> The official editor for editing [Portable Text](https://github.com/portabletext/portabletext) – the JSON based rich text specification for modern content editing platforms.
|
|
11
11
|
|
|
12
|
-
> [!NOTE]
|
|
13
|
-
> We are currently working hard on the general release of this component. Better docs and refined APIs are coming.
|
|
14
|
-
|
|
15
|
-
## End-User Experience
|
|
16
|
-
|
|
17
|
-
In order to provide a robust and consistent end-user experience, the editor is backed by an elaborate E2E test suite generated from a [human-readable Gherkin spec](/packages/editor/gherkin-spec/).
|
|
18
|
-
|
|
19
12
|
## Build Your Own Portable Text Editor
|
|
20
13
|
|
|
21
|
-
> [!WARNING]
|
|
22
|
-
> The `@portabletext/editor` is currently on the path to deprecate legacy APIs and introduce new ones. The end goals are to make the editor easier to use outside of `Sanity` (and without `@sanity/*` libraries) as well as providing a brand new API to configure the behavior of the editor.
|
|
23
|
-
>
|
|
24
|
-
> This means that the `defineSchema` and `EditorProvider` APIs showcased here are still experimental APIs tagged with `@alpha` and cannot be considered stable yet. At the same time, the examples below showcase usages of legacy static methods on the `PortableTextEditor` (for example, `PortableTextEditor.isMarkActive(...)` and `PortableTextEditor.toggleMark(...)`) that will soon be discouraged and deprecrated.
|
|
25
|
-
|
|
26
14
|
Check [/examples/basic/src/App.tsx](/examples/basic/src/App.tsx) for a basic example of how to set up the edior. Most of the source code from this example app can also be found in the instructions below.
|
|
27
15
|
|
|
28
16
|
### Define the Schema
|
|
@@ -45,7 +33,7 @@ const schemaDefinition = defineSchema({
|
|
|
45
33
|
{name: 'h1'},
|
|
46
34
|
{name: 'h2'},
|
|
47
35
|
{name: 'h3'},
|
|
48
|
-
{name: '
|
|
36
|
+
{name: 'blockquote'},
|
|
49
37
|
],
|
|
50
38
|
// Lists apply to entire text blocks as well
|
|
51
39
|
lists: [{name: 'bullet'}, {name: 'number'}],
|
|
@@ -219,153 +207,177 @@ function isStockTicker(
|
|
|
219
207
|
|
|
220
208
|
### Render the Toolbar
|
|
221
209
|
|
|
222
|
-
Your toolbar needs to be rendered within `EditorProvider` because it requires a reference to the `
|
|
210
|
+
Your toolbar needs to be rendered within `EditorProvider` because it requires a reference to the `editor` that it produces. To toggle marks and styles and to insert objects, you'll have to use the `.send` method on this `editor` instance.
|
|
223
211
|
|
|
224
212
|
```tsx
|
|
225
213
|
function Toolbar() {
|
|
226
214
|
// Obtain the editor instance
|
|
227
|
-
const
|
|
228
|
-
// Rerender the toolbar whenever the selection changes
|
|
229
|
-
usePortableTextEditorSelection()
|
|
215
|
+
const editor = useEditor()
|
|
230
216
|
|
|
231
|
-
const decoratorButtons = schemaDefinition.decorators.map((decorator) =>
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}}
|
|
243
|
-
onClick={() => {
|
|
244
|
-
// Toggle the decorator by name
|
|
245
|
-
PortableTextEditor.toggleMark(editorInstance, decorator.name)
|
|
246
|
-
// Pressing this button steals focus so let's focus the editor again
|
|
247
|
-
PortableTextEditor.focus(editorInstance)
|
|
248
|
-
}}
|
|
249
|
-
>
|
|
250
|
-
{decorator.name}
|
|
251
|
-
</button>
|
|
252
|
-
)
|
|
253
|
-
})
|
|
217
|
+
const decoratorButtons = schemaDefinition.decorators.map((decorator) => (
|
|
218
|
+
<DecoratorButton key={decorator.name} decorator={decorator.name} />
|
|
219
|
+
))
|
|
220
|
+
|
|
221
|
+
const annotationButtons = schemaDefinition.annotations.map((annotation) => (
|
|
222
|
+
<AnnotationButton key={annotation.name} annotation={annotation} />
|
|
223
|
+
))
|
|
224
|
+
|
|
225
|
+
const styleButtons = schemaDefinition.styles.map((style) => (
|
|
226
|
+
<StyleButton key={style.name} style={style.name} />
|
|
227
|
+
))
|
|
254
228
|
|
|
255
|
-
const
|
|
229
|
+
const listButtons = schemaDefinition.lists.map((list) => (
|
|
230
|
+
<ListButton key={list.name} list={list.name} />
|
|
231
|
+
))
|
|
232
|
+
|
|
233
|
+
const imageButton = (
|
|
256
234
|
<button
|
|
257
|
-
style={{
|
|
258
|
-
textDecoration: PortableTextEditor.isAnnotationActive(
|
|
259
|
-
editorInstance,
|
|
260
|
-
schemaDefinition.annotations[0].name,
|
|
261
|
-
)
|
|
262
|
-
? 'underline'
|
|
263
|
-
: 'unset',
|
|
264
|
-
}}
|
|
265
235
|
onClick={() => {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
)
|
|
276
|
-
} else {
|
|
277
|
-
PortableTextEditor.addAnnotation(
|
|
278
|
-
editorInstance,
|
|
279
|
-
schemaDefinition.annotations[0],
|
|
280
|
-
{href: 'https://example.com'},
|
|
281
|
-
)
|
|
282
|
-
}
|
|
283
|
-
PortableTextEditor.focus(editorInstance)
|
|
236
|
+
editor.send({
|
|
237
|
+
type: 'insert.block object',
|
|
238
|
+
blockObject: {
|
|
239
|
+
name: 'image',
|
|
240
|
+
value: {src: 'https://example.com/image.jpg'},
|
|
241
|
+
},
|
|
242
|
+
placement: 'auto',
|
|
243
|
+
})
|
|
244
|
+
editor.send({type: 'focus'})
|
|
284
245
|
}}
|
|
285
246
|
>
|
|
286
|
-
|
|
247
|
+
{schemaDefinition.blockObjects[0].name}
|
|
287
248
|
</button>
|
|
288
249
|
)
|
|
289
250
|
|
|
290
|
-
const
|
|
251
|
+
const stockTickerButton = (
|
|
291
252
|
<button
|
|
292
|
-
key={style.name}
|
|
293
|
-
style={{
|
|
294
|
-
textDecoration: PortableTextEditor.hasBlockStyle(
|
|
295
|
-
editorInstance,
|
|
296
|
-
style.name,
|
|
297
|
-
)
|
|
298
|
-
? 'underline'
|
|
299
|
-
: 'unset',
|
|
300
|
-
}}
|
|
301
253
|
onClick={() => {
|
|
302
|
-
|
|
303
|
-
|
|
254
|
+
editor.send({
|
|
255
|
+
type: 'insert.inline object',
|
|
256
|
+
inlineObject: {
|
|
257
|
+
name: 'stock-ticker',
|
|
258
|
+
value: {symbol: 'AAPL'},
|
|
259
|
+
},
|
|
260
|
+
})
|
|
261
|
+
editor.send({type: 'focus'})
|
|
304
262
|
}}
|
|
305
263
|
>
|
|
306
|
-
{
|
|
264
|
+
{schemaDefinition.inlineObjects[0].name}
|
|
307
265
|
</button>
|
|
308
|
-
)
|
|
266
|
+
)
|
|
309
267
|
|
|
310
|
-
|
|
268
|
+
return (
|
|
269
|
+
<>
|
|
270
|
+
<div>{decoratorButtons}</div>
|
|
271
|
+
<div>{annotationButtons}</div>
|
|
272
|
+
<div>{styleButtons}</div>
|
|
273
|
+
<div>{listButtons}</div>
|
|
274
|
+
<div>{imageButton}</div>
|
|
275
|
+
<div>{stockTickerButton}</div>
|
|
276
|
+
</>
|
|
277
|
+
)
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function DecoratorButton(props: {decorator: string}) {
|
|
281
|
+
// Obtain the editor instance
|
|
282
|
+
const editor = useEditor()
|
|
283
|
+
// Check if the decorator is active using a selector
|
|
284
|
+
const active = useEditorSelector(
|
|
285
|
+
editor,
|
|
286
|
+
selectors.isActiveDecorator(props.decorator),
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
return (
|
|
311
290
|
<button
|
|
312
|
-
key={list.name}
|
|
313
291
|
style={{
|
|
314
|
-
textDecoration:
|
|
315
|
-
editorInstance,
|
|
316
|
-
list.name,
|
|
317
|
-
)
|
|
318
|
-
? 'underline'
|
|
319
|
-
: 'unset',
|
|
292
|
+
textDecoration: active ? 'underline' : 'unset',
|
|
320
293
|
}}
|
|
321
294
|
onClick={() => {
|
|
322
|
-
|
|
323
|
-
|
|
295
|
+
// Toggle the decorator
|
|
296
|
+
editor.send({
|
|
297
|
+
type: 'decorator.toggle',
|
|
298
|
+
decorator: props.decorator,
|
|
299
|
+
})
|
|
300
|
+
// Pressing this button steals focus so let's focus the editor again
|
|
301
|
+
editor.send({type: 'focus'})
|
|
324
302
|
}}
|
|
325
303
|
>
|
|
326
|
-
{
|
|
304
|
+
{props.decorator}
|
|
327
305
|
</button>
|
|
328
|
-
)
|
|
306
|
+
)
|
|
307
|
+
}
|
|
329
308
|
|
|
330
|
-
|
|
309
|
+
function AnnotationButton(props: {annotation: {name: string}}) {
|
|
310
|
+
const editor = useEditor()
|
|
311
|
+
const active = useEditorSelector(
|
|
312
|
+
editor,
|
|
313
|
+
selectors.isActiveAnnotation(props.annotation.name),
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
return (
|
|
331
317
|
<button
|
|
318
|
+
style={{
|
|
319
|
+
textDecoration: active ? 'underline' : 'unset',
|
|
320
|
+
}}
|
|
332
321
|
onClick={() => {
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
322
|
+
editor.send({
|
|
323
|
+
type: 'annotation.toggle',
|
|
324
|
+
annotation: {
|
|
325
|
+
name: props.annotation.name,
|
|
326
|
+
value:
|
|
327
|
+
props.annotation.name === 'link'
|
|
328
|
+
? {href: 'https://example.com'}
|
|
329
|
+
: {},
|
|
330
|
+
},
|
|
331
|
+
})
|
|
332
|
+
editor.send({type: 'focus'})
|
|
339
333
|
}}
|
|
340
334
|
>
|
|
341
|
-
{
|
|
335
|
+
{props.annotation.name}
|
|
342
336
|
</button>
|
|
343
337
|
)
|
|
338
|
+
}
|
|
344
339
|
|
|
345
|
-
|
|
340
|
+
function StyleButton(props: {style: string}) {
|
|
341
|
+
const editor = useEditor()
|
|
342
|
+
const active = useEditorSelector(editor, selectors.isActiveStyle(props.style))
|
|
343
|
+
|
|
344
|
+
return (
|
|
346
345
|
<button
|
|
346
|
+
style={{
|
|
347
|
+
textDecoration: active ? 'underline' : 'unset',
|
|
348
|
+
}}
|
|
347
349
|
onClick={() => {
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
schemaDefinition.inlineObjects[0],
|
|
351
|
-
{symbol: 'AAPL'},
|
|
352
|
-
)
|
|
353
|
-
PortableTextEditor.focus(editorInstance)
|
|
350
|
+
editor.send({type: 'style.toggle', style: props.style})
|
|
351
|
+
editor.send({type: 'focus'})
|
|
354
352
|
}}
|
|
355
353
|
>
|
|
356
|
-
{
|
|
354
|
+
{props.style}
|
|
357
355
|
</button>
|
|
358
356
|
)
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
function ListButton(props: {list: string}) {
|
|
360
|
+
const editor = useEditor()
|
|
361
|
+
const active = useEditorSelector(
|
|
362
|
+
editor,
|
|
363
|
+
selectors.isActiveListItem(props.list),
|
|
364
|
+
)
|
|
359
365
|
|
|
360
366
|
return (
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
367
|
+
<button
|
|
368
|
+
style={{
|
|
369
|
+
textDecoration: active ? 'underline' : 'unset',
|
|
370
|
+
}}
|
|
371
|
+
onClick={() => {
|
|
372
|
+
editor.send({
|
|
373
|
+
type: 'list item.toggle',
|
|
374
|
+
listItem: props.list,
|
|
375
|
+
})
|
|
376
|
+
editor.send({type: 'focus'})
|
|
377
|
+
}}
|
|
378
|
+
>
|
|
379
|
+
{props.list}
|
|
380
|
+
</button>
|
|
369
381
|
)
|
|
370
382
|
}
|
|
371
383
|
```
|
|
@@ -379,6 +391,10 @@ The Behavior API is a new way of interfacing with the Portable Text Editor. It a
|
|
|
379
391
|
3. Deriving editor **state** using **pure functions**.
|
|
380
392
|
4. Subscribe to **emitted** editor **events** using `editor.on(…)`.
|
|
381
393
|
|
|
394
|
+
## End-User Experience
|
|
395
|
+
|
|
396
|
+
In order to provide a robust and consistent end-user experience, the editor is backed by an elaborate E2E test suite generated from a [human-readable Gherkin spec](/packages/editor/gherkin-spec/).
|
|
397
|
+
|
|
382
398
|
## Development
|
|
383
399
|
|
|
384
400
|
### Develop Together with Sanity Studio
|
|
@@ -59,10 +59,7 @@ function isEmptyTextBlock(block) {
|
|
|
59
59
|
return onlyText && blockText === "";
|
|
60
60
|
}
|
|
61
61
|
function getTextBlockText(block) {
|
|
62
|
-
return block.children.map((child) =>
|
|
63
|
-
var _a;
|
|
64
|
-
return (_a = child.text) != null ? _a : "";
|
|
65
|
-
}).join("");
|
|
62
|
+
return block.children.map((child) => child.text ?? "").join("");
|
|
66
63
|
}
|
|
67
64
|
const IS_MAC = typeof window < "u" && /Mac|iPod|iPhone|iPad/.test(window.navigator.userAgent), modifiers = {
|
|
68
65
|
alt: "altKey",
|
|
@@ -169,14 +166,12 @@ function compareHotkey(parsedHotkey, event) {
|
|
|
169
166
|
return (parsedHotkey.altKey == null || parsedHotkey.altKey === event.altKey) && (parsedHotkey.ctrlKey == null || parsedHotkey.ctrlKey === event.ctrlKey) && (parsedHotkey.metaKey == null || parsedHotkey.metaKey === event.metaKey) && (parsedHotkey.shiftKey == null || parsedHotkey.shiftKey === event.shiftKey) ? parsedHotkey.keyCode !== void 0 && event.keyCode !== void 0 ? parsedHotkey.keyCode === 91 && event.keyCode === 93 ? !0 : parsedHotkey.keyCode === event.keyCode : parsedHotkey.keyCode === event.keyCode || parsedHotkey.key === event.key.toLowerCase() : !1;
|
|
170
167
|
}
|
|
171
168
|
function toKeyCode(name) {
|
|
172
|
-
var _a;
|
|
173
169
|
const keyName = toKeyName(name);
|
|
174
|
-
return
|
|
170
|
+
return keyCodes[keyName] ?? keyName.toUpperCase().charCodeAt(0);
|
|
175
171
|
}
|
|
176
172
|
function toKeyName(name) {
|
|
177
|
-
var _a;
|
|
178
173
|
const keyName = name.toLowerCase();
|
|
179
|
-
return
|
|
174
|
+
return aliases[keyName] ?? keyName;
|
|
180
175
|
}
|
|
181
176
|
function defineBehavior(behavior) {
|
|
182
177
|
return behavior;
|
|
@@ -351,7 +346,6 @@ const arrowDownOnLonelyBlockObject = {
|
|
|
351
346
|
guard: ({
|
|
352
347
|
context
|
|
353
348
|
}) => {
|
|
354
|
-
var _a;
|
|
355
349
|
const selectionCollapsed = selector_isSelectionCollapsed.isSelectionCollapsed({
|
|
356
350
|
context
|
|
357
351
|
}), focusTextBlock = selector_isSelectionCollapsed.getFocusTextBlock({
|
|
@@ -359,7 +353,7 @@ const arrowDownOnLonelyBlockObject = {
|
|
|
359
353
|
}), focusSpan = selector_isSelectionCollapsed.getFocusSpan({
|
|
360
354
|
context
|
|
361
355
|
});
|
|
362
|
-
return !selectionCollapsed || !focusTextBlock || !focusSpan ? !1 : focusTextBlock.node.children[0]._key === focusSpan.node._key &&
|
|
356
|
+
return !selectionCollapsed || !focusTextBlock || !focusSpan ? !1 : focusTextBlock.node.children[0]._key === focusSpan.node._key && context.selection?.focus.offset === 0 && focusTextBlock.node.level === 1 ? {
|
|
363
357
|
focusTextBlock
|
|
364
358
|
} : !1;
|
|
365
359
|
},
|
|
@@ -375,7 +369,6 @@ const arrowDownOnLonelyBlockObject = {
|
|
|
375
369
|
guard: ({
|
|
376
370
|
context
|
|
377
371
|
}) => {
|
|
378
|
-
var _a;
|
|
379
372
|
const selectionCollapsed = selector_isSelectionCollapsed.isSelectionCollapsed({
|
|
380
373
|
context
|
|
381
374
|
}), focusTextBlock = selector_isSelectionCollapsed.getFocusTextBlock({
|
|
@@ -383,7 +376,7 @@ const arrowDownOnLonelyBlockObject = {
|
|
|
383
376
|
}), focusSpan = selector_isSelectionCollapsed.getFocusSpan({
|
|
384
377
|
context
|
|
385
378
|
});
|
|
386
|
-
return !selectionCollapsed || !focusTextBlock || !focusSpan ? !1 : focusTextBlock.node.children[0]._key === focusSpan.node._key &&
|
|
379
|
+
return !selectionCollapsed || !focusTextBlock || !focusSpan ? !1 : focusTextBlock.node.children[0]._key === focusSpan.node._key && context.selection?.focus.offset === 0 && focusTextBlock.node.level !== void 0 && focusTextBlock.node.level > 1 ? {
|
|
387
380
|
focusTextBlock,
|
|
388
381
|
level: focusTextBlock.node.level - 1
|
|
389
382
|
} : !1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"behavior.core.cjs","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
|
+
{"version":3,"file":"behavior.core.cjs","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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"}
|
|
@@ -63,14 +63,6 @@ function getStartPoint({
|
|
|
63
63
|
offset: 0
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
|
-
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) => {
|
|
67
|
-
for (var prop in b || (b = {}))
|
|
68
|
-
__hasOwnProp.call(b, prop) && __defNormalProp(a, prop, b[prop]);
|
|
69
|
-
if (__getOwnPropSymbols)
|
|
70
|
-
for (var prop of __getOwnPropSymbols(b))
|
|
71
|
-
__propIsEnum.call(b, prop) && __defNormalProp(a, prop, b[prop]);
|
|
72
|
-
return a;
|
|
73
|
-
}, __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
74
66
|
const getBlockTextBefore = ({
|
|
75
67
|
context
|
|
76
68
|
}) => {
|
|
@@ -86,13 +78,14 @@ const getBlockTextBefore = ({
|
|
|
86
78
|
}]
|
|
87
79
|
});
|
|
88
80
|
return getSelectionText({
|
|
89
|
-
context:
|
|
81
|
+
context: {
|
|
82
|
+
...context,
|
|
90
83
|
value: context.value,
|
|
91
84
|
selection: {
|
|
92
85
|
anchor: startOfBlock,
|
|
93
86
|
focus: point
|
|
94
87
|
}
|
|
95
|
-
}
|
|
88
|
+
}
|
|
96
89
|
});
|
|
97
90
|
};
|
|
98
91
|
exports.getBlockTextBefore = getBlockTextBefore;
|