edytor 0.0.11 → 0.1.0-next.16
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 +77 -197
- package/dist/block/block.svelte.d.ts +156 -69
- package/dist/block/block.svelte.js +324 -355
- package/dist/block/block.utils.d.ts +191 -24
- package/dist/block/block.utils.js +327 -460
- package/dist/block/contentRange.d.ts +4 -0
- package/dist/block/contentRange.js +20 -0
- package/dist/block/inlineBlock.svelte.d.ts +26 -19
- package/dist/block/inlineBlock.svelte.js +91 -39
- package/dist/clipboard/clipboard.d.ts +4 -0
- package/dist/clipboard/clipboard.js +4 -0
- package/dist/clipboard/createClipboardFragment.d.ts +3 -0
- package/dist/clipboard/createClipboardFragment.js +103 -0
- package/dist/clipboard/fragmentData.d.ts +6 -0
- package/dist/clipboard/fragmentData.js +74 -0
- package/dist/clipboard/htmlFlow.d.ts +22 -0
- package/dist/clipboard/htmlFlow.js +167 -0
- package/dist/clipboard/insertClipboardFragment.d.ts +18 -0
- package/dist/clipboard/insertClipboardFragment.js +48 -0
- package/dist/clipboard/serializeClipboardFragment.d.ts +7 -0
- package/dist/clipboard/serializeClipboardFragment.js +53 -0
- package/dist/clipboard/textBlocks.d.ts +23 -0
- package/dist/clipboard/textBlocks.js +103 -0
- package/dist/clipboard/types.d.ts +20 -0
- package/dist/clipboard/types.js +2 -0
- package/dist/cloudflare/DocumentRoom.d.ts +586 -0
- package/dist/cloudflare/DocumentRoom.js +1706 -0
- package/dist/cloudflare/index.d.ts +8 -0
- package/dist/cloudflare/index.js +8 -0
- package/dist/cloudflare/routeDocumentSocket.d.ts +33 -0
- package/dist/cloudflare/routeDocumentSocket.js +51 -0
- package/dist/collaboration/RemoteSelections.svelte +94 -0
- package/dist/collaboration/RemoteSelections.svelte.d.ts +7 -0
- package/dist/collaboration/awarenessSelection.d.ts +127 -0
- package/dist/collaboration/awarenessSelection.js +199 -0
- package/dist/collaboration/documentSync.d.ts +20 -0
- package/dist/collaboration/documentSync.js +13 -0
- package/dist/collaboration/index.d.ts +3 -0
- package/dist/collaboration/index.js +3 -0
- package/dist/collaboration/providers.d.ts +13 -0
- package/dist/collaboration/providers.js +21 -0
- package/dist/collaboration/remoteSelection.d.ts +21 -0
- package/dist/collaboration/remoteSelection.js +159 -0
- package/dist/components/Block.svelte +223 -15
- package/dist/components/Block.svelte.d.ts +4 -2
- package/dist/components/Content.svelte +128 -32
- package/dist/components/Content.svelte.d.ts +6 -2
- package/dist/components/Edytor.svelte +308 -110
- package/dist/components/Edytor.svelte.d.ts +64 -20
- package/dist/components/InlineBlock.svelte +38 -7
- package/dist/components/InlineBlock.svelte.d.ts +5 -2
- package/dist/components/Mark.svelte +29 -13
- package/dist/components/Mark.svelte.d.ts +4 -4
- package/dist/components/Suggestion.svelte +48 -0
- package/dist/components/Suggestion.svelte.d.ts +7 -0
- package/dist/components/SuggestionRanges.svelte +58 -0
- package/dist/components/SuggestionRanges.svelte.d.ts +7 -0
- package/dist/components/Text.svelte +107 -14
- package/dist/components/Text.svelte.d.ts +8 -1
- package/dist/constants.d.ts +0 -2
- package/dist/constants.js +0 -2
- package/dist/crdt/admission.d.ts +141 -0
- package/dist/crdt/admission.js +147 -0
- package/dist/crdt/anchors.d.ts +47 -0
- package/dist/crdt/anchors.js +42 -0
- package/dist/crdt/attribution/attribution.d.ts +169 -0
- package/dist/crdt/attribution/attribution.js +136 -0
- package/dist/crdt/attribution/block.d.ts +200 -0
- package/dist/crdt/attribution/block.js +327 -0
- package/dist/crdt/attribution/index.d.ts +9 -0
- package/dist/crdt/attribution/index.js +9 -0
- package/dist/crdt/data.d.ts +81 -0
- package/dist/crdt/data.js +383 -0
- package/dist/crdt/document.d.ts +590 -0
- package/dist/crdt/document.js +1160 -0
- package/dist/crdt/edytor-doc.d.ts +752 -0
- package/dist/crdt/edytor-doc.js +2382 -0
- package/dist/crdt/engine-api.d.ts +153 -0
- package/dist/crdt/engine.d.ts +37 -0
- package/dist/crdt/engine.js +50 -0
- package/dist/crdt/flow.d.ts +104 -0
- package/dist/crdt/flow.js +229 -0
- package/dist/crdt/index.d.ts +630 -0
- package/dist/crdt/index.js +168 -0
- package/dist/crdt/migration/legacy-schema.d.ts +61 -0
- package/dist/crdt/migration/legacy-schema.js +149 -0
- package/dist/crdt/migration/migrate.d.ts +67 -0
- package/dist/crdt/migration/migrate.js +219 -0
- package/dist/crdt/nodes.d.ts +120 -0
- package/dist/crdt/nodes.js +56 -0
- package/dist/crdt/placement/model.d.ts +383 -0
- package/dist/crdt/placement/model.js +811 -0
- package/dist/crdt/placement/rank.d.ts +57 -0
- package/dist/crdt/placement/rank.js +209 -0
- package/dist/crdt/protocols/auth.d.ts +28 -0
- package/dist/crdt/protocols/auth.js +43 -0
- package/dist/crdt/protocols/awareness.d.ts +87 -0
- package/dist/crdt/protocols/awareness.js +271 -0
- package/dist/crdt/protocols/envelope.d.ts +75 -0
- package/dist/crdt/protocols/envelope.js +89 -0
- package/dist/crdt/protocols/observable.d.ts +19 -0
- package/dist/crdt/protocols/observable.js +26 -0
- package/dist/crdt/protocols/sync.d.ts +82 -0
- package/dist/crdt/protocols/sync.js +288 -0
- package/dist/crdt/providers/container.d.ts +23 -0
- package/dist/crdt/providers/container.js +64 -0
- package/dist/crdt/providers/index.d.ts +282 -0
- package/dist/crdt/providers/index.js +118 -0
- package/dist/crdt/providers/indexeddb.d.ts +196 -0
- package/dist/crdt/providers/indexeddb.js +332 -0
- package/dist/crdt/providers/room.d.ts +193 -0
- package/dist/crdt/providers/room.js +444 -0
- package/dist/crdt/providers/websocket.d.ts +223 -0
- package/dist/crdt/providers/websocket.js +601 -0
- package/dist/crdt/rand.d.ts +22 -0
- package/dist/crdt/rand.js +22 -0
- package/dist/crdt/rangeDelete.d.ts +85 -0
- package/dist/crdt/rangeDelete.js +126 -0
- package/dist/crdt/schema.d.ts +96 -0
- package/dist/crdt/schema.js +79 -0
- package/dist/crdt/semantics.d.ts +81 -0
- package/dist/crdt/semantics.js +57 -0
- package/dist/crdt/structs.d.ts +106 -0
- package/dist/crdt/structs.js +119 -0
- package/dist/crdt/text/deletes.d.ts +23 -0
- package/dist/crdt/text/deletes.js +608 -0
- package/dist/crdt/text/model.d.ts +280 -0
- package/dist/crdt/text/model.js +554 -0
- package/dist/crdt/text/runs.d.ts +212 -0
- package/dist/crdt/text/runs.js +1142 -0
- package/dist/crdt/vendor/yjs/API-NOTES.md +59 -0
- package/dist/crdt/vendor/yjs/LICENSE +23 -0
- package/dist/crdt/vendor/yjs/UPSTREAM.md +653 -0
- package/dist/crdt/vendor/yjs/dts/global.d.ts +52 -0
- package/dist/crdt/vendor/yjs/dts/index.d.ts +25 -0
- package/dist/crdt/vendor/yjs/dts/structs/AbstractStruct.d.ts +38 -0
- package/dist/crdt/vendor/yjs/dts/structs/GC.d.ts +25 -0
- package/dist/crdt/vendor/yjs/dts/structs/Item.d.ts +748 -0
- package/dist/crdt/vendor/yjs/dts/structs/Skip.d.ts +30 -0
- package/dist/crdt/vendor/yjs/dts/utils/BlockSet.d.ts +34 -0
- package/dist/crdt/vendor/yjs/dts/utils/Doc.d.ts +198 -0
- package/dist/crdt/vendor/yjs/dts/utils/EventHandler.d.ts +17 -0
- package/dist/crdt/vendor/yjs/dts/utils/ID.d.ts +20 -0
- package/dist/crdt/vendor/yjs/dts/utils/RangeCursor.d.ts +198 -0
- package/dist/crdt/vendor/yjs/dts/utils/RelativePosition.d.ts +80 -0
- package/dist/crdt/vendor/yjs/dts/utils/StructStore.d.ts +61 -0
- package/dist/crdt/vendor/yjs/dts/utils/Transaction.d.ts +129 -0
- package/dist/crdt/vendor/yjs/dts/utils/UndoManager.d.ts +205 -0
- package/dist/crdt/vendor/yjs/dts/utils/UpdateDecoder.d.ts +170 -0
- package/dist/crdt/vendor/yjs/dts/utils/UpdateEncoder.d.ts +164 -0
- package/dist/crdt/vendor/yjs/dts/utils/YEvent.d.ts +93 -0
- package/dist/crdt/vendor/yjs/dts/utils/content-helper.d.ts +1 -0
- package/dist/crdt/vendor/yjs/dts/utils/encoding-helpers.d.ts +5 -0
- package/dist/crdt/vendor/yjs/dts/utils/encoding.d.ts +26 -0
- package/dist/crdt/vendor/yjs/dts/utils/ids.d.ts +407 -0
- package/dist/crdt/vendor/yjs/dts/utils/isParentOf.d.ts +1 -0
- package/dist/crdt/vendor/yjs/dts/utils/meta.d.ts +25 -0
- package/dist/crdt/vendor/yjs/dts/utils/renderer-helpers.d.ts +98 -0
- package/dist/crdt/vendor/yjs/dts/utils/schemas.d.ts +2 -0
- package/dist/crdt/vendor/yjs/dts/utils/transaction-helpers.d.ts +15 -0
- package/dist/crdt/vendor/yjs/dts/utils/updates.d.ts +70 -0
- package/dist/crdt/vendor/yjs/dts/ynode.d.ts +655 -0
- package/dist/crdt/vendor/yjs/global.d.ts +52 -0
- package/dist/crdt/vendor/yjs/src/index.js +64 -0
- package/dist/crdt/vendor/yjs/src/structs/AbstractStruct.js +64 -0
- package/dist/crdt/vendor/yjs/src/structs/GC.js +75 -0
- package/dist/crdt/vendor/yjs/src/structs/Item.js +1538 -0
- package/dist/crdt/vendor/yjs/src/structs/Skip.js +72 -0
- package/dist/crdt/vendor/yjs/src/utils/BlockSet.js +291 -0
- package/dist/crdt/vendor/yjs/src/utils/Doc.js +255 -0
- package/dist/crdt/vendor/yjs/src/utils/EventHandler.js +75 -0
- package/dist/crdt/vendor/yjs/src/utils/ID.js +59 -0
- package/dist/crdt/vendor/yjs/src/utils/RangeCursor.js +407 -0
- package/dist/crdt/vendor/yjs/src/utils/RelativePosition.js +301 -0
- package/dist/crdt/vendor/yjs/src/utils/StructStore.js +134 -0
- package/dist/crdt/vendor/yjs/src/utils/Transaction.js +458 -0
- package/dist/crdt/vendor/yjs/src/utils/UndoManager.js +554 -0
- package/dist/crdt/vendor/yjs/src/utils/UpdateDecoder.js +284 -0
- package/dist/crdt/vendor/yjs/src/utils/UpdateEncoder.js +323 -0
- package/dist/crdt/vendor/yjs/src/utils/YEvent.js +158 -0
- package/dist/crdt/vendor/yjs/src/utils/content-helper.js +0 -0
- package/dist/crdt/vendor/yjs/src/utils/encoding-helpers.js +110 -0
- package/dist/crdt/vendor/yjs/src/utils/encoding.js +662 -0
- package/dist/crdt/vendor/yjs/src/utils/ids.js +1504 -0
- package/dist/crdt/vendor/yjs/src/utils/isParentOf.js +19 -0
- package/dist/crdt/vendor/yjs/src/utils/meta.js +74 -0
- package/dist/crdt/vendor/yjs/src/utils/renderer-helpers.js +186 -0
- package/dist/crdt/vendor/yjs/src/utils/schemas.js +3 -0
- package/dist/crdt/vendor/yjs/src/utils/transaction-helpers.js +391 -0
- package/dist/crdt/vendor/yjs/src/utils/updates.js +264 -0
- package/dist/crdt/vendor/yjs/src/ynode.js +2897 -0
- package/dist/dnd/pragmatic.d.ts +22 -0
- package/dist/dnd/pragmatic.js +26 -0
- package/dist/edytor.svelte.d.ts +323 -54
- package/dist/edytor.svelte.js +771 -197
- package/dist/edytor.utils.d.ts +49 -2
- package/dist/edytor.utils.js +65 -76
- package/dist/events/beforeInputCommands.d.ts +21 -0
- package/dist/events/beforeInputCommands.js +328 -0
- package/dist/events/beforeInputDeleteCommands.d.ts +3 -0
- package/dist/events/beforeInputDeleteCommands.js +245 -0
- package/dist/events/dataTransferPayload.d.ts +6 -0
- package/dist/events/dataTransferPayload.js +9 -0
- package/dist/events/domTextOffset.d.ts +12 -0
- package/dist/events/domTextOffset.js +52 -0
- package/dist/events/events.utils.d.ts +3 -0
- package/dist/events/events.utils.js +13 -0
- package/dist/events/nativeInteractiveControl.d.ts +31 -0
- package/dist/events/nativeInteractiveControl.js +98 -0
- package/dist/events/onBeforeInput.d.ts +10 -1
- package/dist/events/onBeforeInput.js +449 -330
- package/dist/events/onCopy.d.ts +7 -0
- package/dist/events/onCopy.js +30 -0
- package/dist/events/onCut.d.ts +8 -0
- package/dist/events/onCut.js +13 -0
- package/dist/events/onDrop.d.ts +16 -0
- package/dist/events/onDrop.js +158 -0
- package/dist/events/onFocus.d.ts +4 -0
- package/dist/events/onFocus.js +166 -0
- package/dist/events/onInput.d.ts +20 -0
- package/dist/events/onInput.js +249 -0
- package/dist/events/onKeyDown.js +191 -11
- package/dist/events/onPaste.d.ts +3 -0
- package/dist/events/onPaste.js +108 -0
- package/dist/events/wordBoundary.d.ts +2 -0
- package/dist/events/wordBoundary.js +58 -0
- package/dist/index.d.ts +38 -1
- package/dist/index.js +36 -1
- package/dist/kinds.d.ts +100 -0
- package/dist/kinds.js +198 -0
- package/dist/plugins/arrowMove/arrowMove.d.ts +1 -1
- package/dist/plugins/arrowMove/arrowMove.js +30 -65
- package/dist/plugins/blockHandles/BlockHandle.svelte +152 -0
- package/dist/plugins/blockHandles/BlockHandle.svelte.d.ts +12 -0
- package/dist/plugins/blockHandles/BlockHandleController.svelte.d.ts +208 -0
- package/dist/plugins/blockHandles/BlockHandleController.svelte.js +823 -0
- package/dist/plugins/blockHandles/BlockHandles.svelte +151 -0
- package/dist/plugins/blockHandles/BlockHandles.svelte.d.ts +20 -0
- package/dist/plugins/blockHandles/autoScroll.d.ts +8 -0
- package/dist/plugins/blockHandles/autoScroll.js +25 -0
- package/dist/plugins/blockHandles/blockHandlesPlugin.d.ts +37 -0
- package/dist/plugins/blockHandles/blockHandlesPlugin.js +100 -0
- package/dist/plugins/blockHandles/dragPreview.d.ts +33 -0
- package/dist/plugins/blockHandles/dragPreview.js +228 -0
- package/dist/plugins/blockMenu/BlockMenu.svelte +301 -0
- package/dist/plugins/blockMenu/BlockMenu.svelte.d.ts +9 -0
- package/dist/plugins/blockMenu/BlockMenuController.svelte.d.ts +102 -0
- package/dist/plugins/blockMenu/BlockMenuController.svelte.js +245 -0
- package/dist/plugins/blockMenu/blockMenuPlugin.d.ts +11 -0
- package/dist/plugins/blockMenu/blockMenuPlugin.js +89 -0
- package/dist/plugins/code/CodePlugin.svelte +210 -163
- package/dist/plugins/code/CodePlugin.svelte.d.ts +1 -3
- package/dist/plugins/code/code.css +92 -0
- package/dist/plugins/icons.d.ts +2 -0
- package/dist/plugins/icons.js +31 -0
- package/dist/plugins/image/ImageEmpty.svelte +69 -0
- package/dist/plugins/image/ImageEmpty.svelte.d.ts +8 -0
- package/dist/plugins/image/ImagePlugin.svelte +74 -12
- package/dist/plugins/image/ImagePlugin.svelte.d.ts +15 -0
- package/dist/plugins/image/image.d.ts +2 -0
- package/dist/plugins/image/image.js +7 -0
- package/dist/plugins/index.d.ts +14 -1
- package/dist/plugins/index.js +10 -1
- package/dist/plugins/keepInView.d.ts +4 -0
- package/dist/plugins/keepInView.js +6 -0
- package/dist/plugins/markdownShortcuts.d.ts +3 -0
- package/dist/plugins/markdownShortcuts.js +104 -0
- package/dist/plugins/mention/MentionPlugin.svelte +28 -31
- package/dist/plugins/richtext/RichTextPlugin.svelte +411 -200
- package/dist/plugins/richtext/RichTextPlugin.svelte.d.ts +8 -7
- package/dist/plugins/richtext/richTextOperations.d.ts +53 -0
- package/dist/plugins/richtext/richTextOperations.js +200 -0
- package/dist/plugins/slashMenu/SlashMenu.svelte +297 -0
- package/dist/plugins/slashMenu/SlashMenu.svelte.d.ts +11 -0
- package/dist/plugins/slashMenu/SlashMenuController.svelte.d.ts +56 -0
- package/dist/plugins/slashMenu/SlashMenuController.svelte.js +275 -0
- package/dist/plugins/slashMenu/slashMenuPlugin.d.ts +25 -0
- package/dist/plugins/slashMenu/slashMenuPlugin.js +105 -0
- package/dist/plugins/suggestions/SuggestionBars.svelte +142 -0
- package/dist/plugins/suggestions/SuggestionBars.svelte.d.ts +10 -0
- package/dist/plugins/suggestions/suggestionsPlugin.d.ts +28 -0
- package/dist/plugins/suggestions/suggestionsPlugin.js +53 -0
- package/dist/plugins/toolbar/Toolbar.svelte +341 -0
- package/dist/plugins/toolbar/Toolbar.svelte.d.ts +9 -0
- package/dist/plugins/toolbar/ToolbarController.svelte.d.ts +85 -0
- package/dist/plugins/toolbar/ToolbarController.svelte.js +150 -0
- package/dist/plugins/toolbar/toolbarPlugin.d.ts +16 -0
- package/dist/plugins/toolbar/toolbarPlugin.js +40 -0
- package/dist/plugins.d.ts +249 -40
- package/dist/plugins.js +11 -5
- package/dist/selection/domSelection.d.ts +29 -0
- package/dist/selection/domSelection.js +230 -0
- package/dist/selection/replaceSelection.d.ts +143 -0
- package/dist/selection/replaceSelection.js +316 -0
- package/dist/selection/selection.svelte.d.ts +275 -37
- package/dist/selection/selection.svelte.js +1162 -331
- package/dist/selection/selection.utils.d.ts +35 -4
- package/dist/selection/selection.utils.js +309 -100
- package/dist/selection/visibility.d.ts +88 -0
- package/dist/selection/visibility.js +140 -0
- package/dist/session/attempt.d.ts +190 -0
- package/dist/session/attempt.js +188 -0
- package/dist/session/bindings.d.ts +16 -0
- package/dist/session/bindings.js +262 -0
- package/dist/session/commands.d.ts +158 -0
- package/dist/session/commands.js +601 -0
- package/dist/session/composition.svelte.d.ts +114 -0
- package/dist/session/composition.svelte.js +489 -0
- package/dist/session/editing/text.d.ts +33 -0
- package/dist/session/editing/text.js +36 -0
- package/dist/session/handles.d.ts +63 -0
- package/dist/session/handles.js +123 -0
- package/dist/session/history.d.ts +49 -0
- package/dist/session/history.js +131 -0
- package/dist/session/keymap.d.ts +42 -0
- package/dist/session/keymap.js +144 -0
- package/dist/session/moves.d.ts +32 -0
- package/dist/session/moves.js +116 -0
- package/dist/session/navigation.d.ts +51 -0
- package/dist/session/navigation.js +312 -0
- package/dist/session/props.d.ts +28 -0
- package/dist/session/props.js +162 -0
- package/dist/session/selection.d.ts +126 -0
- package/dist/session/selection.js +227 -0
- package/dist/session/suggestions.svelte.d.ts +125 -0
- package/dist/session/suggestions.svelte.js +329 -0
- package/dist/session/virtual.d.ts +33 -0
- package/dist/session/virtual.js +182 -0
- package/dist/surface/attributes.d.ts +36 -0
- package/dist/surface/attributes.js +143 -0
- package/dist/surface/cells.d.ts +103 -0
- package/dist/surface/cells.js +215 -0
- package/dist/surface/observer.svelte.d.ts +70 -0
- package/dist/surface/observer.svelte.js +969 -0
- package/dist/surface/overlay.d.ts +33 -0
- package/dist/surface/overlay.js +91 -0
- package/dist/surface/pin.svelte.d.ts +56 -0
- package/dist/surface/pin.svelte.js +108 -0
- package/dist/surface/projector.svelte.d.ts +69 -0
- package/dist/surface/projector.svelte.js +486 -0
- package/dist/text/deltas.d.ts +14 -3
- package/dist/text/deltas.js +27 -90
- package/dist/text/text.svelte.d.ts +43 -31
- package/dist/text/text.svelte.js +88 -69
- package/dist/text/text.utils.d.ts +7 -2
- package/dist/text/text.utils.js +121 -97
- package/dist/themes/notion.css +473 -0
- package/dist/utils/diffText.d.ts +15 -0
- package/dist/utils/diffText.js +26 -0
- package/dist/utils/json.d.ts +90 -3
- package/dist/utils/json.js +369 -2
- package/dist/utils.d.ts +3 -1
- package/dist/utils.js +2 -0
- package/package.json +112 -50
- package/dist/block/content.svelte.d.ts +0 -14
- package/dist/block/content.svelte.js +0 -40
- package/dist/components/ReadonlyEditor.svelte +0 -46
- package/dist/components/ReadonlyEditor.svelte.d.ts +0 -4
- package/dist/components/readonlyElements.svelte.d.ts +0 -82
- package/dist/components/readonlyElements.svelte.js +0 -144
- package/dist/dnd.svelte.d.ts +0 -17
- package/dist/dnd.svelte.js +0 -125
- package/dist/hotkeys.d.ts +0 -27
- package/dist/hotkeys.js +0 -282
- package/dist/localProvider.d.ts +0 -82
- package/dist/localProvider.js +0 -267
- package/dist/plugins/code/prism.css +0 -141
- package/dist/utils/jsx.d.ts +0 -25
- package/dist/utils/jsx.js +0 -66
- package/dist/utils/serialize.js +0 -1
- /package/dist/{utils/serialize.d.ts → crdt/engine-api.js} +0 -0
|
@@ -1,36 +1,48 @@
|
|
|
1
1
|
import { Edytor } from '../edytor.svelte.js';
|
|
2
|
-
import
|
|
3
|
-
import { type JSONText, type SerializableContent } from '../utils/json.js';
|
|
2
|
+
import { type JSONText } from '../utils/json.js';
|
|
4
3
|
import { Block } from '../block/block.svelte.js';
|
|
5
|
-
|
|
4
|
+
/**
|
|
5
|
+
* An id-only text handle (§2.4 "Handles", R4): the `ordinal`-th text segment
|
|
6
|
+
* of block `blockId` — no identity across commits beyond that position (K5).
|
|
7
|
+
* Getters read the document index; mutators write through the block's model.
|
|
8
|
+
* `node` is the element that renders the segment (a Surface fact).
|
|
9
|
+
*/
|
|
6
10
|
export declare class Text {
|
|
7
11
|
#private;
|
|
8
12
|
readonly: boolean;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
readonly edytor: Edytor;
|
|
14
|
+
readonly blockId: string;
|
|
15
|
+
/** The segment's position among its block's text segments. */
|
|
16
|
+
readonly ordinal: number;
|
|
17
|
+
readonly id: string;
|
|
14
18
|
node: HTMLElement | undefined;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
constructor(edytor: Edytor, blockId: string, ordinal: number);
|
|
20
|
+
get parent(): Block;
|
|
21
|
+
/** Position among the block's content parts. */
|
|
22
|
+
get index(): number;
|
|
19
23
|
get value(): JSONText[];
|
|
24
|
+
/** The segment's text. */
|
|
25
|
+
get stringContent(): string;
|
|
26
|
+
get isEmpty(): boolean;
|
|
27
|
+
get endsWithNewline(): boolean;
|
|
20
28
|
get length(): number;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
/** Display offset of this segment inside its block's content (atoms count 1). */
|
|
30
|
+
get segStart(): number;
|
|
31
|
+
/** The segment is shown by a live block. */
|
|
32
|
+
get isInDocument(): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Re-create this block's text elements from its cell — the repair of a
|
|
35
|
+
* DOM the browser or a foreign script changed (typing and model commits
|
|
36
|
+
* never remount). Never while the IME owns the element. A remount under
|
|
37
|
+
* the caret is a render the projector displays after (`mounted`).
|
|
38
|
+
*/
|
|
39
|
+
refreshFromModel: () => void;
|
|
40
|
+
/** Insert `text` (optionally marked) at segment-local `offset`. */
|
|
41
|
+
insertAt: (offset: number, text: string, marks?: Record<string, unknown> | null) => boolean;
|
|
42
|
+
/** Delete `length` atoms at segment-local `offset`. */
|
|
43
|
+
deleteAt: (offset: number, length: number) => boolean;
|
|
44
|
+
/** Multi-mark format over `[offset, offset+length)` — `null` values remove the mark. */
|
|
45
|
+
formatAt: (offset: number, length: number, attributes: Record<string, unknown>) => boolean;
|
|
34
46
|
private batch;
|
|
35
47
|
getMarksAtRange: (yStart: number, yEnd: number) => JSONText[];
|
|
36
48
|
insertText: (args_0: {
|
|
@@ -38,12 +50,15 @@ export declare class Text {
|
|
|
38
50
|
isAutoDot?: boolean;
|
|
39
51
|
start?: number;
|
|
40
52
|
end?: number;
|
|
41
|
-
marks?: Record<string, SerializableContent | null>;
|
|
53
|
+
marks?: Record<string, import("../utils/json.js").SerializableContent | null>;
|
|
42
54
|
}) => void;
|
|
43
55
|
deleteText: (args_0: {
|
|
44
56
|
direction: "BACKWARD" | "FORWARD";
|
|
45
57
|
length: number;
|
|
46
|
-
}) =>
|
|
58
|
+
}) => {
|
|
59
|
+
start: number;
|
|
60
|
+
end: number;
|
|
61
|
+
} | undefined;
|
|
47
62
|
splitText: (args_0: {
|
|
48
63
|
index?: number;
|
|
49
64
|
}) => JSONText[];
|
|
@@ -54,15 +69,12 @@ export declare class Text {
|
|
|
54
69
|
mark: string;
|
|
55
70
|
start?: number;
|
|
56
71
|
end?: number;
|
|
57
|
-
value?: SerializableContent | null;
|
|
72
|
+
value?: import("../utils/json.js").SerializableContent | null;
|
|
58
73
|
toggle?: boolean;
|
|
59
74
|
}) => void;
|
|
60
75
|
removeMarksFromText: (args_0: {
|
|
61
|
-
mark: string;
|
|
62
76
|
start?: number;
|
|
63
77
|
end?: number;
|
|
64
|
-
value?: SerializableContent | null;
|
|
65
|
-
toggle?: boolean;
|
|
66
78
|
}) => void;
|
|
67
79
|
attach: (node: HTMLElement) => {
|
|
68
80
|
destroy: () => void;
|
package/dist/text/text.svelte.js
CHANGED
|
@@ -1,84 +1,96 @@
|
|
|
1
1
|
import { Edytor } from '../edytor.svelte.js';
|
|
2
|
-
import * as Y from 'yjs';
|
|
3
2
|
import {} from '../utils/json.js';
|
|
4
3
|
import { Block } from '../block/block.svelte.js';
|
|
5
4
|
import { batch, deleteText, removeMarksFromText, getMarksAtRange, insertText, markText, setText, splitText } from './text.utils.js';
|
|
6
|
-
import { deltaToJson,
|
|
7
|
-
import { id } from '../utils.js';
|
|
5
|
+
import { deltaToJson, runsToDeltas } from './deltas.js';
|
|
8
6
|
import { climb } from '../selection/selection.utils.js';
|
|
7
|
+
/** A write through the block's model that the document did not refuse. */
|
|
8
|
+
const accepted = (r) => r !== undefined && r.status !== 'refused';
|
|
9
|
+
/**
|
|
10
|
+
* An id-only text handle (§2.4 "Handles", R4): the `ordinal`-th text segment
|
|
11
|
+
* of block `blockId` — no identity across commits beyond that position (K5).
|
|
12
|
+
* Getters read the document index; mutators write through the block's model.
|
|
13
|
+
* `node` is the element that renders the segment (a Surface fact).
|
|
14
|
+
*/
|
|
9
15
|
export class Text {
|
|
10
16
|
readonly = false;
|
|
11
|
-
parent;
|
|
12
|
-
yText;
|
|
13
17
|
edytor;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
// Used to add en empty string in the DOM if the text is empty in order to be abble to focus on it.
|
|
18
|
-
isEmpty = $state(false);
|
|
19
|
-
// Used to add en empty string at the end of the text if it ends with a newline in order to visually render the newline.
|
|
20
|
-
endsWithNewline = $state(false);
|
|
21
|
-
// Used when user toggles mark without selection range.
|
|
22
|
-
markOnNextInsert = undefined;
|
|
18
|
+
blockId;
|
|
19
|
+
/** The segment's position among its block's text segments. */
|
|
20
|
+
ordinal;
|
|
23
21
|
id;
|
|
24
|
-
|
|
22
|
+
node;
|
|
23
|
+
constructor(edytor, blockId, ordinal) {
|
|
24
|
+
this.edytor = edytor;
|
|
25
|
+
this.blockId = blockId;
|
|
26
|
+
this.ordinal = ordinal;
|
|
27
|
+
this.id = `t:${blockId}:${ordinal}`;
|
|
28
|
+
}
|
|
29
|
+
get parent() {
|
|
30
|
+
return this.edytor.idToBlock.block(this.blockId);
|
|
31
|
+
}
|
|
32
|
+
/** This segment in its block's parts, and its position among them. */
|
|
33
|
+
get #at() {
|
|
34
|
+
const parts = this.edytor.idToBlock.parts(this.blockId);
|
|
35
|
+
for (let index = 0, k = 0; index < parts.length; index++) {
|
|
36
|
+
const part = parts[index];
|
|
37
|
+
if (part.kind === 'text' && k++ === this.ordinal)
|
|
38
|
+
return { part, index };
|
|
39
|
+
}
|
|
40
|
+
return { index: -1 };
|
|
41
|
+
}
|
|
42
|
+
/** Position among the block's content parts. */
|
|
43
|
+
get index() {
|
|
44
|
+
return this.#at.index;
|
|
45
|
+
}
|
|
25
46
|
get value() {
|
|
26
|
-
return deltaToJson(this.#
|
|
47
|
+
return deltaToJson(runsToDeltas(this.#at.part?.items ?? [])[0]);
|
|
48
|
+
}
|
|
49
|
+
/** The segment's text. */
|
|
50
|
+
get stringContent() {
|
|
51
|
+
return this.#at.part?.items.map((item) => item.text).join('') ?? '';
|
|
52
|
+
}
|
|
53
|
+
get isEmpty() {
|
|
54
|
+
return this.length === 0;
|
|
55
|
+
}
|
|
56
|
+
get endsWithNewline() {
|
|
57
|
+
return this.stringContent.endsWith('\n');
|
|
27
58
|
}
|
|
28
59
|
get length() {
|
|
29
|
-
return this.
|
|
60
|
+
return this.#at.part?.length ?? 0;
|
|
30
61
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return
|
|
34
|
-
? jsonToDelta(transformer({ text: this, block: this.parent, content: this.value }))
|
|
35
|
-
: this.#children;
|
|
62
|
+
/** Display offset of this segment inside its block's content (atoms count 1). */
|
|
63
|
+
get segStart() {
|
|
64
|
+
return this.#at.part?.start ?? 0;
|
|
36
65
|
}
|
|
37
|
-
|
|
38
|
-
|
|
66
|
+
/** The segment is shown by a live block. */
|
|
67
|
+
get isInDocument() {
|
|
68
|
+
return this.parent.isInTree && this.#at.part !== undefined;
|
|
39
69
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
this.setChildren(event.target);
|
|
70
|
+
/**
|
|
71
|
+
* Re-create this block's text elements from its cell — the repair of a
|
|
72
|
+
* DOM the browser or a foreign script changed (typing and model commits
|
|
73
|
+
* never remount). Never while the IME owns the element. A remount under
|
|
74
|
+
* the caret is a render the projector displays after (`mounted`).
|
|
75
|
+
*/
|
|
76
|
+
refreshFromModel = () => {
|
|
77
|
+
if (this.edytor.pin.owns(this.node))
|
|
78
|
+
return;
|
|
79
|
+
this.edytor.cells?.remount(this.parent.id);
|
|
52
80
|
};
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
this.yText.applyDelta(content.map((part) => ({
|
|
67
|
-
insert: part.text,
|
|
68
|
-
attributes: part.marks
|
|
69
|
-
})));
|
|
70
|
-
}
|
|
71
|
-
this.setChildren();
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
this.setChildren();
|
|
76
|
-
}
|
|
77
|
-
this.edytor.idToText.set(this.id, this);
|
|
78
|
-
if (!this.edytor.readonly) {
|
|
79
|
-
this.yText.observe(this.observeText);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
81
|
+
// ── segment writes ───────────────────────────────────────────────────
|
|
82
|
+
//
|
|
83
|
+
// `insertAt`/`deleteAt`/`formatAt` are the offset-based primitives the
|
|
84
|
+
// operation layer (`text.utils`), event handlers and plugins call. Offsets
|
|
85
|
+
// are SEGMENT-LOCAL display atoms (UTF-16 units); `segStart` maps them into
|
|
86
|
+
// the block's display space (read from the index, so a write after another
|
|
87
|
+
// in the same transaction lands right).
|
|
88
|
+
/** Insert `text` (optionally marked) at segment-local `offset`. */
|
|
89
|
+
insertAt = (offset, text, marks) => accepted(this.parent.model?.insertText(this.segStart + offset, text, marks ?? undefined));
|
|
90
|
+
/** Delete `length` atoms at segment-local `offset`. */
|
|
91
|
+
deleteAt = (offset, length) => accepted(this.parent.model?.deleteText(this.segStart + offset, length));
|
|
92
|
+
/** Multi-mark format over `[offset, offset+length)` — `null` values remove the mark. */
|
|
93
|
+
formatAt = (offset, length, attributes) => accepted(this.parent.model?.format(this.segStart + offset, length, attributes));
|
|
82
94
|
batch = batch.bind(this);
|
|
83
95
|
getMarksAtRange = getMarksAtRange.bind(this);
|
|
84
96
|
insertText = this.batch('insertText', insertText.bind(this));
|
|
@@ -90,11 +102,13 @@ export class Text {
|
|
|
90
102
|
attach = (node) => {
|
|
91
103
|
this.node = node;
|
|
92
104
|
this.edytor.nodeToText.set(node, this);
|
|
105
|
+
const release = this.edytor.surface.register(node, 'text', this.parent.id);
|
|
93
106
|
node.setAttribute('data-edytor-id', `${this.id}`);
|
|
94
107
|
node.setAttribute('data-edytor-text', `true`);
|
|
95
108
|
let pluginDestroy = this.edytor.plugins.reduce((acc, plugin) => {
|
|
96
109
|
const action = plugin.onTextAttached?.({ node, text: this });
|
|
97
|
-
action
|
|
110
|
+
if (typeof action === 'function')
|
|
111
|
+
acc.push(action);
|
|
98
112
|
return acc;
|
|
99
113
|
}, []);
|
|
100
114
|
let insideVoid = this.parent.definition.void;
|
|
@@ -105,13 +119,18 @@ export class Text {
|
|
|
105
119
|
}
|
|
106
120
|
});
|
|
107
121
|
if (insideVoid) {
|
|
108
|
-
node.
|
|
122
|
+
node.setAttribute('contenteditable', 'true');
|
|
109
123
|
node.style.outline = 'none';
|
|
110
124
|
}
|
|
125
|
+
// A display that waited for a mounted destination runs in the next pass.
|
|
126
|
+
this.edytor.projector?.mounted(this);
|
|
111
127
|
return {
|
|
112
128
|
destroy: () => {
|
|
113
|
-
|
|
114
|
-
|
|
129
|
+
if (this.node === node)
|
|
130
|
+
this.node = undefined;
|
|
131
|
+
if (this.edytor.nodeToText.get(node) === this)
|
|
132
|
+
this.edytor.nodeToText.delete(node);
|
|
133
|
+
release();
|
|
115
134
|
pluginDestroy.forEach((destroy) => destroy());
|
|
116
135
|
}
|
|
117
136
|
};
|
|
@@ -33,8 +33,13 @@ export type TextOperations = {
|
|
|
33
33
|
export declare function batch<T extends (...args: any[]) => any, O extends keyof TextOperations>(operation: O, func: T): T;
|
|
34
34
|
export declare function insertText(this: Text, { value, isAutoDot, start, end, marks }: TextOperations['insertText']): void;
|
|
35
35
|
export declare function getMarksAtRange(this: Text, yStart: number, yEnd: number): JSONText[];
|
|
36
|
-
export declare
|
|
37
|
-
export declare
|
|
36
|
+
export declare const getPreviousGraphemeStart: (value: string, offset: number) => number;
|
|
37
|
+
export declare const getNextGraphemeEnd: (value: string, offset: number) => number;
|
|
38
|
+
export declare function deleteText(this: Text, { direction, length }: TextOperations['deleteText']): {
|
|
39
|
+
start: number;
|
|
40
|
+
end: number;
|
|
41
|
+
} | undefined;
|
|
42
|
+
export declare function removeMarksFromText(this: Text, { start, end }: TextOperations['removeMarksFromText']): void;
|
|
38
43
|
export declare function markText(this: Text, { mark, value, toggle, start, end }: TextOperations['markText']): void;
|
|
39
44
|
export declare function splitText(this: Text, { index }: TextOperations['splitText']): JSONText[];
|
|
40
45
|
export declare function setText(this: Text, { value }: TextOperations['setText']): void;
|
package/dist/text/text.utils.js
CHANGED
|
@@ -1,62 +1,50 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { marksForInsertion } from '../session/editing/text.js';
|
|
2
2
|
export function batch(operation, func) {
|
|
3
3
|
return function (payload) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const normalizedPayload = plugin.onBeforeOperation?.({
|
|
8
|
-
operation,
|
|
9
|
-
payload,
|
|
10
|
-
text: this,
|
|
11
|
-
block: this.parent,
|
|
12
|
-
prevent
|
|
13
|
-
});
|
|
14
|
-
if (normalizedPayload) {
|
|
15
|
-
finalPayload = normalizedPayload;
|
|
16
|
-
break;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
const result = this.edytor.transact(() => func.bind(this)(finalPayload));
|
|
20
|
-
for (const plugin of this.edytor.plugins) {
|
|
21
|
-
plugin.onAfterOperation?.({
|
|
22
|
-
operation,
|
|
23
|
-
payload,
|
|
24
|
-
text: this,
|
|
25
|
-
block: this.parent
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
return result;
|
|
4
|
+
// Dispatched like block operations (`session/commands.ts`): plugins see
|
|
5
|
+
// `block: this.parent` + `text: this`, the text arm of `ChangePayload`.
|
|
6
|
+
return this.edytor.dispatcher.dispatch(operation, payload, { block: this.parent, text: this }, func);
|
|
29
7
|
};
|
|
30
8
|
}
|
|
31
|
-
export function insertText({ value, isAutoDot, start = this.edytor.selection.state.yStart, end = this.edytor.selection.state.yEnd, marks
|
|
9
|
+
export function insertText({ value, isAutoDot, start = this.edytor.selection.state.yStart, end = this.edytor.selection.state.yEnd, marks }) {
|
|
32
10
|
const isCollapsed = start === end || !end;
|
|
33
|
-
//
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
this.
|
|
11
|
+
// The caret's pending marks (L4) apply to an insertion at the caret, which consumes them.
|
|
12
|
+
const { selection } = this.edytor;
|
|
13
|
+
const { startText, yStart } = selection.state;
|
|
14
|
+
const pending = startText === this && yStart === start ? selection.pending : undefined;
|
|
15
|
+
marks ??= marksForInsertion(this, start, {
|
|
16
|
+
replaced: isCollapsed ? undefined : this.getMarksAtRange(start, end),
|
|
17
|
+
pending
|
|
18
|
+
});
|
|
19
|
+
this.edytor.transact(() => {
|
|
20
|
+
if (isAutoDot) {
|
|
21
|
+
// Replace the previous char with the inserted value (autocorrect).
|
|
22
|
+
this.deleteAt(start - 1, 1);
|
|
23
|
+
this.insertAt(start - 1, value, marks);
|
|
24
|
+
}
|
|
25
|
+
else if (!isCollapsed) {
|
|
26
|
+
this.deleteAt(start, end - start);
|
|
27
|
+
this.insertAt(start, value, marks);
|
|
45
28
|
}
|
|
46
29
|
else {
|
|
47
|
-
this.
|
|
30
|
+
this.insertAt(start, value, marks);
|
|
48
31
|
}
|
|
49
32
|
});
|
|
50
|
-
if (
|
|
51
|
-
|
|
52
|
-
}
|
|
33
|
+
if (pending)
|
|
34
|
+
selection.stage(undefined);
|
|
53
35
|
}
|
|
54
36
|
export function getMarksAtRange(yStart, yEnd) {
|
|
55
37
|
const result = [];
|
|
56
38
|
let offset = 0;
|
|
57
39
|
let entered = false;
|
|
58
|
-
|
|
59
|
-
|
|
40
|
+
// Iterate the MODEL runs (`this.value`), never `this.children` — the
|
|
41
|
+
// children getter applies the block's `transformText` (e.g. code
|
|
42
|
+
// tokens), whose marks are local decorations. Reading them here leaked
|
|
43
|
+
// `codeToken` into persisted marks: typed/composed text inside a code
|
|
44
|
+
// line inherited the decoration, splitting the serialized content.
|
|
45
|
+
const parts = this.value;
|
|
46
|
+
for (let i = 0; i < parts.length; i++) {
|
|
47
|
+
const { text, marks } = parts[i];
|
|
60
48
|
const length = text.length;
|
|
61
49
|
const end = offset + length;
|
|
62
50
|
if (yStart >= offset && yStart < end) {
|
|
@@ -66,14 +54,14 @@ export function getMarksAtRange(yStart, yEnd) {
|
|
|
66
54
|
const endOffset = Math.min(length, yEnd - offset);
|
|
67
55
|
result.push({
|
|
68
56
|
text: text.slice(startOffset, endOffset),
|
|
69
|
-
marks:
|
|
57
|
+
marks: { ...(marks ?? {}) }
|
|
70
58
|
});
|
|
71
59
|
}
|
|
72
60
|
else if (entered && end <= yEnd) {
|
|
73
61
|
// Middle of range
|
|
74
62
|
result.push({
|
|
75
63
|
text,
|
|
76
|
-
marks:
|
|
64
|
+
marks: { ...(marks ?? {}) }
|
|
77
65
|
});
|
|
78
66
|
}
|
|
79
67
|
else if (entered && offset < yEnd && yEnd <= end) {
|
|
@@ -81,7 +69,7 @@ export function getMarksAtRange(yStart, yEnd) {
|
|
|
81
69
|
const endOffset = yEnd - offset;
|
|
82
70
|
result.push({
|
|
83
71
|
text: text.slice(0, endOffset),
|
|
84
|
-
marks:
|
|
72
|
+
marks: { ...(marks ?? {}) }
|
|
85
73
|
});
|
|
86
74
|
break;
|
|
87
75
|
}
|
|
@@ -89,57 +77,89 @@ export function getMarksAtRange(yStart, yEnd) {
|
|
|
89
77
|
}
|
|
90
78
|
return result;
|
|
91
79
|
}
|
|
80
|
+
const getGraphemeBoundaries = (value) => {
|
|
81
|
+
const Segmenter = Intl.Segmenter;
|
|
82
|
+
if (Segmenter) {
|
|
83
|
+
return Array.from(new Segmenter(undefined, { granularity: 'grapheme' }).segment(value)).map(({ index, segment }) => ({
|
|
84
|
+
start: index,
|
|
85
|
+
end: index + segment.length
|
|
86
|
+
}));
|
|
87
|
+
}
|
|
88
|
+
let index = 0;
|
|
89
|
+
return Array.from(value).map((segment) => {
|
|
90
|
+
const start = index;
|
|
91
|
+
index += segment.length;
|
|
92
|
+
return {
|
|
93
|
+
start,
|
|
94
|
+
end: index
|
|
95
|
+
};
|
|
96
|
+
});
|
|
97
|
+
};
|
|
98
|
+
export const getPreviousGraphemeStart = (value, offset) => {
|
|
99
|
+
const clampedOffset = Math.min(Math.max(offset, 0), value.length);
|
|
100
|
+
let previousStart = 0;
|
|
101
|
+
for (const boundary of getGraphemeBoundaries(value)) {
|
|
102
|
+
if (boundary.end >= clampedOffset) {
|
|
103
|
+
return boundary.start < clampedOffset ? boundary.start : previousStart;
|
|
104
|
+
}
|
|
105
|
+
previousStart = boundary.start;
|
|
106
|
+
}
|
|
107
|
+
return previousStart;
|
|
108
|
+
};
|
|
109
|
+
export const getNextGraphemeEnd = (value, offset) => {
|
|
110
|
+
const clampedOffset = Math.min(Math.max(offset, 0), value.length);
|
|
111
|
+
for (const boundary of getGraphemeBoundaries(value)) {
|
|
112
|
+
if (boundary.end > clampedOffset) {
|
|
113
|
+
return boundary.end;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return clampedOffset;
|
|
117
|
+
};
|
|
92
118
|
export function deleteText({ direction, length = 1 }) {
|
|
93
119
|
const { yStart, isCollapsed } = this.edytor.selection.state;
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
120
|
+
const requestedLength = Math.max(0, length);
|
|
121
|
+
const textLength = this.length;
|
|
122
|
+
if (requestedLength === 0 || textLength === 0) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const shouldDeleteSingleGrapheme = isCollapsed && requestedLength === 1;
|
|
126
|
+
const start = shouldDeleteSingleGrapheme && direction === 'BACKWARD'
|
|
127
|
+
? getPreviousGraphemeStart(this.stringContent, yStart)
|
|
128
|
+
: direction === 'BACKWARD' && isCollapsed
|
|
129
|
+
? Math.max(0, yStart - requestedLength)
|
|
130
|
+
: Math.max(0, yStart);
|
|
131
|
+
const end = shouldDeleteSingleGrapheme && direction === 'FORWARD'
|
|
132
|
+
? getNextGraphemeEnd(this.stringContent, yStart)
|
|
133
|
+
: direction === 'BACKWARD' && isCollapsed
|
|
134
|
+
? Math.min(textLength, yStart)
|
|
135
|
+
: Math.min(textLength, start + requestedLength);
|
|
136
|
+
const deleteLength = end - start;
|
|
137
|
+
if (deleteLength <= 0) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
this.deleteAt(start, deleteLength);
|
|
141
|
+
return { start, end };
|
|
98
142
|
}
|
|
99
|
-
export function removeMarksFromText({ start = this.edytor.selection.state.yStart || 0, end = this.edytor.selection.state.yEnd || this.
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
Object.assign({ key: null });
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
return acc;
|
|
108
|
-
}, {});
|
|
109
|
-
this.yText.format(start, end, attributes);
|
|
143
|
+
export function removeMarksFromText({ start = this.edytor.selection.state.yStart || 0, end = this.edytor.selection.state.yEnd || this.length }) {
|
|
144
|
+
// Persisted mark changes delegate to the document: `clearMarks` discovers
|
|
145
|
+
// every mark name present in the range and unsets them; `segStart` maps
|
|
146
|
+
// the segment-local range into the block's display offsets.
|
|
147
|
+
this.parent.model?.clearMarks(this.segStart + start, end - start);
|
|
110
148
|
}
|
|
111
149
|
export function markText({ mark, value = true, toggle = false, start = this.edytor.selection.state.yStart, end = this.edytor.selection.state.yEnd }) {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const markValue = (spreadOnAllRange || isNextActiveMark) && toggle ? null : value;
|
|
118
|
-
if (isCollasped) {
|
|
119
|
-
const activeMarks = marksAtRange.reduce((acc, { marks }) => {
|
|
120
|
-
Object.entries(marks || {}).forEach(([key, value]) => {
|
|
121
|
-
if (value === true) {
|
|
122
|
-
Object.assign(acc, { [key]: true });
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
return acc;
|
|
126
|
-
}, {});
|
|
127
|
-
if (isNextActiveMark && markValue === null) {
|
|
128
|
-
delete this.markOnNextInsert[mark];
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
this.markOnNextInsert = {
|
|
132
|
-
...(this.markOnNextInsert || {}),
|
|
133
|
-
...activeMarks,
|
|
134
|
-
[mark]: markValue
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
this.yText.format(start, length, {
|
|
140
|
-
[mark]: markValue
|
|
150
|
+
if (start === end) {
|
|
151
|
+
// A caret stages the full set the next insertion carries (values kept).
|
|
152
|
+
const { selection } = this.edytor;
|
|
153
|
+
const { [mark]: current = null, ...rest } = marksForInsertion(this, start, {
|
|
154
|
+
pending: selection.pending
|
|
141
155
|
});
|
|
156
|
+
const next = current !== null && toggle ? null : value;
|
|
157
|
+
selection.stage(next === null ? rest : { ...rest, [mark]: next });
|
|
158
|
+
return;
|
|
142
159
|
}
|
|
160
|
+
const marksAtRange = this.getMarksAtRange(start, end);
|
|
161
|
+
const spreadOnAllRange = marksAtRange.length > 0 && marksAtRange.every(({ marks }) => marks && mark in marks);
|
|
162
|
+
this.formatAt(start, end - start, { [mark]: spreadOnAllRange && toggle ? null : value });
|
|
143
163
|
}
|
|
144
164
|
// This function split a Y.Text at an index, delete what is after the index and returns the deleted content as a JSONText[]
|
|
145
165
|
export function splitText({ index = this.edytor.selection.state.yStart }) {
|
|
@@ -163,12 +183,16 @@ export function splitText({ index = this.edytor.selection.state.yStart }) {
|
|
|
163
183
|
}
|
|
164
184
|
offset = nextOffset;
|
|
165
185
|
}
|
|
166
|
-
this.
|
|
186
|
+
this.deleteAt(index, this.length - index);
|
|
167
187
|
return content;
|
|
168
188
|
}
|
|
169
189
|
export function setText({ value }) {
|
|
170
|
-
this.
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
190
|
+
this.deleteAt(0, this.length);
|
|
191
|
+
let offset = 0;
|
|
192
|
+
for (const part of value) {
|
|
193
|
+
if (part.text.length) {
|
|
194
|
+
this.insertAt(offset, part.text, part.marks);
|
|
195
|
+
offset += part.text.length;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
174
198
|
}
|