edytor 1.0.0-rc.3 → 2.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 +21 -39
- package/dist/block/block.svelte.d.ts +11 -84
- package/dist/block/block.svelte.js +30 -134
- package/dist/block/colors.d.ts +0 -9
- package/dist/block/colors.js +1 -18
- package/dist/block/contentRange.d.ts +5 -1
- package/dist/block/contentRange.js +15 -16
- package/dist/block/inlineBlock.svelte.d.ts +11 -9
- package/dist/block/inlineBlock.svelte.js +18 -21
- package/dist/clipboard/createClipboardFragment.js +22 -64
- package/dist/clipboard/fragmentData.js +17 -42
- package/dist/clipboard/htmlFlow.js +7 -7
- package/dist/clipboard/insertClipboardFragment.js +5 -4
- package/dist/clipboard/moveText.js +16 -8
- package/dist/clipboard/serializeClipboardFragment.d.ts +2 -0
- package/dist/clipboard/serializeClipboardFragment.js +32 -28
- package/dist/cloudflare/DocumentRoom.d.ts +4 -17
- package/dist/cloudflare/DocumentRoom.js +3 -5
- package/dist/cloudflare/move.d.ts +1 -18
- package/dist/cloudflare/move.js +2 -48
- package/dist/cloudflare/room/admission.d.ts +1 -60
- package/dist/cloudflare/room/admission.js +25 -29
- package/dist/cloudflare/room/comments.d.ts +1 -3
- package/dist/cloudflare/room/comments.js +6 -6
- package/dist/cloudflare/room/context.d.ts +25 -82
- package/dist/cloudflare/room/context.js +8 -8
- package/dist/cloudflare/room/forged.d.ts +1 -1
- package/dist/cloudflare/room/forged.js +2 -12
- package/dist/cloudflare/room/frames.d.ts +1 -1
- package/dist/cloudflare/room/frames.js +1 -1
- package/dist/cloudflare/room/history.d.ts +1 -25
- package/dist/cloudflare/room/history.js +39 -54
- package/dist/cloudflare/room/moves.d.ts +1 -13
- package/dist/cloudflare/room/moves.js +33 -57
- package/dist/cloudflare/room/presence.d.ts +1 -11
- package/dist/cloudflare/room/presence.js +4 -4
- package/dist/cloudflare/room/purge.d.ts +1 -2
- package/dist/cloudflare/room/purge.js +2 -2
- package/dist/cloudflare/room/replicas.d.ts +1 -7
- package/dist/cloudflare/room/replicas.js +2 -2
- package/dist/cloudflare/room/storage.d.ts +3 -32
- package/dist/cloudflare/room/storage.js +33 -108
- package/dist/cloudflare/room/updates.d.ts +4 -4
- package/dist/cloudflare/room/updates.js +17 -24
- package/dist/cloudflare/room/validation.d.ts +1 -5
- package/dist/cloudflare/room/validation.js +16 -37
- package/dist/collaboration/RemoteSelections.svelte +13 -17
- package/dist/collaboration/awarenessSelection.d.ts +22 -1
- package/dist/collaboration/awarenessSelection.js +42 -0
- package/dist/collaboration/comments/client.d.ts +2 -2
- package/dist/collaboration/comments/client.js +1 -1
- package/dist/collaboration/history/index.d.ts +5 -5
- package/dist/collaboration/history/index.js +5 -5
- package/dist/collaboration/history/panel.svelte.d.ts +91 -0
- package/dist/collaboration/history/panel.svelte.js +223 -0
- package/dist/collaboration/providers.d.ts +12 -3
- package/dist/collaboration/providers.js +5 -4
- package/dist/components/Block.svelte +42 -56
- package/dist/components/Block.svelte.d.ts +7 -5
- package/dist/components/Content.svelte +1 -5
- package/dist/components/Edytor.svelte +82 -99
- package/dist/components/Edytor.svelte.d.ts +16 -13
- package/dist/components/InlineBlock.svelte +1 -1
- package/dist/components/Ranges.svelte +96 -0
- package/dist/components/Ranges.svelte.d.ts +19 -0
- package/dist/components/Suggestion.svelte +3 -2
- package/dist/components/Text.svelte +2 -5
- package/dist/components/Text.svelte.d.ts +1 -1
- package/dist/crdt/admission.d.ts +2 -9
- package/dist/crdt/admission.js +3 -9
- package/dist/crdt/attribution/attribution.d.ts +11 -72
- package/dist/crdt/attribution/attribution.js +5 -52
- package/dist/crdt/attribution/block.d.ts +0 -78
- package/dist/crdt/attribution/block.js +1 -144
- package/dist/crdt/data.d.ts +18 -13
- package/dist/crdt/data.js +49 -71
- package/dist/crdt/doc/anchors.js +4 -4
- package/dist/crdt/doc/content.d.ts +5 -1
- package/dist/crdt/doc/content.js +3 -1
- package/dist/crdt/doc/delete.d.ts +1 -0
- package/dist/crdt/doc/funnel.d.ts +0 -23
- package/dist/crdt/doc/funnel.js +34 -85
- package/dist/crdt/doc/gate.d.ts +8 -9
- package/dist/crdt/doc/gate.js +7 -17
- package/dist/crdt/doc/history.d.ts +87 -14
- package/dist/crdt/doc/history.js +334 -149
- package/dist/crdt/doc/layout.d.ts +0 -1
- package/dist/crdt/doc/layout.js +2 -3
- package/dist/crdt/doc/meta.d.ts +4 -4
- package/dist/crdt/doc/meta.js +10 -21
- package/dist/crdt/doc/moves.d.ts +4 -4
- package/dist/crdt/doc/moves.js +5 -5
- package/dist/crdt/doc/plan.d.ts +2 -0
- package/dist/crdt/doc/plan.js +2 -0
- package/dist/crdt/doc/reads.d.ts +8 -5
- package/dist/crdt/doc/reads.js +49 -50
- package/dist/crdt/doc/seed.d.ts +15 -6
- package/dist/crdt/doc/seed.js +27 -26
- package/dist/crdt/doc/split-merge.d.ts +1 -3
- package/dist/crdt/doc/split-merge.js +4 -5
- package/dist/crdt/doc/steps.d.ts +3 -7
- package/dist/crdt/doc/steps.js +20 -9
- package/dist/crdt/doc/types.d.ts +0 -10
- package/dist/crdt/document.d.ts +32 -115
- package/dist/crdt/document.js +216 -302
- package/dist/crdt/edytor-doc.d.ts +689 -90
- package/dist/crdt/edytor-doc.js +74 -149
- package/dist/crdt/engine-api.d.ts +15 -47
- package/dist/crdt/engine.d.ts +7 -17
- package/dist/crdt/engine.js +9 -19
- package/dist/crdt/flow.d.ts +9 -37
- package/dist/crdt/flow.js +260 -238
- package/dist/crdt/index.d.ts +32 -85
- package/dist/crdt/index.js +21 -47
- package/dist/crdt/operations.d.ts +24 -33
- package/dist/crdt/operations.js +8 -17
- package/dist/crdt/placement/display.d.ts +0 -2
- package/dist/crdt/placement/display.js +0 -15
- package/dist/crdt/placement/model.d.ts +160 -12
- package/dist/crdt/placement/model.js +413 -414
- package/dist/crdt/placement/rank.d.ts +1 -5
- package/dist/crdt/placement/rank.js +28 -38
- package/dist/crdt/props.d.ts +32 -0
- package/dist/crdt/props.js +172 -0
- package/dist/crdt/protocol.d.ts +4 -5
- package/dist/crdt/protocol.js +3 -4
- package/dist/crdt/protocols/awareness.d.ts +3 -7
- package/dist/crdt/protocols/awareness.js +17 -33
- package/dist/crdt/protocols/envelope.d.ts +9 -29
- package/dist/crdt/protocols/envelope.js +8 -25
- package/dist/crdt/protocols/sync.d.ts +15 -30
- package/dist/crdt/protocols/sync.js +27 -89
- package/dist/crdt/providers/bound.d.ts +3 -1
- package/dist/crdt/providers/bound.js +3 -1
- package/dist/crdt/providers/container.d.ts +11 -17
- package/dist/crdt/providers/container.js +39 -27
- package/dist/crdt/providers/index.d.ts +34 -6
- package/dist/crdt/providers/index.js +106 -111
- package/dist/crdt/providers/indexeddb.d.ts +2 -12
- package/dist/crdt/providers/indexeddb.js +29 -90
- package/dist/crdt/providers/room.d.ts +58 -2
- package/dist/crdt/providers/room.js +38 -21
- package/dist/crdt/providers/websocket.d.ts +1 -1
- package/dist/crdt/providers/websocket.js +3 -4
- package/dist/crdt/purge.d.ts +2 -2
- package/dist/crdt/purge.js +69 -6
- package/dist/crdt/rangeDelete.d.ts +4 -42
- package/dist/crdt/rangeDelete.js +7 -6
- package/dist/crdt/restore.d.ts +21 -1
- package/dist/crdt/restore.js +54 -59
- package/dist/crdt/schema.d.ts +2 -2
- package/dist/crdt/schema.js +4 -5
- package/dist/crdt/semantics.d.ts +10 -15
- package/dist/crdt/semantics.js +22 -21
- package/dist/crdt/storage.d.ts +7 -13
- package/dist/crdt/storage.js +10 -24
- package/dist/crdt/structs.d.ts +42 -47
- package/dist/crdt/structs.js +76 -67
- package/dist/crdt/tables.d.ts +9 -0
- package/dist/crdt/tables.js +20 -0
- package/dist/crdt/text/delete-index.d.ts +0 -13
- package/dist/crdt/text/delete-index.js +7 -14
- package/dist/crdt/text/deletes.d.ts +9 -22
- package/dist/crdt/text/deletes.js +11 -74
- package/dist/crdt/text/index/cache.js +3 -3
- package/dist/crdt/text/index/fold.d.ts +1 -2
- package/dist/crdt/text/index/fold.js +15 -10
- package/dist/crdt/text/index/layout.d.ts +0 -10
- package/dist/crdt/text/index/layout.js +6 -20
- package/dist/crdt/text/index/records.js +2 -1
- package/dist/crdt/text/index/report.js +5 -6
- package/dist/crdt/text/index/shared.d.ts +11 -4
- package/dist/crdt/text/index/shared.js +8 -7
- package/dist/crdt/text/index/state.d.ts +3 -33
- package/dist/crdt/text/index/state.js +2 -4
- package/dist/crdt/text/model.d.ts +82 -2
- package/dist/crdt/text/model.js +344 -354
- package/dist/crdt/text/rows.d.ts +0 -2
- package/dist/crdt/text/rows.js +0 -11
- package/dist/crdt/text/runs.d.ts +6 -3
- package/dist/crdt/text/runs.js +132 -137
- package/dist/crdt/text/streams.d.ts +1 -1
- package/dist/crdt/text/streams.js +1 -1
- package/dist/crdt/vendor/yjs/API-NOTES.md +25 -8
- package/dist/crdt/vendor/yjs/UPSTREAM.md +288 -8
- package/dist/crdt/vendor/yjs/dts/global.d.ts +5 -26
- package/dist/crdt/vendor/yjs/dts/index.d.ts +10 -15
- package/dist/crdt/vendor/yjs/dts/structs/AbstractStruct.d.ts +2 -2
- package/dist/crdt/vendor/yjs/dts/structs/Item.d.ts +14 -219
- package/dist/crdt/vendor/yjs/dts/structs/Skip.d.ts +2 -2
- package/dist/crdt/vendor/yjs/dts/utils/BlockSet.d.ts +2 -2
- package/dist/crdt/vendor/yjs/dts/utils/Doc.d.ts +12 -123
- package/dist/crdt/vendor/yjs/dts/utils/ID.d.ts +1 -1
- package/dist/crdt/vendor/yjs/dts/utils/RangeCursor.d.ts +37 -58
- package/dist/crdt/vendor/yjs/dts/utils/Transaction.d.ts +3 -78
- package/dist/crdt/vendor/yjs/dts/utils/UpdateDecoder.d.ts +2 -81
- package/dist/crdt/vendor/yjs/dts/utils/UpdateEncoder.d.ts +2 -74
- package/dist/crdt/vendor/yjs/dts/utils/encoding-helpers.d.ts +4 -4
- package/dist/crdt/vendor/yjs/dts/utils/encoding.d.ts +6 -18
- package/dist/crdt/vendor/yjs/dts/utils/ids.d.ts +12 -237
- package/dist/crdt/vendor/yjs/dts/utils/positions.d.ts +5 -0
- package/dist/crdt/vendor/yjs/dts/utils/redo.d.ts +3 -0
- package/dist/crdt/vendor/yjs/dts/utils/transaction-helpers.d.ts +1 -3
- package/dist/crdt/vendor/yjs/dts/utils/updates.d.ts +6 -23
- package/dist/crdt/vendor/yjs/dts/ynode.d.ts +73 -498
- package/dist/crdt/vendor/yjs/global.d.ts +5 -26
- package/dist/crdt/vendor/yjs/src/index.js +11 -25
- package/dist/crdt/vendor/yjs/src/structs/AbstractStruct.js +1 -1
- package/dist/crdt/vendor/yjs/src/structs/GC.js +1 -1
- package/dist/crdt/vendor/yjs/src/structs/Item.js +10 -372
- package/dist/crdt/vendor/yjs/src/structs/Skip.js +1 -1
- package/dist/crdt/vendor/yjs/src/utils/BlockSet.js +2 -2
- package/dist/crdt/vendor/yjs/src/utils/Doc.js +14 -170
- package/dist/crdt/vendor/yjs/src/utils/ID.js +1 -1
- package/dist/crdt/vendor/yjs/src/utils/RangeCursor.js +61 -128
- package/dist/crdt/vendor/yjs/src/utils/StructStore.js +0 -22
- package/dist/crdt/vendor/yjs/src/utils/Transaction.js +17 -282
- package/dist/crdt/vendor/yjs/src/utils/UpdateDecoder.js +3 -130
- package/dist/crdt/vendor/yjs/src/utils/UpdateEncoder.js +2 -132
- package/dist/crdt/vendor/yjs/src/utils/encoding-helpers.js +4 -4
- package/dist/crdt/vendor/yjs/src/utils/encoding.js +49 -146
- package/dist/crdt/vendor/yjs/src/utils/ids.js +23 -900
- package/dist/crdt/vendor/yjs/src/utils/positions.js +115 -0
- package/dist/crdt/vendor/yjs/src/utils/redo.js +143 -0
- package/dist/crdt/vendor/yjs/src/utils/transaction-helpers.js +10 -127
- package/dist/crdt/vendor/yjs/src/utils/updates.js +7 -50
- package/dist/crdt/vendor/yjs/src/ynode.js +261 -2226
- package/dist/dnd/autoScroll.js +1 -2
- package/dist/{plugins/blockHandles → dnd}/dropIndicator.d.ts +2 -2
- package/dist/{plugins/blockHandles → dnd}/dropIndicator.js +52 -60
- package/dist/{plugins/blockHandles → dnd}/geometry.d.ts +4 -3
- package/dist/{plugins/blockHandles → dnd}/geometry.js +6 -6
- package/dist/dnd/placement.d.ts +200 -0
- package/dist/dnd/placement.js +426 -0
- package/dist/dnd/pragmatic.d.ts +4 -22
- package/dist/dnd/pragmatic.js +7 -26
- package/dist/dnd/track.d.ts +14 -0
- package/dist/dnd/track.js +55 -0
- package/dist/dnd/vendor/pragmatic/UPSTREAM.md +103 -0
- package/dist/dnd/vendor/pragmatic/bind-event-listener/LICENSE +21 -0
- package/dist/dnd/vendor/pragmatic/bind-event-listener/bind-all.js +46 -0
- package/dist/dnd/vendor/pragmatic/bind-event-listener/bind.js +7 -0
- package/dist/dnd/vendor/pragmatic/bind-event-listener/index.js +2 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/LICENSE.md +11 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/element-adapter-native-data-key.js +6 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/element-adapter.d.ts +57 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/element-adapter.js +306 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/entry-point/element/adapter.d.ts +8 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/entry-point/element/adapter.js +10 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/entry-point/element/set-custom-native-drag-preview.d.ts +4 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/entry-point/element/set-custom-native-drag-preview.js +6 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/entry-point/types.d.ts +1 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/honey-pot-fix/get-element-from-point-without-honey-pot.js +12 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/honey-pot-fix/honey-pot-data-attribute.js +3 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/honey-pot-fix/is-honey-pot-element.js +4 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/honey-pot-fix/make-honey-pot-fix.js +333 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/internal-types.d.ts +350 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/ledger/dispatch-consumer-event.js +128 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/ledger/lifecycle-manager.js +340 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/ledger/usage-ledger.js +32 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/make-adapter/make-adapter.js +59 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/make-adapter/make-drop-target.js +288 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/make-adapter/make-monitor.js +85 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/combine.js +6 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/element/custom-native-drag-preview/set-custom-native-drag-preview.d.ts +36 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/element/custom-native-drag-preview/set-custom-native-drag-preview.js +153 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/element/custom-native-drag-preview/types.d.ts +16 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/once.js +13 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/add-attribute.js +7 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/android.js +10 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/changing-window/count-events-for-safari.js +104 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/changing-window/is-from-another-window.js +16 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/changing-window/is-leaving-window-in-safari.js +12 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/changing-window/is-leaving-window.js +55 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/detect-broken-drag.js +48 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/get-input.js +14 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/is-firefox.js +13 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/is-safari.js +19 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/max-z-index.js +3 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/media-types/text-media-type.js +6 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/media-types/url-media-type.js +6 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/popover-reset-styles.js +40 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/supports-popover.js +16 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/LICENSE.md +11 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/entry-point/element.d.ts +4 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/entry-point/element.js +8 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/internal-types.d.ts +50 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/over-element/data-attributes.js +9 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/over-element/get-scroll-by.js +117 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/over-element/make-api.js +90 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/over-element/try-scroll.js +183 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/axis.js +22 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/can-scroll-on-edge.js +17 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/configuration.js +49 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/edges.js +9 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/engagement-history.js +43 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/get-over-element-hitbox.js +50 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/get-percentage-in-range.js +19 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/get-scroll-change.js +106 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/is-axis-allowed.js +3 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/is-within.js +11 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/scheduler.js +104 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/side.js +6 -0
- package/dist/dnd/vendor/pragmatic/raf-schd/LICENSE +21 -0
- package/dist/dnd/vendor/pragmatic/raf-schd/raf-schd.esm.js +34 -0
- package/dist/edytor.svelte.d.ts +46 -63
- package/dist/edytor.svelte.js +126 -181
- package/dist/events/beforeInputCommands.d.ts +6 -11
- package/dist/events/beforeInputCommands.js +189 -181
- package/dist/events/beforeInputDeleteCommands.d.ts +20 -1
- package/dist/events/beforeInputDeleteCommands.js +153 -204
- package/dist/events/domTextOffset.d.ts +9 -9
- package/dist/events/domTextOffset.js +20 -48
- package/dist/events/events.utils.d.ts +0 -2
- package/dist/events/events.utils.js +0 -4
- package/dist/events/nativeInteractiveControl.d.ts +13 -13
- package/dist/events/nativeInteractiveControl.js +28 -56
- package/dist/events/onBeforeInput.d.ts +6 -1
- package/dist/events/onBeforeInput.js +207 -331
- package/dist/events/onCopy.js +1 -5
- package/dist/events/onDrop.d.ts +7 -1
- package/dist/events/onDrop.js +64 -78
- package/dist/events/onFocus.d.ts +9 -4
- package/dist/events/onFocus.js +45 -67
- package/dist/events/onInput.d.ts +8 -4
- package/dist/events/onInput.js +34 -147
- package/dist/events/onKeyDown.js +55 -122
- package/dist/events/onPaste.d.ts +14 -1
- package/dist/events/onPaste.js +51 -76
- package/dist/index.d.ts +11 -15
- package/dist/index.js +3 -3
- package/dist/kinds.d.ts +4 -6
- package/dist/kinds.js +28 -27
- package/dist/labels.d.ts +83 -320
- package/dist/labels.js +181 -408
- package/dist/plugins/Chrome.svelte +29 -0
- package/dist/plugins/Chrome.svelte.d.ts +32 -0
- package/dist/plugins/Control.svelte +23 -0
- package/dist/plugins/Control.svelte.d.ts +30 -0
- package/dist/plugins/anchored.svelte.d.ts +47 -0
- package/dist/plugins/anchored.svelte.js +73 -0
- package/dist/plugins/arrowMove/arrowMove.d.ts +2 -1
- package/dist/plugins/arrowMove/arrowMove.js +9 -5
- package/dist/plugins/bands.svelte.d.ts +57 -0
- package/dist/plugins/bands.svelte.js +95 -0
- package/dist/plugins/blockHandles/BlockHandle.svelte +14 -154
- package/dist/plugins/blockHandles/BlockHandle.svelte.d.ts +2 -2
- package/dist/plugins/blockHandles/BlockHandleController.svelte.d.ts +21 -196
- package/dist/plugins/blockHandles/BlockHandleController.svelte.js +158 -573
- package/dist/plugins/blockHandles/BlockHandles.svelte +15 -23
- package/dist/plugins/blockHandles/BlockHandles.svelte.d.ts +2 -2
- package/dist/plugins/blockHandles/blockHandlesPlugin.d.ts +25 -39
- package/dist/plugins/blockHandles/blockHandlesPlugin.js +130 -185
- package/dist/plugins/blockHandles/dragPreview.d.ts +8 -6
- package/dist/plugins/blockHandles/dragPreview.js +18 -16
- package/dist/plugins/blockMenu/BlockMenuController.svelte.d.ts +28 -38
- package/dist/plugins/blockMenu/BlockMenuController.svelte.js +116 -183
- package/dist/plugins/blockMenu/blockMenuPlugin.d.ts +1 -3
- package/dist/plugins/blockMenu/blockMenuPlugin.js +12 -29
- package/dist/plugins/brand.d.ts +8 -0
- package/dist/plugins/brand.js +8 -0
- package/dist/plugins/chrome.d.ts +45 -38
- package/dist/plugins/chrome.js +59 -36
- package/dist/plugins/code/CodeHeader.svelte +8 -38
- package/dist/plugins/code/CodePlugin.svelte +53 -56
- package/dist/plugins/code/CodePlugin.svelte.d.ts +0 -2
- package/dist/plugins/code/LanguageMenu.svelte +16 -125
- package/dist/plugins/code/LanguageMenu.svelte.d.ts +2 -1
- package/dist/plugins/code/code.css +5 -117
- package/dist/plugins/code/header.svelte.d.ts +2 -11
- package/dist/plugins/code/header.svelte.js +11 -38
- package/dist/plugins/code/languageMenu.svelte.d.ts +12 -32
- package/dist/plugins/code/languageMenu.svelte.js +30 -160
- package/dist/plugins/code/languages.d.ts +9 -22
- package/dist/plugins/code/languages.js +39 -128
- package/dist/plugins/columns/ColumnResize.svelte +16 -27
- package/dist/plugins/columns/ColumnResize.svelte.d.ts +1 -1
- package/dist/plugins/columns/ColumnsPlugin.svelte +46 -78
- package/dist/plugins/columns/ColumnsPlugin.svelte.d.ts +0 -12
- package/dist/plugins/columns/columns.css +7 -26
- package/dist/plugins/columns/gaps.d.ts +7 -5
- package/dist/plugins/columns/gaps.js +11 -6
- package/dist/plugins/columns/resize.svelte.d.ts +17 -54
- package/dist/plugins/columns/resize.svelte.js +80 -173
- package/dist/plugins/comments/CommentsController.svelte.d.ts +1 -4
- package/dist/plugins/comments/CommentsController.svelte.js +14 -25
- package/dist/plugins/comments/CommentsSidebar.svelte +82 -431
- package/dist/plugins/comments/CommentsSidebar.svelte.d.ts +4 -2
- package/dist/plugins/comments/commentsPlugin.d.ts +25 -9
- package/dist/plugins/comments/commentsPlugin.js +12 -10
- package/dist/plugins/equation/EquationEditor.svelte +16 -130
- package/dist/plugins/equation/EquationEditor.svelte.d.ts +1 -2
- package/dist/plugins/equation/EquationPlugin.svelte +109 -172
- package/dist/plugins/equation/EquationPlugin.svelte.d.ts +3 -2
- package/dist/plugins/equation/EquationView.svelte +20 -11
- package/dist/plugins/equation/equation.css +7 -0
- package/dist/plugins/equation/equation.svelte.d.ts +37 -24
- package/dist/plugins/equation/equation.svelte.js +20 -94
- package/dist/plugins/equation/katex.js +6 -9
- package/dist/plugins/fileDrop.d.ts +28 -0
- package/dist/plugins/fileDrop.js +116 -0
- package/dist/plugins/find/FindController.svelte.d.ts +8 -13
- package/dist/plugins/find/FindController.svelte.js +34 -55
- package/dist/plugins/find/findPlugin.d.ts +4 -8
- package/dist/plugins/find/findPlugin.js +29 -9
- package/dist/plugins/image/ImageChrome.svelte +6 -167
- package/dist/plugins/image/ImageChrome.svelte.d.ts +0 -2
- package/dist/plugins/image/ImagePlugin.svelte +71 -151
- package/dist/plugins/image/ImagePlugin.svelte.d.ts +12 -41
- package/dist/plugins/image/ImageToolbarHost.svelte +37 -0
- package/dist/plugins/image/ImageToolbarHost.svelte.d.ts +9 -0
- package/dist/plugins/image/controls.svelte.d.ts +6 -36
- package/dist/plugins/image/controls.svelte.js +43 -212
- package/dist/plugins/image/image.css +17 -0
- package/dist/plugins/image/image.d.ts +0 -5
- package/dist/plugins/image/image.js +0 -3
- package/dist/plugins/image/toolbar.svelte.d.ts +69 -0
- package/dist/plugins/image/toolbar.svelte.js +145 -0
- package/dist/plugins/index.d.ts +30 -26
- package/dist/plugins/index.js +28 -22
- package/dist/plugins/list.svelte.d.ts +128 -0
- package/dist/plugins/list.svelte.js +217 -0
- package/dist/plugins/markdownShortcuts.d.ts +1 -1
- package/dist/plugins/markdownShortcuts.js +10 -9
- package/dist/plugins/marquee/MarqueeBox.svelte +3 -20
- package/dist/plugins/marquee/MarqueeBox.svelte.d.ts +1 -1
- package/dist/plugins/marquee/MarqueeController.svelte.d.ts +0 -2
- package/dist/plugins/marquee/MarqueeController.svelte.js +20 -23
- package/dist/plugins/marquee/marquee.js +4 -21
- package/dist/plugins/marquee/marqueePlugin.d.ts +4 -3
- package/dist/plugins/marquee/marqueePlugin.js +16 -15
- package/dist/plugins/media/AudioPlugin.svelte +13 -88
- package/dist/plugins/media/AudioPlugin.svelte.d.ts +11 -4
- package/dist/plugins/media/BookmarkPlugin.svelte +113 -120
- package/dist/plugins/media/BookmarkPlugin.svelte.d.ts +10 -15
- package/dist/plugins/media/EmbedPlugin.svelte +82 -86
- package/dist/plugins/media/EmbedPlugin.svelte.d.ts +11 -17
- package/dist/plugins/media/EmptySlot.svelte +44 -0
- package/dist/plugins/media/EmptySlot.svelte.d.ts +25 -0
- package/dist/plugins/media/FilePlugin.svelte +45 -113
- package/dist/plugins/media/FilePlugin.svelte.d.ts +21 -4
- package/dist/plugins/media/MediaEmpty.svelte +51 -90
- package/dist/plugins/media/MediaEmpty.svelte.d.ts +26 -10
- package/dist/plugins/media/SourceBlock.svelte +200 -0
- package/dist/plugins/media/SourceBlock.svelte.d.ts +34 -0
- package/dist/plugins/media/UploadPreview.svelte +32 -0
- package/dist/plugins/media/UploadPreview.svelte.d.ts +11 -0
- package/dist/plugins/media/VideoPlugin.svelte +14 -97
- package/dist/plugins/media/VideoPlugin.svelte.d.ts +12 -5
- package/dist/plugins/media/empty.svelte.d.ts +47 -46
- package/dist/plugins/media/empty.svelte.js +67 -60
- package/dist/plugins/media/media.d.ts +97 -44
- package/dist/plugins/media/media.js +77 -99
- package/dist/plugins/media/upload.css +23 -0
- package/dist/plugins/media/urlPaste.svelte.d.ts +6 -37
- package/dist/plugins/media/urlPaste.svelte.js +32 -102
- package/dist/plugins/mention/MentionPlugin.svelte +84 -126
- package/dist/plugins/mention/MentionPlugin.svelte.d.ts +17 -27
- package/dist/plugins/mention/mention.css +6 -0
- package/dist/plugins/page/PageLink.svelte +54 -38
- package/dist/plugins/page/PagePlugin.svelte +20 -18
- package/dist/plugins/page/PagePlugin.svelte.d.ts +2 -4
- package/dist/plugins/page/page.d.ts +35 -9
- package/dist/plugins/page/page.js +3 -4
- package/dist/plugins/pageLink/PageLinkPlugin.svelte +154 -109
- package/dist/plugins/pageLink/PageLinkPlugin.svelte.d.ts +19 -26
- package/dist/plugins/pageLink/pageLink.css +6 -0
- package/dist/plugins/planned.d.ts +10 -0
- package/dist/plugins/planned.js +12 -0
- package/dist/plugins/richtext/CalloutIcon.svelte +13 -26
- package/dist/plugins/richtext/CalloutIconPicker.svelte +26 -0
- package/dist/plugins/richtext/CalloutIconPicker.svelte.d.ts +9 -0
- package/dist/plugins/richtext/EmptyBody.svelte +13 -20
- package/dist/plugins/richtext/RichTextControl.svelte +39 -0
- package/dist/plugins/richtext/RichTextControl.svelte.d.ts +8 -0
- package/dist/plugins/richtext/RichTextPlugin.svelte +174 -183
- package/dist/plugins/richtext/RichTextPlugin.svelte.d.ts +34 -34
- package/dist/plugins/richtext/TodoCheckbox.svelte +10 -21
- package/dist/plugins/richtext/TodoCheckbox.svelte.d.ts +0 -2
- package/dist/plugins/richtext/body.js +2 -2
- package/dist/plugins/richtext/calloutIcons.svelte.d.ts +50 -55
- package/dist/plugins/richtext/calloutIcons.svelte.js +86 -174
- package/dist/plugins/richtext/callouts.d.ts +15 -0
- package/dist/plugins/richtext/callouts.js +23 -0
- package/dist/plugins/richtext/controls.svelte.d.ts +110 -0
- package/dist/plugins/richtext/controls.svelte.js +126 -0
- package/dist/plugins/richtext/richTextOperations.js +37 -28
- package/dist/plugins/richtext/richtext.css +6 -0
- package/dist/plugins/slashMenu/SlashMenuController.svelte.d.ts +2 -14
- package/dist/plugins/slashMenu/SlashMenuController.svelte.js +34 -71
- package/dist/plugins/slashMenu/slashMenuPlugin.d.ts +9 -26
- package/dist/plugins/slashMenu/slashMenuPlugin.js +27 -68
- package/dist/plugins/suggestions/SuggestionBars.svelte +27 -84
- package/dist/plugins/suggestions/SuggestionBars.svelte.d.ts +9 -3
- package/dist/plugins/suggestions/suggestionsPlugin.d.ts +10 -18
- package/dist/plugins/suggestions/suggestionsPlugin.js +9 -24
- package/dist/plugins/table/TableChrome.svelte +40 -124
- package/dist/plugins/table/TablePlugin.svelte +106 -168
- package/dist/plugins/table/TablePlugin.svelte.d.ts +0 -4
- package/dist/plugins/table/chrome.svelte.d.ts +38 -141
- package/dist/plugins/table/chrome.svelte.js +340 -589
- package/dist/plugins/table/ops.d.ts +47 -0
- package/dist/plugins/table/ops.js +233 -0
- package/dist/plugins/table/table.css +16 -152
- package/dist/plugins/table/table.d.ts +15 -14
- package/dist/plugins/table/table.js +22 -16
- package/dist/plugins/toc/TableOfContents.svelte +32 -38
- package/dist/plugins/toc/TableOfContents.svelte.d.ts +1 -5
- package/dist/plugins/toc/TocPlugin.svelte +22 -22
- package/dist/plugins/toc/TocPlugin.svelte.d.ts +4 -6
- package/dist/plugins/toc/toc.d.ts +41 -10
- package/dist/plugins/toc/toc.js +2 -3
- package/dist/plugins/toolbar/ToolbarController.svelte.d.ts +4 -68
- package/dist/plugins/toolbar/ToolbarController.svelte.js +63 -89
- package/dist/plugins/toolbar/toolbarPlugin.d.ts +8 -18
- package/dist/plugins/toolbar/toolbarPlugin.js +28 -43
- package/dist/plugins/triggers/TriggerController.svelte.d.ts +4 -68
- package/dist/plugins/triggers/TriggerController.svelte.js +48 -129
- package/dist/plugins/triggers/place.d.ts +0 -9
- package/dist/plugins/triggers/place.js +1 -17
- package/dist/plugins/triggers/triggers.d.ts +31 -9
- package/dist/plugins/triggers/triggers.js +82 -62
- package/dist/plugins/uploads.svelte.d.ts +55 -24
- package/dist/plugins/uploads.svelte.js +123 -50
- package/dist/plugins.d.ts +187 -66
- package/dist/selection/domSelection.d.ts +13 -4
- package/dist/selection/domSelection.js +110 -183
- package/dist/selection/pointer.svelte.d.ts +8 -10
- package/dist/selection/pointer.svelte.js +32 -73
- package/dist/selection/replaceSelection.d.ts +21 -22
- package/dist/selection/replaceSelection.js +60 -69
- package/dist/selection/selection.svelte.d.ts +5 -73
- package/dist/selection/selection.svelte.js +224 -542
- package/dist/selection/selection.utils.d.ts +34 -11
- package/dist/selection/selection.utils.js +128 -247
- package/dist/selection/visibility.d.ts +3 -8
- package/dist/selection/visibility.js +7 -5
- package/dist/session/announcer.svelte.d.ts +2 -1
- package/dist/session/announcer.svelte.js +7 -3
- package/dist/session/attempt.d.ts +43 -39
- package/dist/session/attempt.js +62 -55
- package/dist/session/bindings.js +117 -145
- package/dist/session/commands.d.ts +47 -22
- package/dist/session/commands.js +208 -208
- package/dist/session/composition.svelte.d.ts +2 -4
- package/dist/session/composition.svelte.js +55 -65
- package/dist/session/editing/text.d.ts +6 -0
- package/dist/session/editing/text.js +17 -3
- package/dist/session/handles.d.ts +10 -1
- package/dist/session/handles.js +28 -0
- package/dist/session/history.d.ts +0 -4
- package/dist/session/history.js +16 -21
- package/dist/session/inputRules.d.ts +6 -3
- package/dist/session/inputRules.js +78 -83
- package/dist/session/keymap.d.ts +1 -6
- package/dist/session/keymap.js +17 -20
- package/dist/session/moves.d.ts +43 -10
- package/dist/session/moves.js +101 -59
- package/dist/session/navigation.d.ts +10 -2
- package/dist/session/navigation.js +140 -172
- package/dist/session/ports.d.ts +2 -7
- package/dist/session/props.d.ts +25 -25
- package/dist/session/props.js +62 -159
- package/dist/session/selection.d.ts +4 -3
- package/dist/session/selection.js +5 -0
- package/dist/session/suggestions.svelte.d.ts +1 -1
- package/dist/session/suggestions.svelte.js +42 -47
- package/dist/session/uploads.d.ts +29 -0
- package/dist/session/uploads.js +10 -0
- package/dist/session/virtual.d.ts +3 -3
- package/dist/session/virtual.js +18 -40
- package/dist/surface/attributes.d.ts +1 -0
- package/dist/surface/attributes.js +3 -26
- package/dist/surface/cells.d.ts +5 -0
- package/dist/surface/cells.js +5 -0
- package/dist/surface/lines.d.ts +2 -2
- package/dist/surface/lines.js +1 -1
- package/dist/surface/observer.svelte.d.ts +3 -20
- package/dist/surface/observer.svelte.js +52 -72
- package/dist/surface/overlay.d.ts +41 -3
- package/dist/surface/overlay.js +92 -37
- package/dist/surface/pin.svelte.d.ts +5 -0
- package/dist/surface/pin.svelte.js +5 -0
- package/dist/surface/projector.svelte.d.ts +4 -6
- package/dist/surface/projector.svelte.js +42 -69
- package/dist/text/text.svelte.d.ts +14 -40
- package/dist/text/text.svelte.js +35 -51
- package/dist/text/wordBoundary.d.ts +19 -0
- package/dist/text/wordBoundary.js +29 -44
- package/dist/themes/notion.css +272 -106
- package/dist/utils/json.d.ts +3 -1
- package/dist/utils/json.js +52 -51
- package/dist/utils/listen.d.ts +8 -0
- package/dist/utils/listen.js +19 -0
- package/package.json +4 -5
- package/dist/block/block.utils.d.ts +0 -340
- package/dist/block/block.utils.js +0 -356
- package/dist/collaboration/history/HistoryPanel.svelte +0 -554
- package/dist/collaboration/history/HistoryPanel.svelte.d.ts +0 -7
- package/dist/collaboration/history/panel.d.ts +0 -61
- package/dist/collaboration/history/panel.js +0 -3
- package/dist/components/SuggestionRanges.svelte +0 -58
- package/dist/components/SuggestionRanges.svelte.d.ts +0 -7
- package/dist/crdt/doc/table.d.ts +0 -21
- package/dist/crdt/doc/table.js +0 -288
- package/dist/crdt/migration/generation.d.ts +0 -58
- package/dist/crdt/migration/generation.js +0 -70
- package/dist/crdt/migration/legacy-schema.d.ts +0 -61
- package/dist/crdt/migration/legacy-schema.js +0 -151
- package/dist/crdt/migration/migrate.d.ts +0 -56
- package/dist/crdt/migration/migrate.js +0 -227
- package/dist/crdt/nodes.d.ts +0 -121
- package/dist/crdt/nodes.js +0 -56
- package/dist/crdt/text/index/checks.d.ts +0 -15
- package/dist/crdt/text/index/checks.js +0 -156
- package/dist/crdt/vendor/yjs/dts/utils/EventHandler.d.ts +0 -17
- package/dist/crdt/vendor/yjs/dts/utils/RelativePosition.d.ts +0 -80
- package/dist/crdt/vendor/yjs/dts/utils/UndoManager.d.ts +0 -205
- package/dist/crdt/vendor/yjs/dts/utils/YEvent.d.ts +0 -93
- package/dist/crdt/vendor/yjs/dts/utils/meta.d.ts +0 -25
- package/dist/crdt/vendor/yjs/dts/utils/renderer-helpers.d.ts +0 -98
- package/dist/crdt/vendor/yjs/dts/utils/schemas.d.ts +0 -2
- package/dist/crdt/vendor/yjs/src/utils/EventHandler.js +0 -75
- package/dist/crdt/vendor/yjs/src/utils/RelativePosition.js +0 -301
- package/dist/crdt/vendor/yjs/src/utils/UndoManager.js +0 -554
- package/dist/crdt/vendor/yjs/src/utils/YEvent.js +0 -158
- package/dist/crdt/vendor/yjs/src/utils/meta.js +0 -74
- package/dist/crdt/vendor/yjs/src/utils/renderer-helpers.js +0 -186
- package/dist/crdt/vendor/yjs/src/utils/schemas.js +0 -3
- package/dist/edytor.utils.d.ts +0 -50
- package/dist/edytor.utils.js +0 -67
- package/dist/plugins/blockMenu/BlockMenu.svelte +0 -335
- package/dist/plugins/blockMenu/BlockMenu.svelte.d.ts +0 -9
- package/dist/plugins/find/FindBar.svelte +0 -170
- package/dist/plugins/find/FindBar.svelte.d.ts +0 -9
- package/dist/plugins/find/FindHighlights.svelte +0 -75
- package/dist/plugins/find/FindHighlights.svelte.d.ts +0 -9
- package/dist/plugins/icons.d.ts +0 -2
- package/dist/plugins/icons.js +0 -63
- package/dist/plugins/image/ImageEmpty.svelte +0 -93
- package/dist/plugins/image/ImageEmpty.svelte.d.ts +0 -15
- package/dist/plugins/image/empty.svelte.d.ts +0 -56
- package/dist/plugins/image/empty.svelte.js +0 -83
- package/dist/plugins/keepInView.d.ts +0 -4
- package/dist/plugins/keepInView.js +0 -6
- package/dist/plugins/media/UrlPasteMenu.svelte +0 -92
- package/dist/plugins/media/UrlPasteMenu.svelte.d.ts +0 -9
- package/dist/plugins/richtext/CalloutIconMenu.svelte +0 -98
- package/dist/plugins/richtext/CalloutIconMenu.svelte.d.ts +0 -9
- package/dist/plugins/richtext/labels.d.ts +0 -9
- package/dist/plugins/richtext/labels.js +0 -7
- package/dist/plugins/slashMenu/SlashMenu.svelte +0 -276
- package/dist/plugins/slashMenu/SlashMenu.svelte.d.ts +0 -11
- package/dist/plugins/table/dragPreview.d.ts +0 -29
- package/dist/plugins/table/dragPreview.js +0 -103
- package/dist/plugins/toolbar/LinkCard.svelte +0 -122
- package/dist/plugins/toolbar/LinkCard.svelte.d.ts +0 -9
- package/dist/plugins/toolbar/Toolbar.svelte +0 -349
- package/dist/plugins/toolbar/Toolbar.svelte.d.ts +0 -9
- package/dist/plugins/triggers/TriggerMenu.svelte +0 -135
- package/dist/plugins/triggers/TriggerMenu.svelte.d.ts +0 -7
- package/dist/text/deltas.d.ts +0 -22
- package/dist/text/deltas.js +0 -46
- package/dist/text/text.utils.d.ts +0 -45
- package/dist/text/text.utils.js +0 -199
- /package/dist/{plugins/columns → dnd}/stacking.d.ts +0 -0
- /package/dist/{plugins/columns → dnd}/stacking.js +0 -0
|
@@ -1,19 +1,20 @@
|
|
|
1
|
+
import { untrack } from 'svelte';
|
|
1
2
|
import { autoScrollFor } from '../../dnd/autoScroll.js';
|
|
2
|
-
import { noSelection, project } from '../../session/selection.js';
|
|
3
|
-
import {
|
|
4
|
-
import { HIDDEN, hidden } from '../../selection/visibility.js';
|
|
3
|
+
import { blockSelection, noSelection, project } from '../../session/selection.js';
|
|
4
|
+
import { draggable, dropTargetForElements, setCustomNativeDragPreview } from '../../dnd/pragmatic.js';
|
|
5
5
|
import { getSelectionBlocks, holdsBlocks, movable, outermost, selectMoved, shownText } from '../../selection/replaceSelection.js';
|
|
6
6
|
import { takeKeys } from '../../events/onFocus.js';
|
|
7
7
|
import { EDYTOR_BLOCK_DRAG_MIME } from '../../events/onDrop.js';
|
|
8
8
|
import { kindLabel } from '../../kinds.js';
|
|
9
|
-
import {
|
|
9
|
+
import { siblingSlot } from '../../session/handles.js';
|
|
10
10
|
import { dragPreview } from './dragPreview.js';
|
|
11
|
-
import { DropIndicator } from '
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
11
|
+
import { DropIndicator } from '../../dnd/dropIndicator.js';
|
|
12
|
+
import { DropResolver, SLOP_X, SLOP_Y } from '../../dnd/placement.js';
|
|
13
|
+
import { getOwnRowBottom, ownRow } from '../../dnd/geometry.js';
|
|
14
|
+
import { all, listen } from '../../utils/listen.js';
|
|
14
15
|
/**
|
|
15
|
-
* The DOM event a
|
|
16
|
-
*
|
|
16
|
+
* The DOM event a grip click dispatches on the editor (the one way to
|
|
17
|
+
* answer it: the block menu's, or your own). A menu that takes the keyboard answers it with `preventDefault()`
|
|
17
18
|
* (the block menu does); unanswered, the editor takes the focus, so the keys
|
|
18
19
|
* act on the selected block (Backspace deletes it, Shift+arrows extend it).
|
|
19
20
|
*/
|
|
@@ -31,18 +32,11 @@ const keyMoves = {
|
|
|
31
32
|
ArrowRight: 'in',
|
|
32
33
|
ArrowLeft: 'out'
|
|
33
34
|
};
|
|
34
|
-
/** The drop target data
|
|
35
|
+
/** The drop target data keys of the row at the pointer (`rowAt`) and of its half (the top one). */
|
|
35
36
|
const ROW = 'edytorRow';
|
|
37
|
+
const BEFORE = 'edytorBefore';
|
|
36
38
|
/** The drop target data key of a beside band beyond the editor's edges (`margin`). */
|
|
37
39
|
const MARGIN = 'edytorMargin';
|
|
38
|
-
/** How far beside a target's box it stays the drop target (`getIsSticky`), across and along. */
|
|
39
|
-
const SLOP_X = 20;
|
|
40
|
-
const SLOP_Y = 24;
|
|
41
|
-
/** The right beside band: the row's last 15% (Notion), at least this many px. */
|
|
42
|
-
const RIGHT_BAND = 0.15;
|
|
43
|
-
const RIGHT_BAND_MIN = 32;
|
|
44
|
-
/** The handle column's width when the drag's handle cannot be measured (`+`, grip and gap). */
|
|
45
|
-
const HANDLE_COLUMN = 50;
|
|
46
40
|
/**
|
|
47
41
|
* Whether the pointer is over the own row of a block other than `node` and
|
|
48
42
|
* its descendants. A container (a list) has no row of its own: its padding
|
|
@@ -62,8 +56,6 @@ const endsDocument = (block) => {
|
|
|
62
56
|
return false;
|
|
63
57
|
return true;
|
|
64
58
|
};
|
|
65
|
-
/** Where a block's own text starts: its level's column. */
|
|
66
|
-
const column = (block) => ownTextRow(block.node).left;
|
|
67
59
|
export class BlockHandleController {
|
|
68
60
|
edytor;
|
|
69
61
|
options;
|
|
@@ -79,6 +71,8 @@ export class BlockHandleController {
|
|
|
79
71
|
group = [];
|
|
80
72
|
/** The drop bar and the nest backdrop in the overlay, while our drag runs. */
|
|
81
73
|
indicator;
|
|
74
|
+
/** Where a drop lands (the one resolution a file drag reads too). */
|
|
75
|
+
drop;
|
|
82
76
|
/** The selection the drag in progress replaced when it started: its undo step restores it. */
|
|
83
77
|
held = null;
|
|
84
78
|
/** The handle the drag in progress started from: its width is the handle column's. */
|
|
@@ -88,10 +82,14 @@ export class BlockHandleController {
|
|
|
88
82
|
constructor(edytor, options = { draggable: true }) {
|
|
89
83
|
this.edytor = edytor;
|
|
90
84
|
this.options = options;
|
|
91
|
-
this.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
85
|
+
this.drop = new DropResolver(edytor, {
|
|
86
|
+
targetOf: (node) => this.targets.get(node),
|
|
87
|
+
handle: () => this.handle,
|
|
88
|
+
indicator: (this.indicator = new DropIndicator(edytor, {
|
|
89
|
+
group: () => this.group,
|
|
90
|
+
besideOf: (block) => this.drop.besideOf(block),
|
|
91
|
+
layoutOf: (outer) => this.drop.layoutOf(outer)
|
|
92
|
+
}))
|
|
95
93
|
});
|
|
96
94
|
}
|
|
97
95
|
get readonly() {
|
|
@@ -100,10 +98,6 @@ export class BlockHandleController {
|
|
|
100
98
|
get draggable() {
|
|
101
99
|
return this.options.draggable;
|
|
102
100
|
}
|
|
103
|
-
/** The words the handles say (the plugin's `labels`): read them in a custom `handle`. */
|
|
104
|
-
get labels() {
|
|
105
|
-
return this.options.labels ?? englishLabels.blockHandles;
|
|
106
|
-
}
|
|
107
101
|
/**
|
|
108
102
|
* The block's kind as people read it (`kindLabel`: "Heading 1"), its
|
|
109
103
|
* handle's name; reactive through the block's cell (a Turn into renames it).
|
|
@@ -115,36 +109,54 @@ export class BlockHandleController {
|
|
|
115
109
|
/** The popup the `+` or the grip of `block` opened, while it is open (`edytor.popups`). */
|
|
116
110
|
opened = (block, control) => this.edytor.popups.openedBy(block.id, control);
|
|
117
111
|
/**
|
|
118
|
-
*
|
|
119
|
-
* selects the block and opens its menu,
|
|
112
|
+
* The block's grip (`{@attach handle.grip}`): dragging (when draggable),
|
|
113
|
+
* a click that selects the block and opens its menu, the Alt+arrow moves
|
|
114
|
+
* (`aria-keyshortcuts`), and the ARIA of the menu it opened.
|
|
120
115
|
*/
|
|
121
116
|
grip = (block) => (node) => {
|
|
122
|
-
|
|
117
|
+
node.setAttribute('aria-keyshortcuts', 'Alt+ArrowUp Alt+ArrowDown Alt+ArrowRight Alt+ArrowLeft');
|
|
118
|
+
this.#opener(node, block, 'grip');
|
|
119
|
+
return untrack(() => all(listen(node, 'click', (event) => {
|
|
123
120
|
event.preventDefault();
|
|
124
121
|
event.stopPropagation();
|
|
125
|
-
this
|
|
126
|
-
};
|
|
127
|
-
const pointerdown = (event) => event.stopPropagation();
|
|
128
|
-
const keydown = (event) => this.handleKeyDown(event, block);
|
|
129
|
-
node.addEventListener('click', click);
|
|
130
|
-
node.addEventListener('pointerdown', pointerdown);
|
|
131
|
-
node.addEventListener('keydown', keydown);
|
|
132
|
-
const unregister = this.registerHandle(node, block);
|
|
133
|
-
return {
|
|
134
|
-
destroy: () => {
|
|
135
|
-
node.removeEventListener('click', click);
|
|
136
|
-
node.removeEventListener('pointerdown', pointerdown);
|
|
137
|
-
node.removeEventListener('keydown', keydown);
|
|
138
|
-
unregister();
|
|
139
|
-
}
|
|
140
|
-
};
|
|
122
|
+
this.#activateBlock(block, node);
|
|
123
|
+
}), listen(node, 'pointerdown', (event) => event.stopPropagation()), listen(node, 'keydown', (event) => this.#handleKeyDown(event, block)), this.registerHandle(node, block)));
|
|
141
124
|
};
|
|
125
|
+
/**
|
|
126
|
+
* The block's `+` (`{@attach handle.plus}`): a click offers what to add
|
|
127
|
+
* below (Alt+click above, or a column beside: `addBlock`) under it; a
|
|
128
|
+
* press keeps the editor's focus; the ARIA of the menu it opened.
|
|
129
|
+
*/
|
|
130
|
+
plus = (block) => (node) => {
|
|
131
|
+
this.#opener(node, block, 'add');
|
|
132
|
+
return all(listen(node, 'mousedown', (event) => event.preventDefault()), listen(node, 'pointerdown', (event) => event.stopPropagation()), listen(node, 'click', (event) => {
|
|
133
|
+
event.preventDefault();
|
|
134
|
+
event.stopPropagation();
|
|
135
|
+
this.addBlock(block, event.altKey, node);
|
|
136
|
+
}));
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* Keep `node`'s `aria-expanded`, `aria-controls` and `aria-haspopup` in
|
|
140
|
+
* step with the menu its `control` of `block` opened, while it is open.
|
|
141
|
+
*/
|
|
142
|
+
#opener(node, block, control) {
|
|
143
|
+
$effect(() => {
|
|
144
|
+
const popup = this.opened(block, control);
|
|
145
|
+
const values = { expanded: popup && 'true', controls: popup?.id, haspopup: popup?.haspopup };
|
|
146
|
+
for (const [name, value] of Object.entries(values)) {
|
|
147
|
+
if (value === undefined)
|
|
148
|
+
node.removeAttribute(`aria-${name}`);
|
|
149
|
+
else
|
|
150
|
+
node.setAttribute(`aria-${name}`, String(value));
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
}
|
|
142
154
|
/**
|
|
143
155
|
* Select the block — a block selection holding it stays; over a text
|
|
144
156
|
* range across blocks, the blocks it covers (`select`) — and open its
|
|
145
157
|
* menu.
|
|
146
158
|
*/
|
|
147
|
-
activateBlock(block, anchor) {
|
|
159
|
+
#activateBlock(block, anchor) {
|
|
148
160
|
if (this.edytor.readonly || !block.movable)
|
|
149
161
|
return;
|
|
150
162
|
const { selection } = this.edytor;
|
|
@@ -152,10 +164,8 @@ export class BlockHandleController {
|
|
|
152
164
|
if (!selection.selectedBlocks.has(block))
|
|
153
165
|
this.select(block);
|
|
154
166
|
this.gripped = { before, after: selection.value };
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
// Without a callback, a block menu plugin may answer the activation; with
|
|
158
|
-
// none answering, the keys go to the editor, over the block selection
|
|
167
|
+
// A block menu plugin (or the app) may answer the activation; with none
|
|
168
|
+
// answering, the keys go to the editor, over the block selection
|
|
159
169
|
// (Notion), not to the grip (its own focus: not a user gesture).
|
|
160
170
|
const event = new CustomEvent(BLOCK_ACTIVATE_EVENT, {
|
|
161
171
|
cancelable: true,
|
|
@@ -187,15 +197,14 @@ export class BlockHandleController {
|
|
|
187
197
|
const { edytor } = this;
|
|
188
198
|
if (edytor.readonly || !block.parent)
|
|
189
199
|
return;
|
|
190
|
-
this
|
|
200
|
+
this.#ungrip();
|
|
191
201
|
const column = alt && this.addsColumn(block);
|
|
192
202
|
const above = alt && !column;
|
|
193
203
|
const insert = (then) => {
|
|
194
204
|
const { dispatcher, facade, selection, undoManager: um } = edytor;
|
|
195
205
|
const held = selection.value;
|
|
196
206
|
let refused;
|
|
197
|
-
edytor
|
|
198
|
-
edytor.node?.focus({ preventScroll: true });
|
|
207
|
+
takeKeys(edytor);
|
|
199
208
|
// The addition and `then` are one transaction: one update, one undo
|
|
200
209
|
// step. Refused with nothing applied, the addition is taken back inside
|
|
201
210
|
// it, and the history captures nothing (its undo and redo steps stay).
|
|
@@ -204,20 +213,17 @@ export class BlockHandleController {
|
|
|
204
213
|
um.captureTransaction = (tr) => !refused && capture(tr);
|
|
205
214
|
let out;
|
|
206
215
|
try {
|
|
207
|
-
out = dispatcher.run('
|
|
216
|
+
out = dispatcher.run('insertBlocks', () => edytor.transact(() => {
|
|
208
217
|
const type = block.parent && edytor.defaultChild(block.parent);
|
|
209
218
|
if (!type)
|
|
210
219
|
return;
|
|
211
|
-
const spec = { block: { type } };
|
|
212
220
|
const reused = !column && block.type === type && block.isEmpty;
|
|
213
221
|
const target = reused
|
|
214
222
|
? block
|
|
215
|
-
: above
|
|
216
|
-
? block.insertBlockBefore(spec)
|
|
217
|
-
: block.insertBlockAfter(spec);
|
|
223
|
+
: edytor.idToBlock.get(edytor.insertBlocks(siblingSlot(block, !above), [{ type }]).ids[0] ?? '');
|
|
218
224
|
// A new column right of the block's: the one move path places it.
|
|
219
225
|
if (target && column)
|
|
220
|
-
edytor.
|
|
226
|
+
edytor.move({ blocks: [target], target: block, position: 'right' });
|
|
221
227
|
// The caret is the model's: the projector shows it once the block mounts.
|
|
222
228
|
if (target?.firstText)
|
|
223
229
|
dispatcher.caret(target.firstText, 0);
|
|
@@ -230,7 +236,7 @@ export class BlockHandleController {
|
|
|
230
236
|
if (facade.version !== added || (result !== false && last?.status !== 'refused'))
|
|
231
237
|
return result;
|
|
232
238
|
refused =
|
|
233
|
-
last?.status === 'refused' ? last : { operation: '
|
|
239
|
+
last?.status === 'refused' ? last : { operation: 'insertBlocks', status: 'refused' };
|
|
234
240
|
// The take-back of this command's own uncommitted write, not a user command.
|
|
235
241
|
if (!reused)
|
|
236
242
|
facade.apply(facade.prepare.deleteBlocks([target.id]));
|
|
@@ -261,7 +267,7 @@ export class BlockHandleController {
|
|
|
261
267
|
* block's first line — and the `+` holds that one (its menu's Escape
|
|
262
268
|
* gives it back).
|
|
263
269
|
*/
|
|
264
|
-
ungrip() {
|
|
270
|
+
#ungrip() {
|
|
265
271
|
const { gripped } = this;
|
|
266
272
|
this.gripped = null;
|
|
267
273
|
const { selection, facade } = this.edytor;
|
|
@@ -308,8 +314,8 @@ export class BlockHandleController {
|
|
|
308
314
|
});
|
|
309
315
|
}
|
|
310
316
|
for (const [node, target] of this.targets)
|
|
311
|
-
this
|
|
312
|
-
this
|
|
317
|
+
this.#registerDropTarget(node, target);
|
|
318
|
+
this.#registerDropTarget(element.ownerDocument.body, null);
|
|
313
319
|
this.scrolling?.();
|
|
314
320
|
this.scrolling = root ? autoScrollFor(root, (data) => data.owner === this.owner) : null;
|
|
315
321
|
this.indicator.begin(element.ownerDocument);
|
|
@@ -349,7 +355,7 @@ export class BlockHandleController {
|
|
|
349
355
|
return () => { };
|
|
350
356
|
this.targets.set(node, target);
|
|
351
357
|
if (this.dragging)
|
|
352
|
-
this
|
|
358
|
+
this.#registerDropTarget(node, target);
|
|
353
359
|
return () => {
|
|
354
360
|
if (this.targets.get(node) === target)
|
|
355
361
|
this.targets.delete(node);
|
|
@@ -359,9 +365,20 @@ export class BlockHandleController {
|
|
|
359
365
|
this.indicator.clear();
|
|
360
366
|
};
|
|
361
367
|
}
|
|
362
|
-
|
|
368
|
+
/**
|
|
369
|
+
* A block's drop target (`target`), or the page's (`body`, `null`): the
|
|
370
|
+
* editor's margins (Notion, `dnd.reach`), a drop target only where
|
|
371
|
+
* `margin` gives a placement — the handle column left of the blocks, the
|
|
372
|
+
* page margin past it and the one right of the content, up to the drop
|
|
373
|
+
* reach, within the editor's height — so a row is reached from outside it
|
|
374
|
+
* too, row after row; anywhere else the block targets (and their
|
|
375
|
+
* stickiness) stand, and a block target holding the pointer (its sticky
|
|
376
|
+
* slop) answers before the page.
|
|
377
|
+
*/
|
|
378
|
+
#registerDropTarget(node, target) {
|
|
363
379
|
if (this.registered.has(node))
|
|
364
380
|
return;
|
|
381
|
+
const show = ({ location, source }) => this.#showIndicator(node, location, source.data);
|
|
365
382
|
const cleanup = dropTargetForElements({
|
|
366
383
|
element: node,
|
|
367
384
|
// A beside band counts: a row whose halves are both refused still takes it.
|
|
@@ -370,25 +387,28 @@ export class BlockHandleController {
|
|
|
370
387
|
// row at the pointer's height (`margin`): never a placement held from
|
|
371
388
|
// a row passed on the way.
|
|
372
389
|
canDrop: ({ source, input }) => {
|
|
373
|
-
|
|
390
|
+
const dragSource = this.#getDragSource(source.data);
|
|
391
|
+
if (!dragSource)
|
|
392
|
+
return false;
|
|
393
|
+
if (!target)
|
|
394
|
+
return Boolean(this.drop.margin(this.#drag(dragSource), input));
|
|
395
|
+
if (this.drop.inHandleColumn(input.clientX))
|
|
374
396
|
return false;
|
|
375
|
-
const row = this.rowAt(
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
return Boolean(dragSource && this.beside(dragSource, row, input));
|
|
397
|
+
const row = this.drop.rowAt(this.#drag(dragSource), target, node, input);
|
|
398
|
+
const { before, after } = this.drop.zones(this.#drag(dragSource), row, input);
|
|
399
|
+
return ([...before, ...after].some(this.#drag(dragSource).fits) ||
|
|
400
|
+
Boolean(this.drop.beside(this.#drag(dragSource), row, input)));
|
|
380
401
|
},
|
|
381
|
-
//
|
|
382
|
-
//
|
|
383
|
-
//
|
|
402
|
+
// The row at the pointer and the half of its own row (not its subtree's)
|
|
403
|
+
// the pointer is in: held while the target is sticky (the drag library
|
|
404
|
+
// keeps a sticky record's data).
|
|
384
405
|
getData: ({ source, input }) => {
|
|
385
|
-
const
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
});
|
|
406
|
+
const dragSource = this.#getDragSource(source.data);
|
|
407
|
+
if (!target || !dragSource)
|
|
408
|
+
return { [MARGIN]: true };
|
|
409
|
+
const row = this.drop.rowAt(this.#drag(dragSource), target, node, input);
|
|
410
|
+
const rect = ownRow(row.node);
|
|
411
|
+
return { [ROW]: row.id, [BEFORE]: input.clientY < rect.top + rect.height / 2 };
|
|
392
412
|
},
|
|
393
413
|
// Held while it or a target inside it holds the placement (the drag library
|
|
394
414
|
// keeps an inner target only while every outer one of its chain sticks),
|
|
@@ -396,20 +416,19 @@ export class BlockHandleController {
|
|
|
396
416
|
// the way down (Notion) — never over another block's own row (its parent's,
|
|
397
417
|
// which the drag library would otherwise let it keep), nor over another column.
|
|
398
418
|
getIsSticky: ({ source, input }) => {
|
|
399
|
-
const dragSource = this.getDragSource(source.data);
|
|
400
419
|
const active = this.indicator.target;
|
|
401
|
-
if (!
|
|
420
|
+
if (!target || !this.#getDragSource(source.data) || !active || !node.contains(active))
|
|
402
421
|
return false;
|
|
403
422
|
const rect = node.getBoundingClientRect();
|
|
404
423
|
return (input.clientX >= rect.left - SLOP_X &&
|
|
405
424
|
input.clientX <= rect.right + SLOP_X &&
|
|
406
425
|
input.clientY >= rect.top - SLOP_Y &&
|
|
407
426
|
(input.clientY <= rect.bottom + SLOP_Y || endsDocument(target)) &&
|
|
408
|
-
!this.overOtherColumn(target, input.clientX) &&
|
|
427
|
+
!this.drop.overOtherColumn(target, input.clientX) &&
|
|
409
428
|
!overOtherRow(node, input, (over) => !this.edytor.idToBlock.get(over.dataset.edytorId ?? '')?.isContainer));
|
|
410
429
|
},
|
|
411
|
-
onDragEnter:
|
|
412
|
-
onDrag:
|
|
430
|
+
onDragEnter: show,
|
|
431
|
+
onDrag: show,
|
|
413
432
|
// The target left hands the placement to the innermost one still current (an
|
|
414
433
|
// outer target of its chain that sticks), before the next move asks it to stick.
|
|
415
434
|
onDragLeave: ({ location, source }) => {
|
|
@@ -418,260 +437,62 @@ export class BlockHandleController {
|
|
|
418
437
|
this.indicator.clear();
|
|
419
438
|
const [current] = location.current.dropTargets;
|
|
420
439
|
if (current)
|
|
421
|
-
this
|
|
440
|
+
this.#showIndicator(current.element, location, source.data);
|
|
422
441
|
},
|
|
423
442
|
onDrop: ({ location, source }) => {
|
|
424
443
|
const [current] = location.current.dropTargets;
|
|
425
444
|
if (current?.element !== node)
|
|
426
445
|
return;
|
|
427
|
-
const dragSource = this
|
|
446
|
+
const dragSource = this.#getDragSource(source.data);
|
|
428
447
|
const placement = this.indicator.target === node && this.indicator.placement
|
|
429
448
|
? this.indicator.placement
|
|
430
|
-
: this.placement(current,
|
|
449
|
+
: dragSource && this.placement(current, dragSource, location.current.input);
|
|
431
450
|
this.indicator.clear();
|
|
432
|
-
if (dragSource
|
|
433
|
-
placement &&
|
|
434
|
-
this.canDrop(dragSource, placement.target, placement.position)) {
|
|
435
|
-
const moved = this.moveAndSelect({
|
|
436
|
-
blocks: this.moving(dragSource),
|
|
437
|
-
target: placement.target,
|
|
438
|
-
position: placement.position
|
|
439
|
-
});
|
|
440
|
-
if (moved.length && this.held)
|
|
441
|
-
this.edytor.history.began(this.held);
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
});
|
|
445
|
-
this.registered.set(node, cleanup);
|
|
446
|
-
}
|
|
447
|
-
/**
|
|
448
|
-
* The editor's margins (Notion, `dnd.reach`): during our drag, the page
|
|
449
|
-
* (`body`) is a drop target only where `margin` gives a placement — the
|
|
450
|
-
* handle column left of the blocks, the page margin past it and the one
|
|
451
|
-
* right of the content, up to the drop reach, within the editor's height
|
|
452
|
-
* (a beside band nearest the content, else the row's reorder) — so a row
|
|
453
|
-
* is reached from outside it too, row after row; anywhere else the block
|
|
454
|
-
* targets (and their stickiness) stand, and a block target holding the
|
|
455
|
-
* pointer (its sticky slop) answers before the page.
|
|
456
|
-
*/
|
|
457
|
-
registerMarginTarget(node) {
|
|
458
|
-
if (this.registered.has(node))
|
|
459
|
-
return;
|
|
460
|
-
const cleanup = dropTargetForElements({
|
|
461
|
-
element: node,
|
|
462
|
-
canDrop: ({ source, input }) => {
|
|
463
|
-
const dragSource = this.getDragSource(source.data);
|
|
464
|
-
return Boolean(dragSource && this.margin(dragSource, input));
|
|
465
|
-
},
|
|
466
|
-
getData: () => ({ [MARGIN]: true }),
|
|
467
|
-
onDragEnter: ({ location, source }) => this.showIndicator(node, location, source.data),
|
|
468
|
-
onDrag: ({ location, source }) => this.showIndicator(node, location, source.data),
|
|
469
|
-
onDragLeave: ({ location, source }) => {
|
|
470
|
-
if (this.indicator.target !== node)
|
|
451
|
+
if (!dragSource || !placement)
|
|
471
452
|
return;
|
|
472
|
-
|
|
473
|
-
const
|
|
474
|
-
if (
|
|
475
|
-
this.showIndicator(current.element, location, source.data);
|
|
476
|
-
},
|
|
477
|
-
onDrop: ({ location, source }) => {
|
|
478
|
-
const [current] = location.current.dropTargets;
|
|
479
|
-
if (current?.element !== node)
|
|
453
|
+
const { target, position } = placement;
|
|
454
|
+
const request = { blocks: this.moving(dragSource), target, position };
|
|
455
|
+
if (!this.edytor.canMove(request))
|
|
480
456
|
return;
|
|
481
|
-
const
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
: dragSource && this.margin(dragSource, location.current.input);
|
|
485
|
-
this.indicator.clear();
|
|
486
|
-
if (dragSource &&
|
|
487
|
-
placement &&
|
|
488
|
-
this.canDrop(dragSource, placement.target, placement.position)) {
|
|
489
|
-
const moved = this.moveAndSelect({
|
|
490
|
-
blocks: this.moving(dragSource),
|
|
491
|
-
target: placement.target,
|
|
492
|
-
position: placement.position
|
|
493
|
-
});
|
|
494
|
-
if (moved.length && this.held)
|
|
495
|
-
this.edytor.history.began(this.held);
|
|
496
|
-
}
|
|
457
|
+
const moved = this.#moveAndSelect(request);
|
|
458
|
+
if (moved.length && this.held)
|
|
459
|
+
this.edytor.history.began(this.held);
|
|
497
460
|
}
|
|
498
461
|
});
|
|
499
462
|
this.registered.set(node, cleanup);
|
|
500
463
|
}
|
|
501
|
-
/**
|
|
502
|
-
* The editor's content column (`start`…`end`, the root's content box:
|
|
503
|
-
* where its blocks' boxes start and end), the width of the handle column
|
|
504
|
-
* left of it (the drag's handle, measured: `+`, grip and the gap to the
|
|
505
|
-
* block) and how far the drag reaches past them (`dropReach`, the
|
|
506
|
-
* `--edytor-drop-reach` the root inherits).
|
|
507
|
-
*/
|
|
508
|
-
gutter(root) {
|
|
509
|
-
const style = root.ownerDocument.defaultView?.getComputedStyle(root);
|
|
510
|
-
const rect = root.getBoundingClientRect();
|
|
511
|
-
const px = (value) => parseFloat(value ?? '') || 0;
|
|
512
|
-
const start = rect.left + root.clientLeft + px(style?.paddingLeft);
|
|
513
|
-
const end = rect.right - px(style?.borderRightWidth) - px(style?.paddingRight);
|
|
514
|
-
const width = this.handle?.isConnected ? this.handle.getBoundingClientRect().width : 0;
|
|
515
|
-
return { start, end, handles: width > 0 ? width : HANDLE_COLUMN, reach: dropReach(style) };
|
|
516
|
-
}
|
|
517
|
-
/** Whether `x` is in the handle column left of the editor's blocks (`gutter`): the page target's. */
|
|
518
|
-
inHandleColumn(x) {
|
|
519
|
-
const root = this.edytor.node;
|
|
520
|
-
if (!root)
|
|
521
|
-
return false;
|
|
522
|
-
const { start, handles } = this.gutter(root);
|
|
523
|
-
return x < start && x >= start - handles;
|
|
524
|
-
}
|
|
525
|
-
/**
|
|
526
|
-
* A placement in the editor's margins at the pointer (`dnd.reach`), within
|
|
527
|
-
* the editor's height, for the row the content's near edge shows at the
|
|
528
|
-
* pointer's height (`rowAt`: a nested block's own row; over a layout, the
|
|
529
|
-
* row of its first column on the left, of its last on the right, never
|
|
530
|
-
* another), by the zone the pointer is in (`marginAt`):
|
|
531
|
-
* - the handle column left of the blocks (`gutter`): that row's reorder
|
|
532
|
-
* (`reorder`): a drag straight down the handles reorders, row after
|
|
533
|
-
* row, gaps included (never a beside band);
|
|
534
|
-
* - the first `BESIDE_MARGIN` px past it on the left, and past the
|
|
535
|
-
* content's right edge: the beside band of that side (`beside`, as if
|
|
536
|
-
* the pointer were at that edge) when the document has a layout kind
|
|
537
|
-
* and the row offers one (a refused band shows nothing);
|
|
538
|
-
* - elsewhere within the reach (and there without a band): the reorder,
|
|
539
|
-
* on the left the handle column's, on the right the one the row's
|
|
540
|
-
* right edge offers (`atRightEdge`).
|
|
541
|
-
* `undefined` past the reach, above or below the editor, and inside the
|
|
542
|
-
* content (the blocks' own targets answer there).
|
|
543
|
-
*/
|
|
544
|
-
margin(source, { clientX: x, clientY: y }) {
|
|
545
|
-
const root = this.edytor.node;
|
|
546
|
-
if (!root || this.edytor.readonly)
|
|
547
|
-
return undefined;
|
|
548
|
-
const box = root.getBoundingClientRect();
|
|
549
|
-
if (y < box.top || y > box.bottom)
|
|
550
|
-
return undefined;
|
|
551
|
-
const gutter = this.gutter(root);
|
|
552
|
-
const zone = marginAt(x, gutter);
|
|
553
|
-
if (!zone)
|
|
554
|
-
return undefined;
|
|
555
|
-
const right = zone.side === 'right';
|
|
556
|
-
const band = zone.zone === 'beside' && this.layouts;
|
|
557
|
-
const edge = right ? gutter.end - 1 : gutter.start + 1;
|
|
558
|
-
const hits = root.ownerDocument.elementsFromPoint?.(edge, y) ?? [];
|
|
559
|
-
const hit = hits.find((at) => {
|
|
560
|
-
const block = at.closest('[data-edytor-block="true"]');
|
|
561
|
-
return block && root.contains(block) && this.targets.has(block);
|
|
562
|
-
});
|
|
563
|
-
const node = hit?.closest('[data-edytor-block="true"]');
|
|
564
|
-
const target = node && this.targets.get(node);
|
|
565
|
-
// Between two rows where the margin reorders (a margin, a layout's
|
|
566
|
-
// edge), the reorder shown stays, as a block's sticky slop keeps it.
|
|
567
|
-
const shown = !band && this.indicator.target === root.ownerDocument.body;
|
|
568
|
-
const held = shown ? this.indicator.placement : null;
|
|
569
|
-
const stay = held && !isBeside(held.position) ? held : undefined;
|
|
570
|
-
if (!node || !target)
|
|
571
|
-
return stay;
|
|
572
|
-
const data = { owner: this.owner, blockId: source.id };
|
|
573
|
-
const { facade } = this.edytor;
|
|
574
|
-
let row = this.rowAt(data, target, node, { clientX: edge, clientY: y });
|
|
575
|
-
// Over a layout's edge, its first or last column's row at that height.
|
|
576
|
-
if (facade.isLayout(row.id)) {
|
|
577
|
-
const items = row.children.filter((item) => item.node && this.targets.has(item.node));
|
|
578
|
-
const rect = (right ? items.at(-1) : items[0])?.node?.getBoundingClientRect();
|
|
579
|
-
if (!rect || rect.width === 0)
|
|
580
|
-
return undefined;
|
|
581
|
-
const inner = right ? rect.right - 1 : rect.left + 1;
|
|
582
|
-
row = this.rowAt(data, target, node, { clientX: inner, clientY: y });
|
|
583
|
-
}
|
|
584
|
-
if (facade.isLayout(row.id) || !row.node)
|
|
585
|
-
return stay;
|
|
586
|
-
if (band) {
|
|
587
|
-
const aside = this.beside(source, row, { clientX: right ? Infinity : -Infinity, clientY: y }, zone.side);
|
|
588
|
-
// A band the document refuses shows nothing; a row offering none (a
|
|
589
|
-
// nested row on the left, a layout that would stack) reorders.
|
|
590
|
-
if (aside !== undefined)
|
|
591
|
-
return aside ?? undefined;
|
|
592
|
-
}
|
|
593
|
-
const input = { clientX: x, clientY: y };
|
|
594
|
-
const placement = right
|
|
595
|
-
? this.atRightEdge(source, row, input)
|
|
596
|
-
: this.reorder(source, row, input);
|
|
597
|
-
return placement ?? undefined;
|
|
598
|
-
}
|
|
599
|
-
/**
|
|
600
|
-
* Right of the content, the placement the row offers at its own right
|
|
601
|
-
* edge (`zones` there, by its own row's halves, as its drop target's
|
|
602
|
-
* hitbox splits it): the same before, after or inside as just inside the
|
|
603
|
-
* content, so nothing jumps as the pointer leaves it; `null` when no
|
|
604
|
-
* placement fits.
|
|
605
|
-
*/
|
|
606
|
-
atRightEdge(source, row, { clientX, clientY }) {
|
|
607
|
-
const rect = ownRow(row.node);
|
|
608
|
-
const { before, after } = this.zones(source, row, {
|
|
609
|
-
clientX: Math.min(clientX, rect.right - 1)
|
|
610
|
-
});
|
|
611
|
-
const halves = clientY < rect.top + rect.height / 2 ? [before, after] : [after, before];
|
|
612
|
-
const fits = this.fits(source);
|
|
613
|
-
const placement = halves.flat().find(fits);
|
|
614
|
-
return placement ? { ...placement, blocked: !halves[0].some(fits) } : null;
|
|
615
|
-
}
|
|
616
|
-
/**
|
|
617
|
-
* The handle column's reorder over `row` at the pointer: the hitbox's
|
|
618
|
-
* halves as its own drop target gives them (`zones`, the pointer's x
|
|
619
|
-
* picking the level), its own row's top half before, the bottom half
|
|
620
|
-
* after, only before or after a block — never inside one; `null` when
|
|
621
|
-
* neither half fits. Over an item of a container the dragged blocks do not
|
|
622
|
-
* fit in (a paragraph over a list's item: the document refuses every
|
|
623
|
-
* placement at the item's level), the container is the row: its whole box,
|
|
624
|
-
* the upper half before it, the lower half after it (round 4), so a drag
|
|
625
|
-
* down the handles meets the list as one row it can pass.
|
|
626
|
-
*/
|
|
627
|
-
reorder(source, row, input) {
|
|
628
|
-
const fits = this.fits(source);
|
|
629
|
-
const halvesOf = (row, rect) => {
|
|
630
|
-
const zones = this.zones(source, row, input);
|
|
631
|
-
const [before, after] = [zones.before, zones.after].map((half) => half.filter((placement) => placement.position !== 'inside'));
|
|
632
|
-
return input.clientY < rect.top + rect.height / 2 ? [before, after] : [after, before];
|
|
633
|
-
};
|
|
634
|
-
let halves = halvesOf(row, ownRow(row.node));
|
|
635
|
-
for (let at = row.parent; !halves[0].some(fits) && at?.node && !at.isRoot && at.isContainer; at = at.parent)
|
|
636
|
-
halves = halvesOf(at, at.node.getBoundingClientRect());
|
|
637
|
-
const placement = halves.flat().find(fits);
|
|
638
|
-
return placement ? { ...placement, blocked: !halves[0].some(fits) } : null;
|
|
639
|
-
}
|
|
640
464
|
/**
|
|
641
465
|
* Alt+arrow: one step for the blocks a drag of this handle moves. A text
|
|
642
466
|
* range over them stays, as Mod+Shift+arrow keeps it; else they end
|
|
643
|
-
* selected as after a drop (
|
|
467
|
+
* selected as after a drop (`#moveAndSelect`).
|
|
644
468
|
*/
|
|
645
|
-
handleKeyDown(event, block) {
|
|
469
|
+
#handleKeyDown(event, block) {
|
|
646
470
|
const direction = event.altKey ? keyMoves[event.key] : undefined;
|
|
647
471
|
if (this.edytor.readonly || !direction)
|
|
648
472
|
return;
|
|
649
473
|
event.preventDefault();
|
|
650
474
|
event.stopPropagation();
|
|
651
475
|
const request = { blocks: this.dragBlocks(block), direction };
|
|
652
|
-
if (this
|
|
653
|
-
this.edytor.
|
|
476
|
+
if (this.#covered(block)?.range)
|
|
477
|
+
this.edytor.move(request);
|
|
654
478
|
else
|
|
655
|
-
this
|
|
479
|
+
this.#moveAndSelect(request);
|
|
656
480
|
}
|
|
657
481
|
/**
|
|
658
482
|
* Move, then select what moved — the drag's rule (`onDragStart`): a group
|
|
659
483
|
* the block selection holds keeps it (a moved block's selected children
|
|
660
484
|
* too); any other group ends selected alone.
|
|
661
485
|
*/
|
|
662
|
-
moveAndSelect(request) {
|
|
486
|
+
#moveAndSelect(request) {
|
|
663
487
|
const { selectedBlocks } = this.edytor.selection;
|
|
664
488
|
// A layout the selection covers whole counts as held: its blocks stay selected.
|
|
665
489
|
const holds = holdsBlocks(selectedBlocks, request.blocks);
|
|
666
490
|
const before = holds ? [...selectedBlocks] : [];
|
|
667
|
-
const moved = this.edytor.
|
|
491
|
+
const moved = this.edytor.move(request);
|
|
668
492
|
if (moved.length)
|
|
669
493
|
selectMoved(this.edytor, moved, before);
|
|
670
494
|
return moved;
|
|
671
495
|
}
|
|
672
|
-
canDrop(source, target, position) {
|
|
673
|
-
return this.edytor.canMoveBlocks({ blocks: this.moving(source), target, position });
|
|
674
|
-
}
|
|
675
496
|
/** The blocks a drop of `source` moves: the drag's own group, fixed when it started. */
|
|
676
497
|
moving(source) {
|
|
677
498
|
// A member a collaborator deleted meanwhile is left out; the others still move.
|
|
@@ -682,23 +503,19 @@ export class BlockHandleController {
|
|
|
682
503
|
* The blocks the selection covers — a block selection's blocks as
|
|
683
504
|
* clicked (a selected list is one block: its item's handle drags the
|
|
684
505
|
* item), or the blocks a text range spans (`getSelectionBlocks`, the
|
|
685
|
-
* resolver Tab and Turn into read), a code line as its code
|
|
686
|
-
* (`movable`) — when `source` is one of them; else
|
|
506
|
+
* resolver Tab and Turn into read; `range`), a code line as its code
|
|
507
|
+
* block (`movable`) — when `source` is one of them; else none.
|
|
687
508
|
*/
|
|
688
|
-
covered(source) {
|
|
689
|
-
const { selectedBlocks,
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
/** Whether a text range (no block selection) covers `source` (`covered`). */
|
|
696
|
-
inRange(source) {
|
|
697
|
-
const { selectedBlocks, state } = this.edytor.selection;
|
|
698
|
-
return (!selectedBlocks.size &&
|
|
699
|
-
!state.isCollapsed &&
|
|
700
|
-
movable(getSelectionBlocks(this.edytor)).includes(source));
|
|
509
|
+
#covered(source) {
|
|
510
|
+
const { selectedBlocks, projection } = this.edytor.selection;
|
|
511
|
+
const range = !selectedBlocks.size;
|
|
512
|
+
if (range && projection.isCollapsed)
|
|
513
|
+
return null;
|
|
514
|
+
const covered = movable(range ? getSelectionBlocks(this.edytor) : selectedBlocks);
|
|
515
|
+
return covered.includes(source) ? { covered, range } : null;
|
|
701
516
|
}
|
|
517
|
+
/** The blocks the selection covers when `source` is one of them, else `source` alone. */
|
|
518
|
+
covered = (source) => this.#covered(source)?.covered ?? [source];
|
|
702
519
|
/**
|
|
703
520
|
* The blocks a drag (or an Alt+arrow) from `source`'s handle moves
|
|
704
521
|
* (Notion): the outermost of those the selection covers (`covered`), in
|
|
@@ -715,277 +532,45 @@ export class BlockHandleController {
|
|
|
715
532
|
*/
|
|
716
533
|
select(source) {
|
|
717
534
|
const { selection } = this.edytor;
|
|
718
|
-
selection.
|
|
719
|
-
|
|
720
|
-
/** Whether the drag of `source` may land at a placement. */
|
|
721
|
-
fits = (source) => (placement) => this.canDrop(source, placement.target, placement.position);
|
|
722
|
-
/**
|
|
723
|
-
* The hitbox's operations over `row` for our drag: reorder-before and
|
|
724
|
-
* reorder-after, each `blocked` when the document refuses every
|
|
725
|
-
* placement of that half (`zones`), none outside our drag.
|
|
726
|
-
*/
|
|
727
|
-
operations(data, row, input) {
|
|
728
|
-
const source = this.getDragSource(data);
|
|
729
|
-
if (!source || this.edytor.readonly)
|
|
730
|
-
return {};
|
|
731
|
-
const { before, after } = this.zones(source, row, input);
|
|
732
|
-
const offer = (half) => half.some(this.fits(source)) ? 'available' : 'blocked';
|
|
733
|
-
return { 'reorder-before': offer(before), 'reorder-after': offer(after) };
|
|
734
|
-
}
|
|
735
|
-
/**
|
|
736
|
-
* The block whose row the pointer is on over `node`: the last shown drop
|
|
737
|
-
* target in it whose row starts at or above the pointer (beside a nested
|
|
738
|
-
* block, over its ancestors' indent, the pointer is on that block's
|
|
739
|
-
* row), else `target`, over its own row (`emptied`). A layout's columns
|
|
740
|
-
* sit side by side: only the one under the pointer is measured (between
|
|
741
|
-
* two of them, the layout is the row: its gap).
|
|
742
|
-
*/
|
|
743
|
-
rowAt(data, target, node, { clientX, clientY }) {
|
|
744
|
-
const source = this.getDragSource(data);
|
|
745
|
-
const lift = (row) => (source ? this.emptied(source, row) : row);
|
|
746
|
-
if (clientY < getOwnRowBottom(node))
|
|
747
|
-
return lift(target);
|
|
748
|
-
const { facade } = this.edytor;
|
|
749
|
-
let row = target;
|
|
750
|
-
let aside = null;
|
|
751
|
-
// In document order, rows start lower and lower (within a column): measure
|
|
752
|
-
// none below the pointer, none a closed toggle hides (each read would force
|
|
753
|
-
// a layout), and nothing in a column the pointer is not over.
|
|
754
|
-
for (const inner of node.querySelectorAll('[data-edytor-block="true"]')) {
|
|
755
|
-
if (aside?.contains(inner))
|
|
756
|
-
continue;
|
|
757
|
-
const block = this.targets.get(inner);
|
|
758
|
-
if (!block || inner.closest(HIDDEN))
|
|
759
|
-
continue;
|
|
760
|
-
const rect = inner.getBoundingClientRect();
|
|
761
|
-
if (facade.isLayoutItem(block.id) && (clientX < rect.left || clientX > rect.right)) {
|
|
762
|
-
aside = inner;
|
|
763
|
-
continue;
|
|
764
|
-
}
|
|
765
|
-
if (rect.top > clientY)
|
|
766
|
-
break;
|
|
767
|
-
if (rect.height > 0)
|
|
768
|
-
row = block;
|
|
769
|
-
}
|
|
770
|
-
return lift(row);
|
|
535
|
+
const blocks = selection.selectedBlocks.size ? [source] : this.covered(source);
|
|
536
|
+
selection.select(blockSelection(blocks.map((block) => block.id)));
|
|
771
537
|
}
|
|
772
|
-
/**
|
|
773
|
-
|
|
774
|
-
for (const definition of this.edytor.blocks.values())
|
|
775
|
-
if (definition.layout)
|
|
776
|
-
return true;
|
|
777
|
-
return false;
|
|
778
|
-
}
|
|
779
|
-
/**
|
|
780
|
-
* The block a beside placement over `block` stands beside: the document's
|
|
781
|
-
* own resolution (`facade.besideAt`, `placeBeside`'s): a list item's list,
|
|
782
|
-
* a code line's code block, a toggle's child itself, an item itself.
|
|
783
|
-
*/
|
|
784
|
-
besideOf(block) {
|
|
785
|
-
return this.edytor.idToBlock.get(this.edytor.facade.besideAt(block.id)) ?? block;
|
|
786
|
-
}
|
|
787
|
-
/** The item (and its layout) a beside placement at `outer` (`besideOf`) adds a column beside. */
|
|
788
|
-
layoutOf(outer) {
|
|
789
|
-
const { facade } = this.edytor;
|
|
790
|
-
const item = facade.isLayoutItem(outer.id)
|
|
791
|
-
? outer
|
|
792
|
-
: outer.parent && !outer.parent.isRoot && facade.isLayoutItem(outer.parent.id)
|
|
793
|
-
? outer.parent
|
|
794
|
-
: null;
|
|
795
|
-
return item ? { item, layout: item.parent ?? null } : null;
|
|
796
|
-
}
|
|
797
|
-
/**
|
|
798
|
-
* Whether `x` is over a column other than one holding `block`: a sticky
|
|
799
|
-
* target never holds the pointer across a column boundary.
|
|
800
|
-
*/
|
|
801
|
-
overOtherColumn(block, x) {
|
|
802
|
-
const { facade } = this.edytor;
|
|
803
|
-
for (let at = block; at && !at.isRoot; at = at.parent) {
|
|
804
|
-
if (!facade.isLayoutItem(at.id))
|
|
805
|
-
continue;
|
|
806
|
-
const item = at;
|
|
807
|
-
const over = item.parent?.children.some((other) => {
|
|
808
|
-
const rect = other !== item ? other.node?.getBoundingClientRect() : undefined;
|
|
809
|
-
return rect !== undefined && rect.width > 0 && x >= rect.left && x <= rect.right;
|
|
810
|
-
});
|
|
811
|
-
if (over)
|
|
812
|
-
return true;
|
|
813
|
-
}
|
|
814
|
-
return false;
|
|
815
|
-
}
|
|
816
|
-
/**
|
|
817
|
-
* Notion's beside bands over `row` (`docs/columns-plan.md`, "View layer"), only while the
|
|
818
|
-
* pointer is within its own row's height, the document has a layout kind
|
|
819
|
-
* and the layout the drop makes or grows does not stack (`stacks`):
|
|
820
|
-
* - right: the row's last 15% (at least 32px), and the slop past it;
|
|
821
|
-
* - left: the slop left of the row (its sticky margin, left of its text
|
|
822
|
-
* column), only for a row whose parent is the root or a column (a
|
|
823
|
-
* list's item: its list's) — a nested row keeps the pointer's x for its
|
|
824
|
-
* levels (`zones`) — and only
|
|
825
|
-
* inside the editor (a column's gap): left of the editor's blocks is the
|
|
826
|
-
* handle column, which reorders (`margin`);
|
|
827
|
-
* - over a layout's gap (the row is the layout): right of the column
|
|
828
|
-
* before it, a new column between.
|
|
829
|
-
* `undefined` outside the bands (the hitbox's halves stand), else the
|
|
830
|
-
* placement, or `null` when the document refuses it: a refused band shows
|
|
831
|
-
* nothing.
|
|
832
|
-
*/
|
|
833
|
-
beside(source, row, { clientX: x, clientY: y }, band) {
|
|
834
|
-
if (!row.node || this.edytor.readonly || !this.layouts)
|
|
835
|
-
return undefined;
|
|
538
|
+
/** The drag of `source`: the blocks it moves, and the placements the document takes for them. */
|
|
539
|
+
#drag(source) {
|
|
836
540
|
const group = this.moving(source);
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
let placement;
|
|
841
|
-
if (facade.isLayout(row.id)) {
|
|
842
|
-
const rect = row.node.getBoundingClientRect();
|
|
843
|
-
if (y < rect.top || y > rect.bottom || stacks(rect.width))
|
|
844
|
-
return undefined;
|
|
845
|
-
const items = row.children.filter((item) => item.node && this.targets.has(item.node));
|
|
846
|
-
for (const [index, item] of items.entries()) {
|
|
847
|
-
const next = items[index + 1]?.node?.getBoundingClientRect();
|
|
848
|
-
const own = item.node.getBoundingClientRect();
|
|
849
|
-
if (next && x >= own.right && x <= next.left)
|
|
850
|
-
placement = { target: item, node: item.node, position: 'right' };
|
|
851
|
-
}
|
|
852
|
-
}
|
|
853
|
-
else {
|
|
854
|
-
const rect = ownRow(row.node);
|
|
855
|
-
if (y < rect.top || y > rect.bottom)
|
|
856
|
-
return undefined;
|
|
857
|
-
const outer = this.besideOf(row);
|
|
858
|
-
const width = (this.layoutOf(outer)?.layout ?? outer).node?.getBoundingClientRect().width;
|
|
859
|
-
if (width === undefined || stacks(width))
|
|
860
|
-
return undefined;
|
|
861
|
-
// A container's item (a list's) stands at its container's level, as the
|
|
862
|
-
// document resolves it (`besideAt`): left of a root list's item is left of the list.
|
|
863
|
-
let at = row;
|
|
864
|
-
while (at.parent &&
|
|
865
|
-
!at.parent.isRoot &&
|
|
866
|
-
at.parent.isContainer &&
|
|
867
|
-
!facade.isLayoutItem(at.parent.id))
|
|
868
|
-
at = at.parent;
|
|
869
|
-
const parent = at.parent;
|
|
870
|
-
const level = !parent || parent.isRoot || facade.isLayoutItem(parent.id);
|
|
871
|
-
if (band === 'right' ||
|
|
872
|
-
(!band && x >= rect.right - Math.max(RIGHT_BAND_MIN, rect.width * RIGHT_BAND)))
|
|
873
|
-
placement = { target: row, node: row.node, position: 'right' };
|
|
874
|
-
else if (level &&
|
|
875
|
-
(band === 'left' ||
|
|
876
|
-
(!band && x < rect.left && x >= rect.left - SLOP_X && x >= this.inside(rect.left))))
|
|
877
|
-
placement = { target: row, node: row.node, position: 'left' };
|
|
878
|
-
}
|
|
879
|
-
if (!placement)
|
|
880
|
-
return undefined;
|
|
881
|
-
return this.fits(source)(placement) ? placement : null;
|
|
882
|
-
}
|
|
883
|
-
/** Where the editor's blocks start (`gutter`), or `fallback` without a host. */
|
|
884
|
-
inside(fallback) {
|
|
885
|
-
const root = this.edytor.node;
|
|
886
|
-
return root ? this.gutter(root).start : fallback;
|
|
887
|
-
}
|
|
888
|
-
/** The children a block shows: none for a closed toggle's, or a container's items. */
|
|
889
|
-
shown(block) {
|
|
890
|
-
return block.isContainer
|
|
891
|
-
? []
|
|
892
|
-
: block.children.filter((child) => child.node && this.targets.has(child.node) && !hidden(child));
|
|
893
|
-
}
|
|
894
|
-
/**
|
|
895
|
-
* Over a dragged block, the parent it leaves when that parent shows no
|
|
896
|
-
* other child: the gap under the parent's own row, which reparents as
|
|
897
|
-
* the parent's lower half does (`zones`). Else `row`.
|
|
898
|
-
*/
|
|
899
|
-
emptied(source, row) {
|
|
900
|
-
const group = this.moving(source);
|
|
901
|
-
const parent = group.find((moved) => moved === row || row.isChildOf(moved))?.parent;
|
|
902
|
-
if (!parent?.node || parent.isRoot || !this.targets.has(parent.node))
|
|
903
|
-
return row;
|
|
904
|
-
const shown = this.shown(parent);
|
|
905
|
-
return shown.length && shown.every((child) => group.includes(child)) ? parent : row;
|
|
906
|
-
}
|
|
907
|
-
/**
|
|
908
|
-
* The placements over `row`, each half's in preference order (a refused
|
|
909
|
-
* one gives way to the next, then to the other half's):
|
|
910
|
-
* - the top half: before it;
|
|
911
|
-
* - the bottom half of a block whose children show (not a closed toggle):
|
|
912
|
-
* its first child's slot. Pragmatic drag and drop's tree rule: an
|
|
913
|
-
* expanded item offers no "after" on its own row;
|
|
914
|
-
* - else, after it at the level whose text column is nearest the pointer:
|
|
915
|
-
* the last block of a nested group reparents to any ancestor it ends,
|
|
916
|
-
* down to the root. Past one nesting step right of its text start,
|
|
917
|
-
* inside it (its last child) first. A block every shown child of which
|
|
918
|
-
* is dragged is not expanded: its levels, never inside it when the drag
|
|
919
|
-
* moves only its children (they would stay where they are).
|
|
920
|
-
* None over a dragged block's own row or its subtree: released there, the
|
|
921
|
-
* drag changes nothing (its levels would outdent it) — unless it empties
|
|
922
|
-
* its parent's shown children (`emptied`): that parent's row. Over the
|
|
923
|
-
* hint of the row's empty body (`body.hint`: an open toggle's, a
|
|
924
|
-
* callout's), inside it first, either half.
|
|
925
|
-
*/
|
|
926
|
-
zones(source, row, { clientX, clientY }) {
|
|
927
|
-
const group = this.moving(source);
|
|
928
|
-
if (group.some((moved) => moved === row || row.isChildOf(moved)))
|
|
929
|
-
return { before: [], after: [] };
|
|
930
|
-
const at = (target, position) => target?.node ? [{ target, node: target.node, position }] : [];
|
|
931
|
-
const before = at(row, 'before');
|
|
932
|
-
const shown = this.shown(row);
|
|
933
|
-
const first = shown.find((child) => !group.includes(child));
|
|
934
|
-
if (first)
|
|
935
|
-
return { before, after: at(first, 'before') };
|
|
936
|
-
// A group moved out from under its parent leaves the block before it last.
|
|
937
|
-
const next = (block) => {
|
|
938
|
-
let next = block.nextBlock;
|
|
939
|
-
while (next && group.includes(next))
|
|
940
|
-
next = next.nextBlock;
|
|
941
|
-
return next;
|
|
541
|
+
return {
|
|
542
|
+
group,
|
|
543
|
+
fits: ({ target, position }) => this.edytor.canMove({ blocks: group, target, position })
|
|
942
544
|
};
|
|
943
|
-
const levels = [row];
|
|
944
|
-
for (let level = row; !next(level) && level.parent?.node && !level.parent.isRoot;)
|
|
945
|
-
levels.push((level = level.parent));
|
|
946
|
-
const distance = (level) => Math.abs(column(level) - clientX);
|
|
947
|
-
const after = levels
|
|
948
|
-
.sort((a, b) => distance(a) - distance(b))
|
|
949
|
-
.flatMap((level) => at(level, 'after'));
|
|
950
|
-
const stays = shown.length > 0 && group.every((moved) => moved.parent === row);
|
|
951
|
-
const inside = stays ? [] : at(row, 'inside');
|
|
952
|
-
if (clientY !== undefined && overEmptyBody(row.node, clientY))
|
|
953
|
-
return { before: [...inside, ...before], after: [...inside, ...after] };
|
|
954
|
-
const nests = clientX > column(row) + nestIndent(row.node);
|
|
955
|
-
return { before, after: nests ? [...inside, ...after] : [...after, ...inside] };
|
|
956
545
|
}
|
|
957
546
|
/**
|
|
958
|
-
* The placement a drop target record offers:
|
|
959
|
-
* first (`beside`; `false` when
|
|
960
|
-
*
|
|
961
|
-
* sticky), the pointer
|
|
547
|
+
* The placement a drop target record offers: the page's margins
|
|
548
|
+
* (`margin`), else a beside band of the row first (`beside`; `false` when
|
|
549
|
+
* the document refuses it: nothing shows), else the row's halves, the one
|
|
550
|
+
* the record took first (held while the target is sticky), the pointer
|
|
551
|
+
* live.
|
|
962
552
|
*/
|
|
963
|
-
placement(record,
|
|
964
|
-
const
|
|
553
|
+
placement(record, source, input) {
|
|
554
|
+
const drag = this.#drag(source);
|
|
965
555
|
if (record.data[MARGIN])
|
|
966
|
-
return
|
|
967
|
-
const instruction = extractInstruction(record.data);
|
|
556
|
+
return this.drop.margin(drag, input) ?? false;
|
|
968
557
|
const row = this.edytor.idToBlock.get(record.data[ROW]);
|
|
969
|
-
if (!
|
|
558
|
+
if (!row?.node)
|
|
970
559
|
return null;
|
|
971
|
-
|
|
972
|
-
if (aside !== undefined)
|
|
973
|
-
return aside ?? false;
|
|
974
|
-
const { before, after } = this.zones(source, row, input);
|
|
975
|
-
const halves = instruction.operation === 'reorder-before' ? [before, after] : [after, before];
|
|
976
|
-
const placement = halves.flat().find(this.fits(source));
|
|
977
|
-
return placement ? { ...placement, blocked: instruction.blocked } : null;
|
|
560
|
+
return this.drop.at(drag, row, input, Boolean(record.data[BEFORE]));
|
|
978
561
|
}
|
|
979
|
-
|
|
980
|
-
|
|
562
|
+
/** The block our drag moves from (none in a read-only view). */
|
|
563
|
+
#getDragSource(data) {
|
|
564
|
+
if (data.owner !== this.owner || typeof data.blockId !== 'string' || this.edytor.readonly)
|
|
981
565
|
return null;
|
|
982
566
|
return this.edytor.idToBlock.get(data.blockId) ?? null;
|
|
983
567
|
}
|
|
984
|
-
showIndicator(node, location, data) {
|
|
568
|
+
#showIndicator(node, location, data) {
|
|
985
569
|
const [current] = location.current.dropTargets;
|
|
986
570
|
if (current?.element !== node)
|
|
987
571
|
return;
|
|
988
|
-
const
|
|
572
|
+
const source = this.#getDragSource(data);
|
|
573
|
+
const placement = source && this.placement(current, source, location.current.input);
|
|
989
574
|
// A refused beside band shows nothing.
|
|
990
575
|
if (placement === false)
|
|
991
576
|
return this.indicator.clear();
|