edytor 2.0.0 → 4.0.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 +19 -4
- package/dist/block/block.svelte.js +2 -4
- package/dist/clipboard/htmlFlow.d.ts +20 -7
- package/dist/clipboard/htmlFlow.js +23 -15
- package/dist/clipboard/serializeClipboardFragment.d.ts +37 -4
- package/dist/clipboard/serializeClipboardFragment.js +6 -4
- package/dist/clipboard/textBlocks.d.ts +8 -0
- package/dist/clipboard/textBlocks.js +6 -2
- package/dist/cloudflare/DocumentRoom.d.ts +13 -9
- package/dist/cloudflare/DocumentRoom.js +10 -6
- package/dist/cloudflare/room/admission.js +3 -3
- package/dist/cloudflare/room/context.d.ts +28 -27
- package/dist/cloudflare/room/context.js +2 -2
- package/dist/cloudflare/room/purge.d.ts +6 -3
- package/dist/cloudflare/room/purge.js +44 -19
- package/dist/cloudflare/room/updates.d.ts +3 -4
- package/dist/cloudflare/room/updates.js +6 -8
- package/dist/cloudflare/routeDocumentSocket.d.ts +17 -0
- package/dist/cloudflare/routeDocumentSocket.js +53 -0
- package/dist/collaboration/comments/client.d.ts +1 -1
- package/dist/collaboration/comments/client.js +1 -1
- package/dist/collaboration/remoteSelection.js +3 -3
- package/dist/components/Edytor.svelte +2 -10
- package/dist/components/Edytor.svelte.d.ts +1 -3
- package/dist/crdt/admission.d.ts +5 -10
- package/dist/crdt/admission.js +5 -11
- package/dist/crdt/attribution/attribution.d.ts +31 -12
- package/dist/crdt/attribution/attribution.js +56 -18
- package/dist/crdt/attribution/block.d.ts +3 -3
- package/dist/crdt/attribution/block.js +7 -8
- package/dist/crdt/attribution/index.d.ts +1 -1
- package/dist/crdt/attribution/index.js +1 -1
- package/dist/crdt/data.d.ts +62 -31
- package/dist/crdt/data.js +211 -103
- package/dist/crdt/doc/delete.d.ts +1 -1
- package/dist/crdt/doc/delete.js +13 -30
- package/dist/crdt/doc/funnel.d.ts +7 -6
- package/dist/crdt/doc/funnel.js +39 -33
- package/dist/crdt/doc/gate.d.ts +3 -20
- package/dist/crdt/doc/gate.js +2 -41
- package/dist/crdt/doc/history.d.ts +25 -9
- package/dist/crdt/doc/history.js +152 -42
- package/dist/crdt/doc/layout.js +11 -22
- package/dist/crdt/doc/meta.js +12 -17
- package/dist/crdt/doc/moves.d.ts +1 -1
- package/dist/crdt/doc/moves.js +52 -32
- package/dist/crdt/doc/reads.js +2 -2
- package/dist/crdt/doc/seed.js +2 -2
- package/dist/crdt/doc/split-merge.js +12 -15
- package/dist/crdt/doc/steps.d.ts +25 -13
- package/dist/crdt/doc/steps.js +52 -122
- package/dist/crdt/doc/types.d.ts +21 -9
- package/dist/crdt/document.d.ts +21 -19
- package/dist/crdt/document.js +26 -23
- package/dist/crdt/edytor-doc.d.ts +66 -68
- package/dist/crdt/edytor-doc.js +21 -20
- package/dist/crdt/engine-api.d.ts +33 -1
- package/dist/crdt/engine.d.ts +0 -1
- package/dist/crdt/engine.js +1 -4
- package/dist/crdt/flow.d.ts +1 -1
- package/dist/crdt/flow.js +25 -27
- package/dist/crdt/index.d.ts +29 -28
- package/dist/crdt/index.js +3 -3
- package/dist/crdt/placement/display.d.ts +5 -30
- package/dist/crdt/placement/display.js +39 -144
- package/dist/crdt/placement/keys.d.ts +58 -0
- package/dist/crdt/placement/keys.js +90 -0
- package/dist/crdt/placement/model.d.ts +119 -118
- package/dist/crdt/placement/model.js +242 -142
- package/dist/crdt/placement/resolve.d.ts +123 -35
- package/dist/crdt/placement/resolve.js +187 -153
- package/dist/crdt/placement/slots.d.ts +134 -0
- package/dist/crdt/placement/slots.js +152 -0
- package/dist/crdt/protocol.d.ts +2 -2
- package/dist/crdt/protocol.js +2 -2
- package/dist/crdt/providers/index.d.ts +1 -1
- package/dist/crdt/providers/room.d.ts +26 -11
- package/dist/crdt/providers/room.js +77 -27
- package/dist/crdt/providers/websocket.d.ts +1 -1
- package/dist/crdt/providers/websocket.js +33 -32
- package/dist/crdt/purge.d.ts +17 -8
- package/dist/crdt/purge.js +236 -126
- package/dist/crdt/restore.d.ts +2 -2
- package/dist/crdt/restore.js +18 -34
- package/dist/crdt/schema.d.ts +22 -21
- package/dist/crdt/schema.js +29 -23
- package/dist/crdt/semantics.js +3 -1
- package/dist/crdt/storage.d.ts +1 -1
- package/dist/crdt/storage.js +1 -1
- package/dist/crdt/structs.d.ts +15 -15
- package/dist/crdt/structs.js +8 -22
- package/dist/crdt/text/index/cache.js +4 -0
- package/dist/crdt/text/index/claims.js +12 -0
- package/dist/crdt/text/index/fold.d.ts +2 -3
- package/dist/crdt/text/index/fold.js +194 -44
- package/dist/crdt/text/index/layout.js +5 -8
- package/dist/crdt/text/index/placement.d.ts +26 -18
- package/dist/crdt/text/index/placement.js +404 -138
- package/dist/crdt/text/index/records.d.ts +3 -3
- package/dist/crdt/text/index/records.js +24 -31
- package/dist/crdt/text/index/shared.d.ts +11 -3
- package/dist/crdt/text/index/shared.js +12 -3
- package/dist/crdt/text/index/state.d.ts +21 -17
- package/dist/crdt/text/index/state.js +15 -17
- package/dist/crdt/text/index/streams.d.ts +10 -5
- package/dist/crdt/text/index/streams.js +78 -27
- package/dist/crdt/text/items.d.ts +10 -3
- package/dist/crdt/text/items.js +7 -0
- package/dist/crdt/text/model.d.ts +77 -62
- package/dist/crdt/text/model.js +84 -169
- package/dist/crdt/text/ranges.d.ts +1 -1
- package/dist/crdt/text/ranges.js +3 -3
- package/dist/crdt/text/rows.d.ts +13 -7
- package/dist/crdt/text/rows.js +24 -7
- package/dist/crdt/text/runs.d.ts +17 -12
- package/dist/crdt/text/runs.js +24 -7
- package/dist/crdt/text/streams.d.ts +26 -13
- package/dist/crdt/text/streams.js +41 -14
- package/dist/crdt/vendor/yjs/UPSTREAM.md +568 -21
- package/dist/crdt/vendor/yjs/dts/global.d.ts +2 -0
- package/dist/crdt/vendor/yjs/dts/index.d.ts +1 -1
- package/dist/crdt/vendor/yjs/dts/structs/AbstractStruct.d.ts +7 -0
- package/dist/crdt/vendor/yjs/dts/structs/Item.d.ts +194 -10
- package/dist/crdt/vendor/yjs/dts/utils/Doc.d.ts +6 -3
- package/dist/crdt/vendor/yjs/dts/utils/StructStore.d.ts +5 -18
- package/dist/crdt/vendor/yjs/dts/utils/Transaction.d.ts +15 -1
- package/dist/crdt/vendor/yjs/dts/utils/UpdateDecoder.d.ts +14 -6
- package/dist/crdt/vendor/yjs/dts/utils/UpdateEncoder.d.ts +33 -6
- package/dist/crdt/vendor/yjs/dts/utils/ids.d.ts +1 -65
- package/dist/crdt/vendor/yjs/dts/utils/marks.d.ts +6 -1
- package/dist/crdt/vendor/yjs/dts/ynode.d.ts +43 -7
- package/dist/crdt/vendor/yjs/global.d.ts +2 -0
- package/dist/crdt/vendor/yjs/src/index.js +1 -1
- package/dist/crdt/vendor/yjs/src/structs/AbstractStruct.js +10 -0
- package/dist/crdt/vendor/yjs/src/structs/Item.js +610 -51
- package/dist/crdt/vendor/yjs/src/utils/BlockSet.js +18 -9
- package/dist/crdt/vendor/yjs/src/utils/Doc.js +5 -3
- package/dist/crdt/vendor/yjs/src/utils/StructStore.js +5 -0
- package/dist/crdt/vendor/yjs/src/utils/Transaction.js +36 -13
- package/dist/crdt/vendor/yjs/src/utils/UpdateDecoder.js +88 -18
- package/dist/crdt/vendor/yjs/src/utils/UpdateEncoder.js +119 -32
- package/dist/crdt/vendor/yjs/src/utils/encoding.js +13 -1
- package/dist/crdt/vendor/yjs/src/utils/ids.js +7 -7
- package/dist/crdt/vendor/yjs/src/utils/marks.js +193 -8
- package/dist/crdt/vendor/yjs/src/utils/redo.js +1 -1
- package/dist/crdt/vendor/yjs/src/utils/transaction-helpers.js +1 -1
- package/dist/crdt/vendor/yjs/src/utils/updates.js +3 -3
- package/dist/crdt/vendor/yjs/src/ynode.js +177 -12
- package/dist/dnd/autoScroll.d.ts +15 -7
- package/dist/dnd/autoScroll.js +10 -15
- package/dist/dnd/dropIndicator.js +2 -5
- package/dist/dnd/external.d.ts +6 -0
- package/dist/dnd/external.js +17 -0
- package/dist/dnd/geometry.d.ts +2 -0
- package/dist/dnd/geometry.js +3 -4
- package/dist/dnd/placement.d.ts +1 -1
- package/dist/dnd/pragmatic.d.ts +3 -1
- package/dist/dnd/pragmatic.js +12 -2
- package/dist/dnd/vendor/pragmatic/UPSTREAM.md +51 -18
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/drop-target-for-external.d.ts +4 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/drop-target-for-external.js +6 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/element-adapter.d.ts +0 -2
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/element-adapter.js +4 -22
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/external-adapter-types.d.ts +26 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/external-adapter.d.ts +30 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/external-adapter.js +203 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/get-available-items.js +13 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/get-available-types.js +9 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/is-an-available-type.js +19 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/monitor-for-external.d.ts +4 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/monitor-for-external.js +6 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/honey-pot-fix/make-honey-pot-fix.js +4 -16
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/internal-types.d.ts +1 -8
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/make-adapter/make-drop-target.js +5 -6
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/make-adapter/make-monitor.js +2 -3
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/element/custom-native-drag-preview/set-custom-native-drag-preview.d.ts +1 -1
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/element/custom-native-drag-preview/set-custom-native-drag-preview.js +6 -24
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/contains-files.d.ts +2 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/contains-files.js +5 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/get-files.d.ts +3 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/get-files.js +12 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/native-types.d.ts +12 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/changing-window/is-entering-window-in-safari.js +10 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/changing-window/is-entering-window.js +55 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/entry-point/external.d.ts +4 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/entry-point/external.js +8 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/internal-types.d.ts +0 -4
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/over-element/get-scroll-by.js +16 -72
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/over-element/try-scroll.js +1 -9
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/configuration.js +4 -29
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/get-scroll-change.js +2 -3
- package/dist/edytor.svelte.d.ts +2 -5
- package/dist/edytor.svelte.js +21 -32
- package/dist/events/beforeInputCommands.js +2 -2
- package/dist/events/onBeforeInput.js +1 -1
- package/dist/events/onDrop.d.ts +0 -6
- package/dist/events/onDrop.js +10 -23
- package/dist/events/onInput.d.ts +0 -12
- package/dist/events/onInput.js +1 -67
- package/dist/events/onPageHide.d.ts +3 -0
- package/dist/events/onPageHide.js +16 -0
- package/dist/export/forms.d.ts +627 -0
- package/dist/export/forms.js +749 -0
- package/dist/export/index.d.ts +170 -0
- package/dist/export/index.js +161 -0
- package/dist/export/markdown.d.ts +41 -0
- package/dist/export/markdown.js +585 -0
- package/dist/export/markdownWriter.d.ts +9 -0
- package/dist/export/markdownWriter.js +133 -0
- package/dist/export/mdx.d.ts +15 -0
- package/dist/export/mdx.js +33 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/kinds.js +1 -1
- package/dist/plugins/anchored.svelte.d.ts +21 -25
- package/dist/plugins/anchored.svelte.js +23 -39
- package/dist/plugins/blockHandles/BlockHandleController.svelte.js +24 -32
- package/dist/plugins/blockHandles/dragPreview.d.ts +26 -7
- package/dist/plugins/blockHandles/dragPreview.js +33 -0
- package/dist/plugins/blockMenu/BlockMenuController.svelte.d.ts +5 -0
- package/dist/plugins/blockMenu/BlockMenuController.svelte.js +7 -2
- package/dist/plugins/blockMenu/blockMenuPlugin.js +5 -50
- package/dist/plugins/chrome.d.ts +27 -5
- package/dist/plugins/chrome.js +24 -9
- package/dist/plugins/code/CodePlugin.svelte +12 -9
- package/dist/plugins/code/header.svelte.js +7 -11
- package/dist/plugins/code/languageMenu.svelte.d.ts +5 -2
- package/dist/plugins/code/languageMenu.svelte.js +13 -20
- package/dist/plugins/columns/ColumnsPlugin.svelte +7 -20
- package/dist/plugins/columns/resize.svelte.d.ts +2 -3
- package/dist/plugins/columns/resize.svelte.js +2 -5
- package/dist/plugins/comments/CommentsController.svelte.d.ts +6 -0
- package/dist/plugins/comments/CommentsController.svelte.js +20 -0
- package/dist/plugins/equation/EquationPlugin.svelte +12 -22
- package/dist/plugins/equation/equation.svelte.d.ts +7 -15
- package/dist/plugins/equation/equation.svelte.js +13 -50
- package/dist/plugins/equation/tex.d.ts +17 -0
- package/dist/plugins/equation/tex.js +42 -0
- package/dist/plugins/fileDrop.d.ts +38 -23
- package/dist/plugins/fileDrop.js +82 -76
- package/dist/plugins/find/FindController.svelte.d.ts +5 -0
- package/dist/plugins/find/FindController.svelte.js +14 -14
- package/dist/plugins/find/findPlugin.js +1 -15
- package/dist/plugins/image/ImageChrome.svelte +8 -2
- package/dist/plugins/image/ImagePlugin.svelte +15 -52
- package/dist/plugins/image/controls.svelte.js +16 -2
- package/dist/plugins/image/toolbar.svelte.d.ts +5 -4
- package/dist/plugins/image/toolbar.svelte.js +21 -31
- package/dist/plugins/index.d.ts +1 -1
- package/dist/plugins/list.svelte.d.ts +9 -0
- package/dist/plugins/list.svelte.js +18 -0
- package/dist/plugins/marquee/marqueePlugin.js +0 -4
- package/dist/plugins/media/AudioPlugin.svelte +1 -1
- package/dist/plugins/media/BookmarkPlugin.svelte +6 -97
- package/dist/plugins/media/EmbedPlugin.svelte +5 -90
- package/dist/plugins/media/EmptySlot.svelte +36 -20
- package/dist/plugins/media/EmptySlot.svelte.d.ts +6 -15
- package/dist/plugins/media/FilePlugin.svelte +1 -19
- package/dist/plugins/media/MediaEmpty.svelte +2 -55
- package/dist/plugins/media/MediaEmpty.svelte.d.ts +18 -14
- package/dist/plugins/media/SourceBlock.svelte +142 -52
- package/dist/plugins/media/SourceBlock.svelte.d.ts +10 -4
- package/dist/plugins/media/VideoPlugin.svelte +1 -1
- package/dist/plugins/media/empty.svelte.js +2 -7
- package/dist/plugins/media/media.d.ts +2 -63
- package/dist/plugins/media/media.js +1 -194
- package/dist/plugins/media/sources.d.ts +60 -0
- package/dist/plugins/media/sources.js +165 -0
- package/dist/plugins/media/urlPaste.svelte.d.ts +2 -1
- package/dist/plugins/media/urlPaste.svelte.js +12 -21
- package/dist/plugins/mention/MentionPlugin.svelte +8 -35
- package/dist/plugins/page/PagePlugin.svelte +2 -9
- package/dist/plugins/page/page.js +1 -1
- package/dist/plugins/pageLink/PageLinkPlugin.svelte +6 -13
- package/dist/plugins/richtext/RichTextPlugin.svelte +85 -197
- package/dist/plugins/richtext/body.js +1 -1
- package/dist/plugins/richtext/calloutIcons.svelte.d.ts +2 -2
- package/dist/plugins/richtext/calloutIcons.svelte.js +5 -7
- package/dist/plugins/richtext/richTextOperations.d.ts +1 -19
- package/dist/plugins/richtext/richTextOperations.js +3 -49
- package/dist/plugins/slashMenu/SlashMenuController.svelte.d.ts +2 -0
- package/dist/plugins/slashMenu/SlashMenuController.svelte.js +7 -0
- package/dist/plugins/slashMenu/slashMenuPlugin.js +5 -14
- package/dist/plugins/table/TableChrome.svelte +2 -3
- package/dist/plugins/table/TablePlugin.svelte +20 -54
- package/dist/plugins/table/chrome.svelte.d.ts +5 -2
- package/dist/plugins/table/chrome.svelte.js +30 -54
- package/dist/plugins/table/table.js +3 -3
- package/dist/plugins/toc/TocPlugin.svelte +2 -4
- package/dist/plugins/toolbar/ToolbarController.svelte.d.ts +7 -0
- package/dist/plugins/toolbar/ToolbarController.svelte.js +20 -13
- package/dist/plugins/toolbar/toolbarPlugin.js +19 -53
- package/dist/plugins/triggers/TriggerController.svelte.d.ts +7 -2
- package/dist/plugins/triggers/TriggerController.svelte.js +11 -4
- package/dist/plugins/triggers/place.js +1 -2
- package/dist/plugins/triggers/triggers.d.ts +6 -1
- package/dist/plugins/triggers/triggers.js +12 -13
- package/dist/plugins/uploads.svelte.d.ts +5 -2
- package/dist/plugins/uploads.svelte.js +25 -15
- package/dist/plugins.d.ts +26 -0
- package/dist/plugins.js +0 -24
- package/dist/selection/replaceSelection.js +2 -2
- package/dist/selection/selection.svelte.d.ts +4 -10
- package/dist/selection/selection.svelte.js +7 -11
- package/dist/session/bindings.js +1 -1
- package/dist/session/commands.d.ts +7 -11
- package/dist/session/commands.js +13 -19
- package/dist/session/inputRules.js +1 -1
- package/dist/session/navigation.js +1 -1
- package/dist/session/suggestions.svelte.d.ts +0 -11
- package/dist/session/suggestions.svelte.js +15 -3
- package/dist/session/uploads.d.ts +8 -8
- package/dist/surface/lines.js +1 -3
- package/dist/surface/observer.svelte.d.ts +17 -1
- package/dist/surface/observer.svelte.js +74 -19
- package/dist/surface/overlay.d.ts +0 -14
- package/dist/surface/overlay.js +0 -25
- package/dist/surface/projector.svelte.d.ts +15 -3
- package/dist/surface/projector.svelte.js +60 -9
- package/dist/text/text.svelte.js +3 -13
- package/dist/utils/sanitize.d.ts +38 -0
- package/dist/utils/sanitize.js +82 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +5 -0
- package/package.json +19 -2
- package/dist/crdt/placement/rank.d.ts +0 -87
- package/dist/crdt/placement/rank.js +0 -332
- package/dist/crdt/placement/source.d.ts +0 -43
- package/dist/crdt/placement/source.js +0 -66
- package/dist/crdt/text/delete-index.d.ts +0 -129
- package/dist/crdt/text/delete-index.js +0 -365
- package/dist/crdt/text/deletes.d.ts +0 -76
- package/dist/crdt/text/deletes.js +0 -362
- package/dist/crdt/text/index/anchored.d.ts +0 -17
- package/dist/crdt/text/index/anchored.js +0 -197
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/max-z-index.js +0 -3
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/supports-popover.js +0 -16
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/is-axis-allowed.js +0 -3
- package/dist/plugins/code/LanguageMenu.svelte +0 -25
- package/dist/plugins/code/LanguageMenu.svelte.d.ts +0 -9
- package/dist/plugins/equation/EquationEditor.svelte +0 -27
- package/dist/plugins/equation/EquationEditor.svelte.d.ts +0 -9
- package/dist/plugins/image/ImageToolbarHost.svelte +0 -37
- package/dist/plugins/image/ImageToolbarHost.svelte.d.ts +0 -9
- package/dist/plugins/richtext/CalloutIconPicker.svelte +0 -26
- package/dist/plugins/richtext/CalloutIconPicker.svelte.d.ts +0 -9
|
@@ -1,362 +0,0 @@
|
|
|
1
|
-
import { CONTENT_NODE, HORIZON_ROOT, INLINE_NODE, RESTORED_ROOT, TEXT_DELETES_ROOT } from '../schema.js';
|
|
2
|
-
import { attrItems, clientsOf, dropSearchMarkers, engineOps, firstItem, keepFromCollection, nextClock, onTransaction, stepsOf, structAt, walkIdSet } from '../structs.js';
|
|
3
|
-
import { clip, decode, deleteIndex, encode, FOLD_SPANS, keyOf, mergeSpans, overlaps } from './delete-index.js';
|
|
4
|
-
const REACT = Symbol('edytor.text-deletes');
|
|
5
|
-
const states = new WeakMap();
|
|
6
|
-
export const bindDeletes = (Y) => {
|
|
7
|
-
const { idSet, each, rootSpans, members, liveRoots, shown, indexOf, leaves, holders, minus, parts, addCopies, indexRecord, indexMark, recordsIn, sync } = deleteIndex(Y);
|
|
8
|
-
const ops = engineOps(Y);
|
|
9
|
-
const attach = (doc) => {
|
|
10
|
-
let s = states.get(doc);
|
|
11
|
-
if (s !== undefined)
|
|
12
|
-
return s;
|
|
13
|
-
s = {
|
|
14
|
-
doc: doc,
|
|
15
|
-
marks: doc.get(TEXT_DELETES_ROOT),
|
|
16
|
-
restored: doc.get(RESTORED_ROOT),
|
|
17
|
-
horizon: doc.get(HORIZON_ROOT),
|
|
18
|
-
held: new Map(),
|
|
19
|
-
holds: new Map(),
|
|
20
|
-
copies: new Map(),
|
|
21
|
-
byRoot: new Map(),
|
|
22
|
-
byOrigin: new Map(),
|
|
23
|
-
copyKeys: new Set(),
|
|
24
|
-
policies: new Set(),
|
|
25
|
-
lastMark: null
|
|
26
|
-
};
|
|
27
|
-
states.set(doc, s);
|
|
28
|
-
const st = s;
|
|
29
|
-
const records = (node, fn) => {
|
|
30
|
-
for (let it = firstItem(node); it; it = it.right)
|
|
31
|
-
if (!it.deleted)
|
|
32
|
-
for (const [r, bytes] of recordsIn(it, null))
|
|
33
|
-
fn(r, bytes);
|
|
34
|
-
};
|
|
35
|
-
attrItems(st.restored).forEach((it) => {
|
|
36
|
-
// A record the purge deleted names nothing any more.
|
|
37
|
-
if (!it.deleted)
|
|
38
|
-
for (const [r, bytes] of recordsIn(it, null))
|
|
39
|
-
indexRecord(st, r, bytes);
|
|
40
|
-
});
|
|
41
|
-
records(st.marks, (r, bytes) => indexMark(st, r, bytes));
|
|
42
|
-
// A deleted copy may have to be copied again by any replica (holds,
|
|
43
|
-
// duplicates, pending characters): garbage collection keeps its content.
|
|
44
|
-
const copy = (it) => it != null &&
|
|
45
|
-
(st.copies.get(it.id.client) ?? []).some((e) => overlaps(e, { k: it.id.clock, n: it.length }));
|
|
46
|
-
// (an inline atom copy keeps its attributes too)
|
|
47
|
-
keepFromCollection(doc, (it) => !copy(it) && !copy(it.parent?._item));
|
|
48
|
-
onTransaction(doc, 'afterTransaction', (tr) => react(st, tr));
|
|
49
|
-
return st;
|
|
50
|
-
};
|
|
51
|
-
// ── the writes ─────────────────────────────────────────────────────
|
|
52
|
-
/** Delete the live ids `live` (split at their edges); `into` a step, kept for its undo. */
|
|
53
|
-
const remove = (tr, live, into, keep = into !== undefined) => {
|
|
54
|
-
if (live.length === 0)
|
|
55
|
-
return;
|
|
56
|
-
each(tr, live, (it) => {
|
|
57
|
-
if (it.deleted)
|
|
58
|
-
return;
|
|
59
|
-
it.delete(tr);
|
|
60
|
-
dropSearchMarkers(it.parent);
|
|
61
|
-
if (keep)
|
|
62
|
-
it.keep = true;
|
|
63
|
-
});
|
|
64
|
-
if (into !== undefined)
|
|
65
|
-
ops.insertInto(into.deletes, idSet(live));
|
|
66
|
-
};
|
|
67
|
-
/** Restore root span `r` by copying its leaves; writes the restoration record. */
|
|
68
|
-
const restore = (s, p, tr, r) => {
|
|
69
|
-
const rows = [];
|
|
70
|
-
const copies = [];
|
|
71
|
-
for (const leaf of leaves(s, r)) {
|
|
72
|
-
const items = [];
|
|
73
|
-
each(tr, [leaf], (it) => void (it.deleted && items.push(it)));
|
|
74
|
-
for (const it of items) {
|
|
75
|
-
// A leaf has no copy: a local `redone` link left by an earlier
|
|
76
|
-
// restoration points at a copy this lineage no longer shows.
|
|
77
|
-
it.redone = null;
|
|
78
|
-
const copy = ops.redo(tr, it, new Set([it]));
|
|
79
|
-
if (copy === null)
|
|
80
|
-
continue;
|
|
81
|
-
dropSearchMarkers(copy.parent);
|
|
82
|
-
// An inline atom comes back with its attributes: they were deleted with
|
|
83
|
-
// it and are re-created into the copy (their parent's `redone`).
|
|
84
|
-
const attrs = it.content.type?._map;
|
|
85
|
-
if (attrs !== undefined) {
|
|
86
|
-
const kids = [...attrs.values()].filter((c) => c.deleted);
|
|
87
|
-
for (const kid of kids)
|
|
88
|
-
ops.redo(tr, kid, new Set(kids));
|
|
89
|
-
}
|
|
90
|
-
const e = {
|
|
91
|
-
c: copy.id.client,
|
|
92
|
-
k: copy.id.clock,
|
|
93
|
-
n: it.length,
|
|
94
|
-
rc: r.c,
|
|
95
|
-
rk: leaf.rk + it.id.clock - leaf.k,
|
|
96
|
-
oc: it.id.client,
|
|
97
|
-
ok: it.id.clock
|
|
98
|
-
};
|
|
99
|
-
rows.push([e.k, e.n, e.rc, e.rk, e.oc, e.ok]);
|
|
100
|
-
copies.push(e);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
if (rows.length === 0)
|
|
104
|
-
return;
|
|
105
|
-
// One key per record (its own id): a map entry depends on nothing, so
|
|
106
|
-
// the record integrates with the copies it names, before collection.
|
|
107
|
-
const next = nextClock(s.doc, s.doc.clientID);
|
|
108
|
-
s.restored.setAttr(`${s.doc.clientID.toString(36)}.${next.toString(36)}`, encode(rows));
|
|
109
|
-
addCopies(s, copies);
|
|
110
|
-
};
|
|
111
|
-
/**
|
|
112
|
-
* Keep root spans `roots` visible for `p`: restore what nothing shows and
|
|
113
|
-
* no mark (but those `skip` names) holds; return the rest, which `p`
|
|
114
|
-
* watches — unless this replica's own copy shows it. `done` collects what
|
|
115
|
-
* this pass restored (once per character).
|
|
116
|
-
*/
|
|
117
|
-
const settle = (s, p, tr, roots, skip, done = []) => {
|
|
118
|
-
const watch = [];
|
|
119
|
-
for (const r of roots)
|
|
120
|
-
for (const part of minus(r, done).flatMap((x) => parts(s, x))) {
|
|
121
|
-
const live = shown(s, [part]);
|
|
122
|
-
if (live.length > 0) {
|
|
123
|
-
if (live.some((l) => l.c !== s.doc.clientID))
|
|
124
|
-
watch.push(part);
|
|
125
|
-
}
|
|
126
|
-
else if (holders(s, part, skip).length > 0)
|
|
127
|
-
watch.push(part);
|
|
128
|
-
else {
|
|
129
|
-
restore(s, p, tr, part);
|
|
130
|
-
done.push(part);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
return watch;
|
|
134
|
-
};
|
|
135
|
-
/** The undo step of this replica that wrote `mark`. */
|
|
136
|
-
const stepOf = (s, mark) => {
|
|
137
|
-
for (const p of s.policies)
|
|
138
|
-
for (const step of stepsOf(p.um().undoStack))
|
|
139
|
-
if (step.inserts.has(mark.client, mark.clock))
|
|
140
|
-
return step;
|
|
141
|
-
return undefined;
|
|
142
|
-
};
|
|
143
|
-
/** This replica's live marks hide what the copies `copies` show, in their steps. */
|
|
144
|
-
const hold = (s, tr, copies) => {
|
|
145
|
-
for (const e of copies) {
|
|
146
|
-
const r = { c: e.rc, k: e.rk, n: e.n };
|
|
147
|
-
for (const mark of holders(s, r, (m) => m.client !== s.doc.clientID)) {
|
|
148
|
-
const roots = (s.holds.get(keyOf(mark)) ?? []).flatMap((h) => {
|
|
149
|
-
const lo = Math.max(h.k, r.k);
|
|
150
|
-
const hi = Math.min(h.k + h.n, r.k + r.n);
|
|
151
|
-
return h.c === r.c && hi > lo ? [{ c: r.c, k: lo, n: hi - lo }] : [];
|
|
152
|
-
});
|
|
153
|
-
remove(tr, shown(s, roots), stepOf(s, mark));
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
};
|
|
157
|
-
/**
|
|
158
|
-
* Delete this replica's copies of characters another copy shows further
|
|
159
|
-
* left (and watch them). The leftmost copy wins: a copy sits right before
|
|
160
|
-
* the member it restored, so keeping the leftmost keeps restored text in
|
|
161
|
-
* order whichever restorations overlapped.
|
|
162
|
-
*/
|
|
163
|
-
const dedupe = (s, tr, copies) => {
|
|
164
|
-
const doomed = [];
|
|
165
|
-
for (const e of copies) {
|
|
166
|
-
const ms = members(s, { c: e.rc, k: e.rk, n: e.n });
|
|
167
|
-
const live = ms.flatMap((m) => liveRoots(s, m).map((p) => clip(m, p.k, p.k + p.n)));
|
|
168
|
-
for (const o of live) {
|
|
169
|
-
if (o.c !== s.doc.clientID)
|
|
170
|
-
continue;
|
|
171
|
-
for (let rk = o.rk; rk < o.rk + o.n; rk++) {
|
|
172
|
-
const k = o.k + rk - o.rk;
|
|
173
|
-
const at = indexOf(s, o.c, k);
|
|
174
|
-
const left = live.some((m) => m !== o && m.rk <= rk && rk < m.rk + m.n && indexOf(s, m.c, m.k + rk - m.rk) < at);
|
|
175
|
-
if (left)
|
|
176
|
-
doomed.push({ c: o.c, k, n: 1 });
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
remove(tr, doomed, undefined, true);
|
|
181
|
-
const [p] = s.policies;
|
|
182
|
-
for (const d of doomed)
|
|
183
|
-
p.watch.push(...rootSpans(s, d));
|
|
184
|
-
};
|
|
185
|
-
/** Whether `tr` deleted a member of a character some history watches. */
|
|
186
|
-
const watchedDied = (s, tr) => [...s.policies].some((p) => p.watch.some((w) => members(s, w).some((m) => tr.deleteSet.intersects(m.c, m.k, m.n))));
|
|
187
|
-
/** After every commit: index its records; after a remote one, keep this replica's facts. */
|
|
188
|
-
const react = (s, tr) => {
|
|
189
|
-
const fresh = sync(s, tr);
|
|
190
|
-
// A purge deletes marks past the horizon: nothing comes back for
|
|
191
|
-
// it, and a pending character only they held stays deleted.
|
|
192
|
-
if (tr.changed.has(s.horizon)) {
|
|
193
|
-
for (const p of s.policies)
|
|
194
|
-
p.watch = p.watch.filter((w) => holders(s, w).length > 0 || shown(s, [w]).length > 0);
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
197
|
-
if (tr.local || s.policies.size === 0)
|
|
198
|
-
return;
|
|
199
|
-
if (fresh.copies.length === 0 && !fresh.released && !watchedDied(s, tr))
|
|
200
|
-
return;
|
|
201
|
-
s.doc.transact((t) => {
|
|
202
|
-
hold(s, t, fresh.copies);
|
|
203
|
-
dedupe(s, t, fresh.copies);
|
|
204
|
-
for (const p of s.policies)
|
|
205
|
-
p.watch = settle(s, p, t, p.watch);
|
|
206
|
-
}, REACT);
|
|
207
|
-
};
|
|
208
|
-
/**
|
|
209
|
-
* The spans of this writer's last record merged with `spans`, when a
|
|
210
|
-
* delete may fold into it — it is the records list's last element, live,
|
|
211
|
-
* this replica's, written in this transaction or in the step still
|
|
212
|
-
* capturing (`open`: the history steps whose capture group is open), or
|
|
213
|
-
* anywhere when no history records steps here; and the merged record
|
|
214
|
-
* stays small ({@link FOLD_SPANS}). `null`: write a record of its own.
|
|
215
|
-
*/
|
|
216
|
-
const foldInto = (s, tr, open, spans) => {
|
|
217
|
-
const at = s.lastMark;
|
|
218
|
-
if (at === null || at.c !== s.doc.clientID)
|
|
219
|
-
return null;
|
|
220
|
-
const last = structAt(Y, clientsOf(s.doc).get(at.c) ?? [], at.k);
|
|
221
|
-
if (last === null ||
|
|
222
|
-
last.deleted ||
|
|
223
|
-
last.parent !== s.marks ||
|
|
224
|
-
last.right !== null ||
|
|
225
|
-
last.id.clock + last.length - 1 !== at.k)
|
|
226
|
-
return null;
|
|
227
|
-
const same = tr?.insertSet.has(at.c, at.k) === true ||
|
|
228
|
-
open.some((ids) => ids.has(at.c, at.k)) ||
|
|
229
|
-
s.policies.size === 0;
|
|
230
|
-
if (!same)
|
|
231
|
-
return null;
|
|
232
|
-
const [, bytes] = recordsIn(last, null).at(-1) ?? [];
|
|
233
|
-
if (bytes === undefined)
|
|
234
|
-
return null;
|
|
235
|
-
const merged = mergeSpans([...decode(bytes, 3).map(([c, k, n]) => ({ c, k, n })), ...spans]);
|
|
236
|
-
return merged.length <= FOLD_SPANS ? merged : null;
|
|
237
|
-
};
|
|
238
|
-
/**
|
|
239
|
-
* Delete this replica's last record (the list's tail, {@link foldInto})
|
|
240
|
-
* and append `bytes` right after it, by item: no index walk over the
|
|
241
|
-
* list's tombstones. The list's search markers are dropped (their
|
|
242
|
-
* positions no longer hold).
|
|
243
|
-
*/
|
|
244
|
-
const replaceLast = (s, tr, bytes) => {
|
|
245
|
-
const at = s.lastMark;
|
|
246
|
-
const tail = ops.cleanStart(tr, at.c, at.k);
|
|
247
|
-
tail.delete(tr);
|
|
248
|
-
dropSearchMarkers(s.marks);
|
|
249
|
-
const client = s.doc.clientID;
|
|
250
|
-
ops.appendAfter(tr, tail, s.marks, client, nextClock(s.doc, client), [bytes]);
|
|
251
|
-
};
|
|
252
|
-
/** The text units `ids` names, as spans. */
|
|
253
|
-
const unitsIn = (s, ids) => {
|
|
254
|
-
const out = [];
|
|
255
|
-
walkIdSet(Y, s.doc, ids, (st, lo, hi) => {
|
|
256
|
-
if (hi > lo && isUnit(st))
|
|
257
|
-
out.push({ c: st.id.client, k: lo, n: hi - lo });
|
|
258
|
-
});
|
|
259
|
-
return out;
|
|
260
|
-
};
|
|
261
|
-
/** A text unit a mark can hold: a character or inline atom of a backing text. */
|
|
262
|
-
const isUnit = (it) => it.parentSub === null &&
|
|
263
|
-
it.parent?.name === CONTENT_NODE &&
|
|
264
|
-
(typeof it.content?.str === 'string' || it.content?.type?.name === INLINE_NODE);
|
|
265
|
-
return {
|
|
266
|
-
/** The history's extra scope: the marks (an undo removes its own). */
|
|
267
|
-
scope: (doc) => attach(doc).marks,
|
|
268
|
-
/**
|
|
269
|
-
* Mark `spans` (the characters a text delete just deleted, inside its
|
|
270
|
-
* transaction) as this writer's, and hide their other visible copies.
|
|
271
|
-
*/
|
|
272
|
-
markDeleted: (doc, deleted) => {
|
|
273
|
-
const s = attach(doc);
|
|
274
|
-
// Text inserted and deleted within one open capture group never comes
|
|
275
|
-
// back by that step's undo (the engine skips such a step): no mark.
|
|
276
|
-
const fresh = [...s.policies].flatMap((p) => {
|
|
277
|
-
const um = p.um();
|
|
278
|
-
const top = stepsOf(um.undoStack).at(-1);
|
|
279
|
-
const open = top !== undefined &&
|
|
280
|
-
!um.undoing &&
|
|
281
|
-
!um.redoing &&
|
|
282
|
-
um.lastChange > 0 &&
|
|
283
|
-
Date.now() - um.lastChange < um.captureTimeout;
|
|
284
|
-
return open ? [top.inserts] : [];
|
|
285
|
-
});
|
|
286
|
-
const tr = s.doc._transaction;
|
|
287
|
-
const spans = deleted.flatMap((sp) => {
|
|
288
|
-
const out = [];
|
|
289
|
-
for (let k = sp.k; k < sp.k + sp.n; k++) {
|
|
290
|
-
if (fresh.some((ids) => ids.has(sp.c, k)))
|
|
291
|
-
continue;
|
|
292
|
-
const last = out[out.length - 1];
|
|
293
|
-
if (last !== undefined && last.k + last.n === k)
|
|
294
|
-
last.n++;
|
|
295
|
-
else
|
|
296
|
-
out.push({ c: sp.c, k, n: 1 });
|
|
297
|
-
}
|
|
298
|
-
return out;
|
|
299
|
-
});
|
|
300
|
-
if (spans.length === 0)
|
|
301
|
-
return;
|
|
302
|
-
// A delete in the step that wrote this writer's last record
|
|
303
|
-
// (a backspace run) folds into it, its spans merged — one record per
|
|
304
|
-
// step, not per keystroke. The record is replaced (deleted and
|
|
305
|
-
// written again), never edited, so an undo of the step still takes
|
|
306
|
-
// back exactly what the step deleted.
|
|
307
|
-
const folded = tr === null ? null : foldInto(s, tr, fresh, spans);
|
|
308
|
-
const k = nextClock(s.doc, s.doc.clientID);
|
|
309
|
-
const bytes = encode((folded ?? spans).map((sp) => [sp.c, sp.k, sp.n]));
|
|
310
|
-
if (folded === null)
|
|
311
|
-
s.marks.insert(s.marks.length, [bytes]);
|
|
312
|
-
else
|
|
313
|
-
replaceLast(s, tr, bytes);
|
|
314
|
-
s.lastMark = { c: s.doc.clientID, k };
|
|
315
|
-
if (tr !== null)
|
|
316
|
-
remove(tr, shown(s, spans.flatMap((sp) => rootSpans(s, sp))));
|
|
317
|
-
},
|
|
318
|
-
/** A doc's index of marks and copies, and the delete the purge writes (`purge.ts`). */
|
|
319
|
-
state: attach,
|
|
320
|
-
remove,
|
|
321
|
-
/** The restore and apply rules of a history on `doc` (`doc/history.ts`). */
|
|
322
|
-
history: (doc, um) => {
|
|
323
|
-
const s = attach(doc);
|
|
324
|
-
const p = { um, watch: [], tr: null, units: [] };
|
|
325
|
-
s.policies.add(p);
|
|
326
|
-
const current = () => {
|
|
327
|
-
const tr = s.doc._transaction;
|
|
328
|
-
if (p.tr !== tr)
|
|
329
|
-
Object.assign(p, { tr, units: [] });
|
|
330
|
-
return p;
|
|
331
|
-
};
|
|
332
|
-
return {
|
|
333
|
-
/** Text units are restored by `onApply`, character by character. */
|
|
334
|
-
restoreFilter: (item) => {
|
|
335
|
-
const it = item;
|
|
336
|
-
if (!isUnit(it))
|
|
337
|
-
return true;
|
|
338
|
-
current().units.push({ c: it.id.client, k: it.id.clock, n: it.length });
|
|
339
|
-
return false;
|
|
340
|
-
},
|
|
341
|
-
onApply: (transaction, stackItem) => {
|
|
342
|
-
const tr = transaction;
|
|
343
|
-
const q = current();
|
|
344
|
-
const step = stackItem;
|
|
345
|
-
const fresh = sync(s, tr);
|
|
346
|
-
const roots = q.units.flatMap((u) => rootSpans(s, u));
|
|
347
|
-
const ours = (m) => step.inserts.has(m.client, m.clock);
|
|
348
|
-
q.watch.push(...settle(s, q, tr, roots, ours));
|
|
349
|
-
// A redo writes its marks again: they hide what shows their characters.
|
|
350
|
-
const held = fresh.marks.flatMap((m) => s.holds.get(keyOf(m)) ?? []);
|
|
351
|
-
remove(tr, shown(s, held));
|
|
352
|
-
// Text the step deleted that no mark of it holds (an undo of typing) is
|
|
353
|
-
// this writer's delete too.
|
|
354
|
-
const bare = unitsIn(s, tr.deleteSet).filter((u) => rootSpans(s, u).some((r) => !held.some((h) => h.c === r.c && h.k <= r.k && r.k + r.n <= h.k + h.n)));
|
|
355
|
-
if (bare.length > 0)
|
|
356
|
-
s.marks.insert(s.marks.length, [encode(bare.map((u) => [u.c, u.k, u.n]))]);
|
|
357
|
-
q.units = [];
|
|
358
|
-
}
|
|
359
|
-
};
|
|
360
|
-
}
|
|
361
|
-
};
|
|
362
|
-
};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Anchored merge claims (`merge.claim.anchor`): the effective claimer of
|
|
3
|
-
* each claim a split its writer did not see moves to the piece that ends
|
|
4
|
-
* its region, re-decided after each fold's texts.
|
|
5
|
-
*/
|
|
6
|
-
import type { BlockId } from '../../placement/model.js';
|
|
7
|
-
import { type Claim } from '../model.js';
|
|
8
|
-
import type { IndexClaims } from './claims.js';
|
|
9
|
-
import type { FoldCtx, IndexState } from './state.js';
|
|
10
|
-
/** The anchored merge claims of one doc's index, over its state and claim graph. */
|
|
11
|
-
export declare const indexAnchored: (ix: IndexState & IndexClaims) => {
|
|
12
|
-
sameClaims: (x: readonly Claim[], y: readonly Claim[]) => boolean;
|
|
13
|
-
effectiveClaims: (b: BlockId, list: readonly Claim[]) => Claim[];
|
|
14
|
-
targetOf: (holder: BlockId, c: Claim) => [BlockId];
|
|
15
|
-
applyRetargets: (ctx: FoldCtx | null) => void;
|
|
16
|
-
};
|
|
17
|
-
export type IndexAnchored = ReturnType<typeof indexAnchored>;
|
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
import { storeOf } from '../../structs.js';
|
|
2
|
-
import { cmpStamp, isBoundary } from '../model.js';
|
|
3
|
-
import { gapOfItem, headOf, segmentOfCut, segmentOfGap } from '../rows.js';
|
|
4
|
-
import { addTo, dropFrom } from './shared.js';
|
|
5
|
-
/** The anchored merge claims of one doc's index, over its state and claim graph. */
|
|
6
|
-
export const indexAnchored = (ix) => {
|
|
7
|
-
const { doc, blocks, rows, streamIx, homeOfText, attachOf, foreignOf, anchoredIn, retargets, unresolved, reclaim, noteClaims, invalidateBlock } = ix;
|
|
8
|
-
// ── anchored merge claims (`merge.claim.anchor`) ──
|
|
9
|
-
// A claim written since 0.1.0-next.26 carries the end of its holder's
|
|
10
|
-
// stream as its writer saw it (`a`: the last unit, `r`: the item after
|
|
11
|
-
// it). A split the writer did not see moves it to the piece that ends
|
|
12
|
-
// that region: its EFFECTIVE claimer is the block of the segment just
|
|
13
|
-
// before `r` (the text's last segment when `r` is null), if that is
|
|
14
|
-
// the holder's segment or one after it in the holder's row. Records
|
|
15
|
-
// carry their list (`listClaims`) and their effective claims
|
|
16
|
-
// (`claims`: their own that stay, then those other holders' anchors
|
|
17
|
-
// move to them, by stamp); every reader of claims reads the effective
|
|
18
|
-
// ones. Targets change only with a row's cuts: re-decided after each
|
|
19
|
-
// fold's texts for the holders whose record changed and those anchored
|
|
20
|
-
// in a re-placed row.
|
|
21
|
-
const anchorHomes = new Map();
|
|
22
|
-
const sameClaims = (x, y) => x.length === y.length &&
|
|
23
|
-
x.every((c, i) => c.m === y[i].m &&
|
|
24
|
-
c.holder === y[i].holder &&
|
|
25
|
-
c.seqIndex === y[i].seqIndex &&
|
|
26
|
-
cmpStamp(c.stamp, y[i].stamp) === 0);
|
|
27
|
-
/** `b`'s effective claims: its own that stay with it, then the others' moved to it, by stamp. */
|
|
28
|
-
function effectiveClaims(b, list) {
|
|
29
|
-
const targets = attachOf.get(b);
|
|
30
|
-
const own = targets === undefined ? list : list.filter((_, i) => (targets[i] ?? b) === b);
|
|
31
|
-
const holders = foreignOf.get(b);
|
|
32
|
-
if (holders === undefined)
|
|
33
|
-
return own;
|
|
34
|
-
const moved = [];
|
|
35
|
-
for (const h of holders) {
|
|
36
|
-
const hr = blocks.get(h);
|
|
37
|
-
const ts = attachOf.get(h);
|
|
38
|
-
if (hr === undefined || ts === undefined)
|
|
39
|
-
continue;
|
|
40
|
-
(hr.listClaims ?? hr.claims).forEach((c, i) => {
|
|
41
|
-
if (ts[i] === b)
|
|
42
|
-
moved.push({ ...c, holder: h });
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
moved.sort((x, y) => cmpStamp(x.stamp, y.stamp));
|
|
46
|
-
return [...own, ...moved];
|
|
47
|
-
}
|
|
48
|
-
const store = storeOf(doc);
|
|
49
|
-
/** The struct holding unit `ref`, and the unit's offset in it (`null`: none held). */
|
|
50
|
-
const unitAt = (ref) => {
|
|
51
|
-
if (store.getClock(ref.c) <= ref.k)
|
|
52
|
-
return null;
|
|
53
|
-
const s = store.getItem({ client: ref.c, clock: ref.k });
|
|
54
|
-
if (s?.parent === undefined || s.parent === null)
|
|
55
|
-
return null;
|
|
56
|
-
return [s, ref.k - s.id.clock];
|
|
57
|
-
};
|
|
58
|
-
/** The gap of row `row` unit `off` of `it` lies in (`-1`: stale, the walk met an unknown boundary). */
|
|
59
|
-
const gapOfUnit = (row, it, off) => {
|
|
60
|
-
const arr = it.content?.arr;
|
|
61
|
-
if (!it.deleted && it.countable !== false && arr !== undefined) {
|
|
62
|
-
const key = (k) => row.keyIndex.get(`${it.id.client}:${it.id.clock + k}`);
|
|
63
|
-
for (let k = off; k >= 0; k--)
|
|
64
|
-
if (isBoundary(arr[k])) {
|
|
65
|
-
const j = key(k);
|
|
66
|
-
if (j === undefined)
|
|
67
|
-
return -1;
|
|
68
|
-
// The unit itself, a boundary: the units before it.
|
|
69
|
-
return k === off ? j : j + 1;
|
|
70
|
-
}
|
|
71
|
-
for (let k = off + 1; k < it.length; k++)
|
|
72
|
-
if (isBoundary(arr[k])) {
|
|
73
|
-
const j = key(k);
|
|
74
|
-
return j === undefined ? -1 : j;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return gapOfItem(row, it);
|
|
78
|
-
};
|
|
79
|
-
/** The effective claimer of `holder`'s claim `c`. */
|
|
80
|
-
const targetOf = (holder, c) => {
|
|
81
|
-
if (c.a === undefined)
|
|
82
|
-
return [holder];
|
|
83
|
-
const at = streamIx.get(holder);
|
|
84
|
-
const row = at && rows.get(at.home);
|
|
85
|
-
if (row === undefined)
|
|
86
|
-
return [holder];
|
|
87
|
-
const a = unitAt(c.a);
|
|
88
|
-
if (a === null || a[0].parent !== row.text)
|
|
89
|
-
return [holder];
|
|
90
|
-
const k0 = segmentOfCut(row, at.cut);
|
|
91
|
-
let gap = row.bounds.length;
|
|
92
|
-
if (c.r != null) {
|
|
93
|
-
const r = unitAt(c.r);
|
|
94
|
-
if (r === null || r[0].parent !== row.text)
|
|
95
|
-
return [holder];
|
|
96
|
-
gap = gapOfUnit(row, r[0], r[1]);
|
|
97
|
-
}
|
|
98
|
-
if (k0 < 0 || gap < 0)
|
|
99
|
-
return [holder];
|
|
100
|
-
const k = segmentOfGap(row, gap);
|
|
101
|
-
const target = k < k0 ? null : headOf(row, k);
|
|
102
|
-
return [target ?? holder];
|
|
103
|
-
};
|
|
104
|
-
/**
|
|
105
|
-
* The rows whose placement may move `holder`'s anchored claim `c`: its
|
|
106
|
-
* stream's and its anchor's text's. `null` while it is unresolved — the
|
|
107
|
-
* holder has no stream, or an anchor names a unit not integrated yet
|
|
108
|
-
* (a payload is no dependency: the claim can arrive first) — and
|
|
109
|
-
* re-decided at every fold.
|
|
110
|
-
*/
|
|
111
|
-
const watchOf = (holder, c) => {
|
|
112
|
-
if (c.a !== undefined && unitAt(c.a) === null)
|
|
113
|
-
return null;
|
|
114
|
-
if (c.r != null && unitAt(c.r) === null)
|
|
115
|
-
return null;
|
|
116
|
-
const homes = [];
|
|
117
|
-
const own = streamIx.get(holder)?.home;
|
|
118
|
-
if (own !== undefined)
|
|
119
|
-
homes.push(own);
|
|
120
|
-
const a = c.a === undefined ? null : unitAt(c.a);
|
|
121
|
-
const text = a === null ? undefined : homeOfText.get(a[0].parent);
|
|
122
|
-
if (text !== undefined && text !== own)
|
|
123
|
-
homes.push(text);
|
|
124
|
-
return homes.length === 0 ? null : homes;
|
|
125
|
-
};
|
|
126
|
-
/**
|
|
127
|
-
* The retarget pass: re-decide the targets of the holders queued, move
|
|
128
|
-
* their claims between effective claimers, and re-read the claims of
|
|
129
|
-
* every block that gained or lost one (its claim facts and readers).
|
|
130
|
-
*/
|
|
131
|
-
const applyRetargets = (ctx) => {
|
|
132
|
-
for (const h of retargets) {
|
|
133
|
-
const rec = blocks.get(h);
|
|
134
|
-
const before = attachOf.get(h);
|
|
135
|
-
for (const home of anchorHomes.get(h) ?? [])
|
|
136
|
-
dropFrom(anchoredIn, home, h);
|
|
137
|
-
anchorHomes.delete(h);
|
|
138
|
-
let after;
|
|
139
|
-
unresolved.delete(h);
|
|
140
|
-
for (const [i, c] of (rec?.listClaims ?? []).entries()) {
|
|
141
|
-
if (c.a === undefined)
|
|
142
|
-
continue;
|
|
143
|
-
const [t] = targetOf(h, c);
|
|
144
|
-
const watch = watchOf(h, c);
|
|
145
|
-
if (watch === null)
|
|
146
|
-
unresolved.add(h);
|
|
147
|
-
else
|
|
148
|
-
for (const home of watch) {
|
|
149
|
-
addTo(anchoredIn, home, h);
|
|
150
|
-
addTo(anchorHomes, h, home);
|
|
151
|
-
}
|
|
152
|
-
if (t !== h)
|
|
153
|
-
(after ??= new Array((rec.listClaims ?? []).length).fill(h))[i] = t;
|
|
154
|
-
}
|
|
155
|
-
const was = new Set(before ?? []);
|
|
156
|
-
const now = new Set(after ?? []);
|
|
157
|
-
for (const t of was)
|
|
158
|
-
if (t !== h && !now.has(t))
|
|
159
|
-
dropFrom(foreignOf, t, h);
|
|
160
|
-
for (const t of now)
|
|
161
|
-
if (t !== h)
|
|
162
|
-
addTo(foreignOf, t, h);
|
|
163
|
-
if (after === undefined)
|
|
164
|
-
attachOf.delete(h);
|
|
165
|
-
else
|
|
166
|
-
attachOf.set(h, after);
|
|
167
|
-
if (before !== undefined || after !== undefined) {
|
|
168
|
-
reclaim.add(h);
|
|
169
|
-
for (const t of was)
|
|
170
|
-
reclaim.add(t);
|
|
171
|
-
for (const t of now)
|
|
172
|
-
reclaim.add(t);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
retargets.clear();
|
|
176
|
-
for (const b of reclaim) {
|
|
177
|
-
const rec = blocks.get(b);
|
|
178
|
-
if (rec === undefined)
|
|
179
|
-
continue;
|
|
180
|
-
const before = rec.claims;
|
|
181
|
-
const after = effectiveClaims(b, rec.listClaims ?? before);
|
|
182
|
-
if (sameClaims(before, after))
|
|
183
|
-
continue;
|
|
184
|
-
rec.claims = after;
|
|
185
|
-
noteClaims(b, before, after);
|
|
186
|
-
if (ctx !== null)
|
|
187
|
-
invalidateBlock(b, ctx, before);
|
|
188
|
-
}
|
|
189
|
-
reclaim.clear();
|
|
190
|
-
};
|
|
191
|
-
return {
|
|
192
|
-
sameClaims,
|
|
193
|
-
effectiveClaims,
|
|
194
|
-
targetOf,
|
|
195
|
-
applyRetargets
|
|
196
|
-
};
|
|
197
|
-
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { once } from '../public-utils/once.js';
|
|
2
|
-
|
|
3
|
-
// Using `once` as the value won't change in a browser
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Returns `true` if the browser supports the Popover API (top-layer).
|
|
7
|
-
*
|
|
8
|
-
* When supported, elements with `popover="manual"` can be promoted to the
|
|
9
|
-
* browser's top layer via `element.showPopover()`, which is more reliable
|
|
10
|
-
* than `z-index` for ensuring an element renders above everything else.
|
|
11
|
-
*
|
|
12
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/Popover_API
|
|
13
|
-
*/
|
|
14
|
-
export const supportsPopover = once(function supportsPopover() {
|
|
15
|
-
return typeof HTMLElement !== 'undefined' && typeof HTMLElement.prototype.showPopover === 'function';
|
|
16
|
-
});
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { Snippet } from 'svelte';
|
|
3
|
-
import type { LanguageMenu } from './languageMenu.svelte.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* The code language list (`LanguageMenu`), in the overlay under the
|
|
7
|
-
* language button of its block: the plugin's `menu` snippet, placed. Its
|
|
8
|
-
* keys and ARIA are the controller's attachments (`keys`, `popup`,
|
|
9
|
-
* `option(index)`).
|
|
10
|
-
*/
|
|
11
|
-
let { menu, snippet }: { menu: LanguageMenu; snippet: Snippet<[LanguageMenu]> } = $props();
|
|
12
|
-
|
|
13
|
-
const place = $derived(menu.open && menu.panel.place(4));
|
|
14
|
-
</script>
|
|
15
|
-
|
|
16
|
-
{#if place}
|
|
17
|
-
<div
|
|
18
|
-
data-edytor-code-language-panel
|
|
19
|
-
style:position="absolute"
|
|
20
|
-
style:left="{place.left}px"
|
|
21
|
-
style:top="{place.top}px"
|
|
22
|
-
>
|
|
23
|
-
{@render snippet(menu)}
|
|
24
|
-
</div>
|
|
25
|
-
{/if}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { Snippet } from 'svelte';
|
|
2
|
-
import type { LanguageMenu } from './languageMenu.svelte.js';
|
|
3
|
-
type $$ComponentProps = {
|
|
4
|
-
menu: LanguageMenu;
|
|
5
|
-
snippet: Snippet<[LanguageMenu]>;
|
|
6
|
-
};
|
|
7
|
-
declare const LanguageMenu: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
8
|
-
type LanguageMenu = ReturnType<typeof LanguageMenu>;
|
|
9
|
-
export default LanguageMenu;
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { Snippet } from 'svelte';
|
|
3
|
-
import type { EquationEditor } from './equation.svelte.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* The equation editor (`EquationEditor`), in the overlay under the edited
|
|
7
|
-
* equation (Notion's), centered under a block one: the plugin's `panel`
|
|
8
|
-
* snippet, placed. It takes the field's focus and keys through the
|
|
9
|
-
* controller's attachment (`field`).
|
|
10
|
-
*/
|
|
11
|
-
let { editor, panel }: { editor: EquationEditor; panel: Snippet<[EquationEditor]> } = $props();
|
|
12
|
-
|
|
13
|
-
const place = $derived(editor.place);
|
|
14
|
-
</script>
|
|
15
|
-
|
|
16
|
-
{#if place}
|
|
17
|
-
<div
|
|
18
|
-
data-edytor-equation-panel
|
|
19
|
-
data-display={editor.display ? 'block' : 'inline'}
|
|
20
|
-
style:position="absolute"
|
|
21
|
-
style:left="{place.left}px"
|
|
22
|
-
style:top="{place.top}px"
|
|
23
|
-
style:transform={editor.display ? 'translateX(-50%)' : undefined}
|
|
24
|
-
>
|
|
25
|
-
{@render panel(editor)}
|
|
26
|
-
</div>
|
|
27
|
-
{/if}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { Snippet } from 'svelte';
|
|
2
|
-
import type { EquationEditor } from './equation.svelte.js';
|
|
3
|
-
type $$ComponentProps = {
|
|
4
|
-
editor: EquationEditor;
|
|
5
|
-
panel: Snippet<[EquationEditor]>;
|
|
6
|
-
};
|
|
7
|
-
declare const EquationEditor: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
8
|
-
type EquationEditor = ReturnType<typeof EquationEditor>;
|
|
9
|
-
export default EquationEditor;
|