edytor 1.0.0-rc.2 → 1.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 +65 -25
- package/dist/block/block.svelte.d.ts +10 -85
- package/dist/block/block.svelte.js +47 -141
- 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 +8 -10
- package/dist/block/inlineBlock.svelte.js +14 -22
- package/dist/clipboard/createClipboardFragment.js +22 -64
- package/dist/clipboard/fragmentData.js +17 -42
- package/dist/clipboard/htmlFlow.d.ts +6 -1
- package/dist/clipboard/htmlFlow.js +26 -13
- 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 +22 -17
- package/dist/cloudflare/DocumentRoom.js +10 -5
- package/dist/cloudflare/index.d.ts +1 -1
- package/dist/cloudflare/index.js +1 -1
- 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 +20 -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 +9 -30
- package/dist/cloudflare/room/storage.js +52 -104
- 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/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 +160 -119
- package/dist/components/Block.svelte.d.ts +8 -3
- package/dist/components/Content.svelte +91 -44
- package/dist/components/CustomMark.svelte +46 -0
- package/dist/components/CustomMark.svelte.d.ts +11 -0
- package/dist/components/Edytor.svelte +80 -95
- package/dist/components/Edytor.svelte.d.ts +8 -12
- package/dist/components/InlineBlock.svelte +4 -9
- package/dist/components/Mark.svelte +46 -35
- package/dist/components/Mark.svelte.d.ts +7 -0
- 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 +48 -14
- 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 +8 -13
- package/dist/crdt/data.js +30 -70
- 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 +1 -5
- package/dist/crdt/doc/reads.js +38 -49
- 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 +24 -115
- package/dist/crdt/document.js +207 -305
- package/dist/crdt/edytor-doc.d.ts +671 -90
- package/dist/crdt/edytor-doc.js +73 -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 +26 -85
- package/dist/crdt/index.js +21 -47
- package/dist/crdt/operations.d.ts +24 -33
- package/dist/crdt/operations.js +7 -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/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/{plugins/blockHandles → dnd}/autoScroll.d.ts +2 -1
- package/dist/{plugins/blockHandles → dnd}/autoScroll.js +3 -3
- 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 +34 -64
- package/dist/edytor.svelte.js +118 -180
- package/dist/events/beforeInputCommands.d.ts +6 -11
- package/dist/events/beforeInputCommands.js +189 -184
- 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 +33 -72
- package/dist/events/onFocus.d.ts +9 -4
- package/dist/events/onFocus.js +92 -72
- 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 +13 -1
- package/dist/events/onPaste.js +46 -76
- package/dist/index.d.ts +10 -13
- package/dist/index.js +3 -3
- package/dist/kinds.d.ts +4 -6
- package/dist/kinds.js +28 -27
- package/dist/labels.d.ts +91 -314
- package/dist/labels.js +180 -396
- 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 -151
- package/dist/plugins/blockHandles/BlockHandle.svelte.d.ts +2 -2
- package/dist/plugins/blockHandles/BlockHandleController.svelte.d.ts +63 -97
- package/dist/plugins/blockHandles/BlockHandleController.svelte.js +247 -268
- package/dist/plugins/blockHandles/BlockHandles.svelte +46 -29
- package/dist/plugins/blockHandles/BlockHandles.svelte.d.ts +2 -2
- package/dist/plugins/blockHandles/blockHandlesPlugin.d.ts +29 -23
- package/dist/plugins/blockHandles/blockHandlesPlugin.js +130 -162
- package/dist/plugins/blockHandles/dragPreview.d.ts +8 -6
- package/dist/plugins/blockHandles/dragPreview.js +20 -17
- package/dist/plugins/blockHandles/dropIndicator.js +52 -60
- package/dist/plugins/blockHandles/geometry.d.ts +46 -1
- package/dist/plugins/blockHandles/geometry.js +51 -4
- package/dist/plugins/blockMenu/BlockMenuController.svelte.d.ts +59 -28
- package/dist/plugins/blockMenu/BlockMenuController.svelte.js +180 -105
- 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 +79 -0
- package/dist/plugins/chrome.js +87 -0
- package/dist/plugins/code/CodeHeader.svelte +12 -58
- package/dist/plugins/code/CodeHeader.svelte.d.ts +1 -0
- package/dist/plugins/code/CodePlugin.svelte +75 -56
- package/dist/plugins/code/CodePlugin.svelte.d.ts +0 -2
- package/dist/plugins/code/LanguageMenu.svelte +25 -0
- package/dist/plugins/code/LanguageMenu.svelte.d.ts +9 -0
- package/dist/plugins/code/code.css +5 -100
- package/dist/plugins/code/header.svelte.d.ts +47 -0
- package/dist/plugins/code/header.svelte.js +141 -0
- package/dist/plugins/code/languageMenu.svelte.d.ts +84 -0
- package/dist/plugins/code/languageMenu.svelte.js +199 -0
- package/dist/plugins/code/languages.d.ts +21 -10
- package/dist/plugins/code/languages.js +39 -126
- package/dist/plugins/columns/ColumnResize.svelte +13 -25
- 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/resize.svelte.d.ts +14 -51
- package/dist/plugins/columns/resize.svelte.js +70 -164
- 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 -430
- package/dist/plugins/comments/CommentsSidebar.svelte.d.ts +6 -7
- package/dist/plugins/comments/commentsPlugin.d.ts +31 -10
- package/dist/plugins/comments/commentsPlugin.js +12 -10
- package/dist/plugins/equation/EquationEditor.svelte +18 -129
- package/dist/plugins/equation/EquationEditor.svelte.d.ts +2 -1
- package/dist/plugins/equation/EquationPlugin.svelte +123 -168
- package/dist/plugins/equation/EquationPlugin.svelte.d.ts +5 -3
- package/dist/plugins/equation/EquationView.svelte +20 -11
- package/dist/plugins/equation/equation.svelte.d.ts +74 -36
- package/dist/plugins/equation/equation.svelte.js +74 -66
- package/dist/plugins/equation/importUrl.d.ts +6 -0
- package/dist/plugins/equation/importUrl.js +6 -0
- package/dist/plugins/equation/katex.d.ts +8 -0
- package/dist/plugins/equation/katex.js +77 -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 +5 -151
- package/dist/plugins/image/ImagePlugin.svelte +49 -117
- package/dist/plugins/image/ImagePlugin.svelte.d.ts +1 -24
- 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 -57
- package/dist/plugins/image/controls.svelte.js +51 -174
- 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 +39 -24
- package/dist/plugins/index.js +30 -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 +6 -5
- package/dist/plugins/marquee/MarqueeBox.svelte +15 -0
- package/dist/plugins/marquee/MarqueeBox.svelte.d.ts +9 -0
- package/dist/plugins/marquee/MarqueeController.svelte.d.ts +46 -0
- package/dist/plugins/marquee/MarqueeController.svelte.js +243 -0
- package/dist/plugins/marquee/marquee.d.ts +33 -0
- package/dist/plugins/marquee/marquee.js +89 -0
- package/dist/plugins/marquee/marqueePlugin.d.ts +32 -0
- package/dist/plugins/marquee/marqueePlugin.js +68 -0
- package/dist/plugins/media/AudioPlugin.svelte +3 -88
- package/dist/plugins/media/AudioPlugin.svelte.d.ts +1 -4
- package/dist/plugins/media/BookmarkPlugin.svelte +124 -112
- package/dist/plugins/media/BookmarkPlugin.svelte.d.ts +20 -7
- package/dist/plugins/media/EmbedPlugin.svelte +93 -77
- package/dist/plugins/media/EmbedPlugin.svelte.d.ts +21 -9
- package/dist/plugins/media/EmptySlot.svelte +44 -0
- package/dist/plugins/media/EmptySlot.svelte.d.ts +25 -0
- package/dist/plugins/media/FilePlugin.svelte +35 -111
- package/dist/plugins/media/FilePlugin.svelte.d.ts +12 -4
- package/dist/plugins/media/MediaEmpty.svelte +55 -112
- package/dist/plugins/media/MediaEmpty.svelte.d.ts +26 -10
- package/dist/plugins/media/SourceBlock.svelte +164 -0
- package/dist/plugins/media/SourceBlock.svelte.d.ts +33 -0
- package/dist/plugins/media/VideoPlugin.svelte +4 -97
- package/dist/plugins/media/VideoPlugin.svelte.d.ts +2 -5
- package/dist/plugins/media/empty.svelte.d.ts +69 -0
- package/dist/plugins/media/empty.svelte.js +111 -0
- package/dist/plugins/media/media.d.ts +93 -30
- package/dist/plugins/media/media.js +79 -86
- package/dist/plugins/media/urlPaste.svelte.d.ts +9 -32
- package/dist/plugins/media/urlPaste.svelte.js +46 -75
- package/dist/plugins/mention/MentionPlugin.svelte +47 -124
- package/dist/plugins/mention/MentionPlugin.svelte.d.ts +11 -23
- 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 +52 -108
- package/dist/plugins/pageLink/PageLinkPlugin.svelte.d.ts +11 -23
- package/dist/plugins/planned.d.ts +10 -0
- package/dist/plugins/planned.js +12 -0
- package/dist/plugins/richtext/CalloutIcon.svelte +25 -0
- package/dist/plugins/richtext/CalloutIcon.svelte.d.ts +9 -0
- package/dist/plugins/richtext/CalloutIconPicker.svelte +26 -0
- package/dist/plugins/richtext/CalloutIconPicker.svelte.d.ts +9 -0
- package/dist/plugins/richtext/EmptyBody.svelte +25 -0
- package/dist/plugins/richtext/EmptyBody.svelte.d.ts +8 -0
- package/dist/plugins/richtext/RichTextControl.svelte +39 -0
- package/dist/plugins/richtext/RichTextControl.svelte.d.ts +8 -0
- package/dist/plugins/richtext/RichTextPlugin.svelte +272 -148
- package/dist/plugins/richtext/RichTextPlugin.svelte.d.ts +37 -18
- package/dist/plugins/richtext/TodoCheckbox.svelte +10 -21
- package/dist/plugins/richtext/TodoCheckbox.svelte.d.ts +0 -2
- package/dist/plugins/richtext/body.d.ts +9 -0
- package/dist/plugins/richtext/body.js +16 -0
- package/dist/plugins/richtext/calloutIcons.svelte.d.ts +97 -0
- package/dist/plugins/richtext/calloutIcons.svelte.js +214 -0
- 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/slashMenu/SlashMenuController.svelte.d.ts +18 -11
- package/dist/plugins/slashMenu/SlashMenuController.svelte.js +93 -35
- package/dist/plugins/slashMenu/slashMenuPlugin.d.ts +11 -24
- package/dist/plugins/slashMenu/slashMenuPlugin.js +27 -68
- package/dist/plugins/suggestions/SuggestionBars.svelte +32 -84
- package/dist/plugins/suggestions/SuggestionBars.svelte.d.ts +9 -3
- package/dist/plugins/suggestions/suggestionsPlugin.d.ts +10 -16
- package/dist/plugins/suggestions/suggestionsPlugin.js +9 -24
- package/dist/plugins/table/TableChrome.svelte +96 -127
- package/dist/plugins/table/TableChrome.svelte.d.ts +5 -1
- package/dist/plugins/table/TablePlugin.svelte +116 -171
- package/dist/plugins/table/TablePlugin.svelte.d.ts +0 -4
- package/dist/plugins/table/chrome.svelte.d.ts +110 -117
- package/dist/plugins/table/chrome.svelte.js +643 -289
- package/dist/plugins/table/ops.d.ts +47 -0
- package/dist/plugins/table/ops.js +233 -0
- package/dist/plugins/table/table.css +55 -134
- package/dist/plugins/table/table.d.ts +26 -7
- package/dist/plugins/table/table.js +23 -49
- 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 +29 -66
- package/dist/plugins/toolbar/ToolbarController.svelte.js +151 -76
- package/dist/plugins/toolbar/toolbarPlugin.d.ts +14 -13
- package/dist/plugins/toolbar/toolbarPlugin.js +28 -43
- package/dist/plugins/triggers/TriggerController.svelte.d.ts +6 -45
- package/dist/plugins/triggers/TriggerController.svelte.js +51 -96
- 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 +38 -20
- package/dist/plugins/uploads.svelte.js +39 -32
- package/dist/plugins.d.ts +167 -60
- package/dist/selection/domSelection.d.ts +13 -4
- package/dist/selection/domSelection.js +110 -183
- package/dist/selection/pointer.svelte.d.ts +12 -10
- package/dist/selection/pointer.svelte.js +154 -71
- 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 +263 -542
- package/dist/selection/selection.utils.d.ts +34 -11
- package/dist/selection/selection.utils.js +128 -247
- package/dist/selection/visibility.d.ts +11 -8
- package/dist/selection/visibility.js +23 -8
- package/dist/session/announcer.svelte.d.ts +2 -1
- package/dist/session/announcer.svelte.js +7 -3
- package/dist/session/attempt.d.ts +33 -39
- package/dist/session/attempt.js +61 -53
- package/dist/session/bindings.js +108 -139
- package/dist/session/commands.d.ts +47 -22
- package/dist/session/commands.js +206 -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 +15 -21
- package/dist/session/inputRules.js +75 -84
- package/dist/session/keymap.d.ts +1 -6
- package/dist/session/keymap.js +17 -20
- package/dist/session/moves.d.ts +10 -10
- package/dist/session/moves.js +31 -59
- package/dist/session/navigation.d.ts +18 -3
- package/dist/session/navigation.js +194 -153
- package/dist/session/ports.d.ts +7 -0
- package/dist/session/selection.d.ts +4 -3
- package/dist/session/selection.js +8 -0
- package/dist/session/suggestions.svelte.d.ts +1 -1
- package/dist/session/suggestions.svelte.js +64 -47
- 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 +32 -0
- package/dist/surface/lines.js +43 -0
- package/dist/surface/observer.svelte.d.ts +3 -20
- package/dist/surface/observer.svelte.js +73 -77
- package/dist/surface/overlay.d.ts +48 -6
- package/dist/surface/overlay.js +133 -23
- 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 +315 -126
- 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 -525
- package/dist/collaboration/history/HistoryPanel.svelte.d.ts +0 -7
- package/dist/collaboration/history/panel.d.ts +0 -43
- 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 -447
- 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 -116
- package/dist/plugins/image/ImageEmpty.svelte.d.ts +0 -12
- package/dist/plugins/keepInView.d.ts +0 -4
- package/dist/plugins/keepInView.js +0 -6
- package/dist/plugins/media/UrlPasteMenu.svelte +0 -83
- package/dist/plugins/media/UrlPasteMenu.svelte.d.ts +0 -7
- package/dist/plugins/richtext/labels.d.ts +0 -5
- package/dist/plugins/richtext/labels.js +0 -3
- package/dist/plugins/slashMenu/SlashMenu.svelte +0 -360
- package/dist/plugins/slashMenu/SlashMenu.svelte.d.ts +0 -11
- package/dist/plugins/toolbar/LinkCard.svelte +0 -118
- package/dist/plugins/toolbar/LinkCard.svelte.d.ts +0 -7
- package/dist/plugins/toolbar/Toolbar.svelte +0 -400
- package/dist/plugins/toolbar/Toolbar.svelte.d.ts +0 -9
- package/dist/plugins/triggers/TriggerMenu.svelte +0 -144
- package/dist/plugins/triggers/TriggerMenu.svelte.d.ts +0 -7
- package/dist/session/props.d.ts +0 -28
- package/dist/session/props.js +0 -162
- 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
|
@@ -1,5 +1,35 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { untrack } from 'svelte';
|
|
2
|
+
import { autoScrollFor } from '../../dnd/autoScroll.js';
|
|
3
|
+
import { draggable, dropTargetForElements, setCustomNativeDragPreview } from '../../dnd/pragmatic.js';
|
|
4
|
+
import { EDYTOR_BLOCK_DRAG_MIME } from '../../events/onDrop.js';
|
|
5
|
+
import { takeKeys } from '../../events/onFocus.js';
|
|
6
|
+
import { pin } from '../../surface/overlay.js';
|
|
7
|
+
import { attribute } from '../chrome.js';
|
|
8
|
+
import { ChromeList, holdKeys, menuKey, optionAttachment } from '../list.svelte.js';
|
|
9
|
+
import { BandDrag, bandKey } from '../bands.svelte.js';
|
|
10
|
+
import { all, listen } from '../../utils/listen.js';
|
|
11
|
+
import { dragPreview } from '../blockHandles/dragPreview.js';
|
|
2
12
|
import { caretCell, deleteColumn, deleteRows, gridOf, insertColumn, insertRow, moveColumn, moveRows, widthOf } from './table.js';
|
|
13
|
+
/** The drag data key naming the chrome a row's or a column's drag is from. */
|
|
14
|
+
const MOVE = Symbol('edytor table move');
|
|
15
|
+
/** How far past the table's box a drag still aims at it (the grips stand outside it). */
|
|
16
|
+
const GUTTER = 32;
|
|
17
|
+
const styleOf = (node) => node.ownerDocument.defaultView?.getComputedStyle(node);
|
|
18
|
+
/** A computed length in pixels, `0` when none. */
|
|
19
|
+
const px = (value) => Number.parseFloat(value ?? '') || 0;
|
|
20
|
+
/** The resolved widths of `grid`'s columns, as laid out (none where nothing is). */
|
|
21
|
+
const trackWidths = (grid) => (styleOf(grid)?.gridTemplateColumns ?? '')
|
|
22
|
+
.split(/\s+/)
|
|
23
|
+
.map(Number.parseFloat)
|
|
24
|
+
.filter(Number.isFinite);
|
|
25
|
+
/** The grid element of a table block. */
|
|
26
|
+
const gridNode = (table) => table?.node?.querySelector('[data-edytor-table-grid]');
|
|
27
|
+
/** A table's stored column entries (`data.columns`), each found by its column id. */
|
|
28
|
+
const entriesOf = (table) => {
|
|
29
|
+
const stored = table.edytor.facade.blockDataOf(table.id)?.columns;
|
|
30
|
+
return Array.isArray(stored) ? stored : [];
|
|
31
|
+
};
|
|
32
|
+
const entryIndex = (entries, id) => entries.findIndex((c) => c?.id === id);
|
|
3
33
|
/**
|
|
4
34
|
* The table's chrome (`table.*`), in the overlay: while the pointer is over
|
|
5
35
|
* a table of an editable view, a `+` under it (a row at its end) and one
|
|
@@ -11,410 +41,734 @@ import { caretCell, deleteColumn, deleteRows, gridOf, insertColumn, insertRow, m
|
|
|
11
41
|
* column's `data.columns[i].width` (one command, one undo step), Escape
|
|
12
42
|
* drops the preview. Every action is a table command (`table.ts`): refused
|
|
13
43
|
* when the view is readonly.
|
|
44
|
+
*
|
|
45
|
+
* What a `menu` snippet receives: the open menu (`menu`), its rows
|
|
46
|
+
* (`items`, each a `MenuItemPayload`), the keyboard's row (`index`), the
|
|
47
|
+
* attachments that give it the keys and the ARIA (`popup` and `keys` on
|
|
48
|
+
* the menu's element, `option(index)` on each row) and `close()`.
|
|
49
|
+
* A grip's own attachment is its payload's `grip`.
|
|
14
50
|
*/
|
|
15
|
-
export class TableChrome {
|
|
16
|
-
edytor;
|
|
17
|
-
labels;
|
|
51
|
+
export class TableChrome extends ChromeList {
|
|
18
52
|
columnWidth;
|
|
19
53
|
minColumnWidth;
|
|
20
|
-
/**
|
|
54
|
+
/**
|
|
55
|
+
* The table, row and column (their ids) under the pointer.
|
|
56
|
+
* @internal
|
|
57
|
+
*/
|
|
21
58
|
hovered = $state(null);
|
|
22
|
-
/**
|
|
59
|
+
/** What the open grip menu acts on (`null`: none is open). */
|
|
23
60
|
menu = $state(null);
|
|
24
|
-
/**
|
|
61
|
+
/**
|
|
62
|
+
* The measured table the chrome is for.
|
|
63
|
+
* @internal
|
|
64
|
+
*/
|
|
25
65
|
layout = $state.raw(null);
|
|
26
|
-
/**
|
|
66
|
+
/**
|
|
67
|
+
* A block drag is in progress: no chrome takes the pointer.
|
|
68
|
+
* @internal
|
|
69
|
+
*/
|
|
27
70
|
dragging = $state(false);
|
|
28
|
-
/**
|
|
29
|
-
|
|
71
|
+
/**
|
|
72
|
+
* The column resize (its drag in progress, `band.drag`).
|
|
73
|
+
* @internal
|
|
74
|
+
*/
|
|
75
|
+
band;
|
|
76
|
+
/**
|
|
77
|
+
* The row's or column's drag in progress (`table.drag`).
|
|
78
|
+
* @internal
|
|
79
|
+
*/
|
|
80
|
+
moving = $state(null);
|
|
30
81
|
/**
|
|
31
82
|
* The cell the caret was last in: the row and column the block menu's
|
|
32
83
|
* actions on its table act on. A block selection (the grip that opens
|
|
33
84
|
* the menu) keeps it; a caret outside every table clears it.
|
|
85
|
+
* @internal
|
|
34
86
|
*/
|
|
35
87
|
cell = null;
|
|
36
|
-
constructor(edytor,
|
|
37
|
-
/**
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
88
|
+
constructor(edytor,
|
|
89
|
+
/**
|
|
90
|
+
* A column's width when it sets none, and the narrowest a resize leaves.
|
|
91
|
+
* @internal
|
|
92
|
+
*/
|
|
93
|
+
columnWidth,
|
|
94
|
+
/** @internal */
|
|
95
|
+
minColumnWidth) {
|
|
96
|
+
super(edytor, 'table-menu', 'menu', (node) => {
|
|
97
|
+
const kind = this.menu?.kind;
|
|
98
|
+
if (!kind)
|
|
99
|
+
return null;
|
|
100
|
+
node.setAttribute('data-edytor-table-menu', kind);
|
|
101
|
+
return {};
|
|
102
|
+
});
|
|
41
103
|
this.columnWidth = columnWidth;
|
|
42
104
|
this.minColumnWidth = minColumnWidth;
|
|
105
|
+
this.band = new BandDrag(edytor);
|
|
106
|
+
}
|
|
107
|
+
get count() {
|
|
108
|
+
return this.#rows.length;
|
|
43
109
|
}
|
|
44
|
-
/** The view is readonly (reactive). */
|
|
110
|
+
/** The view is readonly (reactive): the chrome shows nothing. */
|
|
45
111
|
get readonly() {
|
|
46
112
|
return this.edytor.readonly;
|
|
47
113
|
}
|
|
48
|
-
/**
|
|
49
|
-
|
|
50
|
-
|
|
114
|
+
/**
|
|
115
|
+
* The column resize in progress.
|
|
116
|
+
* @internal
|
|
117
|
+
*/
|
|
118
|
+
get drag() {
|
|
119
|
+
return this.band.drag;
|
|
51
120
|
}
|
|
52
|
-
/**
|
|
121
|
+
/**
|
|
122
|
+
* The table the chrome is for: the one a band drags or a grip moves, a
|
|
123
|
+
* menu is open on, or under the pointer.
|
|
124
|
+
* @internal
|
|
125
|
+
*/
|
|
53
126
|
get table() {
|
|
54
|
-
return this.drag?.table ?? this.menu?.table ?? this.hovered?.table ?? null;
|
|
127
|
+
return (this.drag?.table ?? this.moving?.table ?? this.menu?.table ?? this.hovered?.table ?? null);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* What the `kind` grip stands for now (the open menu's row or column,
|
|
131
|
+
* else the hovered one): its table, id and position; `null` when none.
|
|
132
|
+
*/
|
|
133
|
+
#source(kind) {
|
|
134
|
+
const table = this.block(this.table);
|
|
135
|
+
const grid = gridOf(table);
|
|
136
|
+
const id = this.menu?.kind === kind ? this.menu.id : this.hovered?.[kind];
|
|
137
|
+
const ids = kind === 'row' ? grid?.rows.map((row) => row.id) : grid?.columns;
|
|
138
|
+
const index = id ? (ids?.indexOf(id) ?? -1) : -1;
|
|
139
|
+
return table && grid && index >= 0 ? { table, grid, id: id, index } : null;
|
|
55
140
|
}
|
|
56
|
-
/**
|
|
141
|
+
/**
|
|
142
|
+
* The selection changed: a caret in a cell is the one the block menu acts on.
|
|
143
|
+
* @internal
|
|
144
|
+
*/
|
|
57
145
|
track = () => {
|
|
58
|
-
if (this.edytor.selection.value.kind
|
|
59
|
-
|
|
60
|
-
this.cell = caretCell(this.edytor)?.id ?? null;
|
|
146
|
+
if (this.edytor.selection.value.kind === 'text')
|
|
147
|
+
this.cell = caretCell(this.edytor)?.id ?? null;
|
|
61
148
|
};
|
|
62
|
-
/**
|
|
149
|
+
/**
|
|
150
|
+
* Whether the chrome shows (on its table all through a band's or a grip's drag).
|
|
151
|
+
* @internal
|
|
152
|
+
*/
|
|
63
153
|
get shown() {
|
|
64
|
-
return this.drag !== null ||
|
|
154
|
+
return (this.drag !== null ||
|
|
155
|
+
this.moving !== null ||
|
|
156
|
+
(!this.readonly && !this.dragging && this.table !== null));
|
|
65
157
|
}
|
|
66
|
-
/**
|
|
158
|
+
/**
|
|
159
|
+
* The block of table `id`, if it is still a shown table.
|
|
160
|
+
* @internal
|
|
161
|
+
*/
|
|
67
162
|
block = (id) => {
|
|
68
163
|
const block = id ? this.edytor.idToBlock.get(id) : undefined;
|
|
69
164
|
return block?.isInTree && this.edytor.facade.isTable(block.id) ? block : null;
|
|
70
165
|
};
|
|
166
|
+
/**
|
|
167
|
+
* Whether layer-relative `x` is in the part of the grid its box shows
|
|
168
|
+
* (`table.overflow`): a band or a grip outside it is not shown.
|
|
169
|
+
* @internal
|
|
170
|
+
*/
|
|
171
|
+
inView = (x) => {
|
|
172
|
+
const view = this.layout?.view;
|
|
173
|
+
return !!view && x >= view.left - 1 && x <= view.right + 1;
|
|
174
|
+
};
|
|
175
|
+
/**
|
|
176
|
+
* The grid's visible span, horizontally, layer-relative.
|
|
177
|
+
* @internal
|
|
178
|
+
*/
|
|
179
|
+
get span() {
|
|
180
|
+
const layout = this.layout;
|
|
181
|
+
if (!layout)
|
|
182
|
+
return { left: 0, width: 0 };
|
|
183
|
+
const left = Math.max(layout.left, layout.view.left);
|
|
184
|
+
const right = Math.min(layout.left + layout.width, layout.view.right);
|
|
185
|
+
return { left, width: Math.max(0, right - left) };
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* The open menu's or the hovered row's and column's lines in the
|
|
189
|
+
* measured table, with their positions.
|
|
190
|
+
*/
|
|
191
|
+
#lines(kind) {
|
|
192
|
+
const layout = this.layout;
|
|
193
|
+
const id = this.menu?.kind === kind ? this.menu.id : this.hovered?.[kind];
|
|
194
|
+
const lines = (kind === 'row' ? layout?.rows : layout?.columns) ?? [];
|
|
195
|
+
const index = lines.findIndex((line) => line.id === id);
|
|
196
|
+
return index < 0 ? null : { layout: layout, index, id: id };
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Where the grips stand, layer-relative, the point each centers on: the
|
|
200
|
+
* row grip on the grid's left edge, at the middle of the row it stands
|
|
201
|
+
* for; the column grip on its top edge, at the middle of the column it
|
|
202
|
+
* stands for, while that middle shows (the grip a drag started from
|
|
203
|
+
* stays, its source, even scrolled out of view).
|
|
204
|
+
* @internal
|
|
205
|
+
*/
|
|
206
|
+
get grips() {
|
|
207
|
+
const row = this.#lines('row');
|
|
208
|
+
const column = this.#lines('column');
|
|
209
|
+
const r = row && row.layout.rows[row.index];
|
|
210
|
+
const c = column && column.layout.columns[column.index];
|
|
211
|
+
const x = c ? c.left + c.width / 2 : 0;
|
|
212
|
+
return [
|
|
213
|
+
...(row && r
|
|
214
|
+
? [{ ...row, kind: 'row', x: row.layout.left, y: r.top + r.height / 2 }]
|
|
215
|
+
: []),
|
|
216
|
+
...(column && (this.moving?.kind === 'column' || this.inView(x))
|
|
217
|
+
? [{ ...column, kind: 'column', x, y: column.layout.top }]
|
|
218
|
+
: [])
|
|
219
|
+
];
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Where the `+` under the table stands (as wide as the grid shows) and
|
|
223
|
+
* the one beside it (as tall as the grid, while its right edge shows).
|
|
224
|
+
* @internal
|
|
225
|
+
*/
|
|
226
|
+
get bars() {
|
|
227
|
+
const layout = this.layout;
|
|
228
|
+
if (!layout)
|
|
229
|
+
return [];
|
|
230
|
+
const { left, width } = this.span;
|
|
231
|
+
const right = layout.left + layout.width;
|
|
232
|
+
return [
|
|
233
|
+
{ kind: 'row', left, top: layout.top + layout.height + 2, width },
|
|
234
|
+
...(this.inView(right)
|
|
235
|
+
? [{ kind: 'column', left: right + 2, top: layout.top, height: layout.height }]
|
|
236
|
+
: [])
|
|
237
|
+
];
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Where the open menu stands: under its grip.
|
|
241
|
+
* @internal
|
|
242
|
+
*/
|
|
243
|
+
get menuPlace() {
|
|
244
|
+
const kind = this.menu?.kind;
|
|
245
|
+
const at = kind && this.#lines(kind);
|
|
246
|
+
if (!at)
|
|
247
|
+
return null;
|
|
248
|
+
const { layout, index } = at;
|
|
249
|
+
if (kind === 'row') {
|
|
250
|
+
const row = layout.rows[index];
|
|
251
|
+
return { left: layout.left - 9, top: row.top + Math.min(row.height, 28) };
|
|
252
|
+
}
|
|
253
|
+
const column = layout.columns[index];
|
|
254
|
+
return { left: column.left + column.width / 2 - 12, top: layout.top + 10 };
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* The drop line of a grip's drag, layer-relative: between two rows
|
|
258
|
+
* (columns), where the drop would land.
|
|
259
|
+
* @internal
|
|
260
|
+
*/
|
|
261
|
+
get line() {
|
|
262
|
+
const move = this.moving;
|
|
263
|
+
const gap = move?.gap ?? null;
|
|
264
|
+
const layout = this.layout;
|
|
265
|
+
if (!move || gap === null || !layout)
|
|
266
|
+
return null;
|
|
267
|
+
const row = move.kind === 'row';
|
|
268
|
+
const lines = row ? layout.rows : layout.columns.map((c) => ({ top: c.left, height: c.width }));
|
|
269
|
+
const last = lines.at(-1);
|
|
270
|
+
const at = lines[gap]?.top ?? (last && last.top + last.height);
|
|
271
|
+
if (at === undefined)
|
|
272
|
+
return null;
|
|
273
|
+
if (row)
|
|
274
|
+
return { kind: move.kind, gap, left: this.span.left, top: at - 2, width: this.span.width };
|
|
275
|
+
return this.inView(at)
|
|
276
|
+
? { kind: move.kind, gap, left: at - 2, top: layout.top, height: layout.height }
|
|
277
|
+
: null;
|
|
278
|
+
}
|
|
71
279
|
/**
|
|
72
280
|
* The width column `index` of `table` shows (its `data.columns` entry, the
|
|
73
281
|
* resize preview while a band drags it): what the grid's template reads.
|
|
282
|
+
* @internal
|
|
74
283
|
*/
|
|
75
284
|
width = (table, index, column) => {
|
|
76
285
|
const drag = this.drag;
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
return widthOf(column, this.columnWidth);
|
|
286
|
+
const at = drag?.table === table ? index - drag.column : -1;
|
|
287
|
+
const preview = at === 0 ? this.#dragWidth(drag) : at === 1 ? this.#nextWidth(drag) : undefined;
|
|
288
|
+
return preview ?? widthOf(column, this.columnWidth);
|
|
80
289
|
};
|
|
81
|
-
|
|
82
|
-
|
|
290
|
+
/** The resize's width: the pointer's, between the minimum and the room's (`table.width.fit`). */
|
|
291
|
+
#dragWidth = (drag) => Math.max(this.minColumnWidth, Math.min(drag.max, Math.round(drag.width + drag.at - drag.from)));
|
|
292
|
+
/**
|
|
293
|
+
* The right neighbour's width while column `drag.column` is `#dragWidth`
|
|
294
|
+
* (`table.width.neighbour`): the column grows into the free room first,
|
|
295
|
+
* then what it gains past it comes off its neighbour, down to the
|
|
296
|
+
* minimum; a narrowing gives nothing back.
|
|
297
|
+
*/
|
|
298
|
+
#nextWidth(drag) {
|
|
299
|
+
if (drag.next === undefined)
|
|
300
|
+
return undefined;
|
|
301
|
+
const take = Math.max(0, this.#dragWidth(drag) - drag.width - drag.slack);
|
|
302
|
+
return Math.max(Math.min(drag.next, this.minColumnWidth), drag.next - take);
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* The widths `table`'s grid shows, by position (its columns' stored
|
|
306
|
+
* widths, else the default one): what its template reads, the model's.
|
|
307
|
+
*/
|
|
308
|
+
#widthsOf(table) {
|
|
309
|
+
const entries = entriesOf(table);
|
|
310
|
+
return (gridOf(table)?.columns ?? []).map((id) => widthOf(entries[entryIndex(entries, id)], this.columnWidth));
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* A resize of column `column` of the measured table, pressed at `from`
|
|
314
|
+
* (`table.width.fit`, `table.width.neighbour`): the column may grow by the
|
|
315
|
+
* room the table leaves free and by what its right neighbour can give
|
|
316
|
+
* (down to the minimum), so the table never gets wider; it may always narrow.
|
|
317
|
+
*/
|
|
318
|
+
#resize(column, from, at) {
|
|
319
|
+
const layout = this.layout;
|
|
320
|
+
const table = this.block(layout?.table);
|
|
321
|
+
const widths = table ? this.#widthsOf(table) : [];
|
|
322
|
+
const width = widths[column];
|
|
323
|
+
if (!layout || !table || width === undefined)
|
|
324
|
+
return null;
|
|
325
|
+
const next = widths[column + 1];
|
|
326
|
+
const slack = Math.max(0, layout.room - widths.reduce((sum, w) => sum + w, 0));
|
|
327
|
+
const gives = next === undefined ? 0 : next - Math.min(next, this.minColumnWidth);
|
|
328
|
+
const max = Math.floor(width + slack + gives);
|
|
329
|
+
return { table: table.id, column, from, at, width, max, slack, next };
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* The pointer is over `target`: the table, row and column holding it (the innermost table).
|
|
333
|
+
* @internal
|
|
334
|
+
*/
|
|
83
335
|
hover = (target) => {
|
|
336
|
+
// A grip's drag keeps its row or column.
|
|
337
|
+
if (this.moving)
|
|
338
|
+
return;
|
|
84
339
|
const element = target instanceof Element ? target : null;
|
|
85
340
|
const cell = element?.closest('[data-edytor-table-cell], [data-edytor-table-pad]');
|
|
86
|
-
const
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const was = this.hovered;
|
|
96
|
-
if (was?.table === next?.table && was?.row === next?.row && was?.column === next?.column)
|
|
97
|
-
return;
|
|
341
|
+
const table = element?.closest('[data-edytor-table]')?.dataset.edytorId;
|
|
342
|
+
const grid = gridOf(this.block(table));
|
|
343
|
+
const next = table && grid
|
|
344
|
+
? {
|
|
345
|
+
table,
|
|
346
|
+
row: cell?.closest('[data-edytor-table-row]')?.dataset.edytorId ?? null,
|
|
347
|
+
column: grid.columns[Number(cell?.dataset.edytorColumn)] ?? null
|
|
348
|
+
}
|
|
349
|
+
: null;
|
|
98
350
|
// Over the chrome (a grip, the `+`), the row and column it is for stay.
|
|
99
|
-
if (next ===
|
|
351
|
+
if (JSON.stringify(next) === JSON.stringify(this.hovered) || (!next && this.menu))
|
|
100
352
|
return;
|
|
101
353
|
this.hovered = next;
|
|
102
354
|
this.edytor.overlay.invalidate();
|
|
103
355
|
};
|
|
104
|
-
/**
|
|
356
|
+
/**
|
|
357
|
+
* The pointer left for `to`: the chrome stays while it is over the editor or the overlay.
|
|
358
|
+
* @internal
|
|
359
|
+
*/
|
|
105
360
|
leave = (to) => {
|
|
106
361
|
const node = to instanceof Node ? to : null;
|
|
107
362
|
const { edytor } = this;
|
|
108
363
|
if (node && (edytor.overlay.layer?.contains(node) || edytor.node?.contains(node)))
|
|
109
364
|
return;
|
|
110
|
-
if (!this.menu && !this.drag)
|
|
365
|
+
if (!this.menu && !this.drag && !this.moving)
|
|
111
366
|
this.hovered = null;
|
|
112
367
|
edytor.overlay.invalidate();
|
|
113
368
|
};
|
|
114
|
-
/**
|
|
369
|
+
/**
|
|
370
|
+
* The overlay measure: the shown table's grid, rows and columns.
|
|
371
|
+
* @internal
|
|
372
|
+
*/
|
|
115
373
|
measure = (host, origin) => {
|
|
116
|
-
const layout = this.shown ? this
|
|
374
|
+
const layout = this.shown ? this.#read(origin) : null;
|
|
117
375
|
return () => {
|
|
118
|
-
|
|
119
|
-
if (
|
|
376
|
+
pin(host);
|
|
377
|
+
if (JSON.stringify(layout) !== JSON.stringify(this.layout))
|
|
120
378
|
this.layout = layout;
|
|
121
379
|
};
|
|
122
380
|
};
|
|
123
|
-
read(origin) {
|
|
381
|
+
#read(origin) {
|
|
124
382
|
const table = this.block(this.table);
|
|
125
|
-
const grid =
|
|
383
|
+
const grid = gridNode(table);
|
|
126
384
|
const columns = gridOf(table)?.columns;
|
|
127
385
|
if (!table || !grid?.isConnected || !columns)
|
|
128
386
|
return null;
|
|
129
387
|
const box = grid.getBoundingClientRect();
|
|
130
|
-
const widths = (grid
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
.filter((w) => Number.isFinite(w));
|
|
134
|
-
let x = box.left - origin.left;
|
|
388
|
+
const widths = trackWidths(grid);
|
|
389
|
+
const left = box.left - origin.left;
|
|
390
|
+
let x = left;
|
|
135
391
|
const cols = columns.map((id, i) => {
|
|
136
392
|
const width = widths[i] ?? this.columnWidth;
|
|
137
|
-
const col = { id, left: x, width };
|
|
138
393
|
x += width;
|
|
139
|
-
return
|
|
394
|
+
return { id, left: x - width, width };
|
|
140
395
|
});
|
|
141
396
|
const rows = table.children.flatMap((row) => {
|
|
142
397
|
const rect = row.node?.getBoundingClientRect();
|
|
143
398
|
return rect ? [{ id: row.id, top: rect.top - origin.top, height: rect.height }] : [];
|
|
144
399
|
});
|
|
400
|
+
// The box the grid scrolls in: its client box is what shows, and the room.
|
|
401
|
+
const scroller = grid.closest('[data-edytor-table-scroll]') ?? grid.parentElement;
|
|
402
|
+
const inner = scroller?.clientWidth ?? 0;
|
|
403
|
+
const clip = inner > 0 ? scroller.getBoundingClientRect() : undefined;
|
|
404
|
+
const style = styleOf(grid);
|
|
405
|
+
const at = clip ? clip.left + scroller.clientLeft - origin.left : 0;
|
|
145
406
|
return {
|
|
146
407
|
table: table.id,
|
|
147
|
-
left
|
|
408
|
+
left,
|
|
148
409
|
top: box.top - origin.top,
|
|
149
|
-
width: Math.min(box.width, x -
|
|
410
|
+
width: Math.min(box.width, x - left) || box.width,
|
|
150
411
|
height: box.height,
|
|
151
412
|
rows,
|
|
152
|
-
columns: cols
|
|
413
|
+
columns: cols,
|
|
414
|
+
view: clip ? { left: at, right: at + inner } : { left: -Infinity, right: Infinity },
|
|
415
|
+
room: clip ? inner - px(style?.borderLeftWidth) - px(style?.borderRightWidth) : Infinity
|
|
153
416
|
};
|
|
154
417
|
}
|
|
155
|
-
/**
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
this.menu
|
|
418
|
+
/**
|
|
419
|
+
* Open the `kind` grip's menu on the row or column it stands for, its
|
|
420
|
+
* first row that can run the keyboard's, or close it when it is open
|
|
421
|
+
* there (a grip's click).
|
|
422
|
+
*/
|
|
423
|
+
toggle = (kind) => {
|
|
424
|
+
const source = this.#source(kind);
|
|
425
|
+
const open = this.menu?.kind === kind;
|
|
426
|
+
this.menu = open || !source ? null : { kind, table: source.table.id, id: source.id };
|
|
427
|
+
if (this.menu)
|
|
428
|
+
this.index = Math.max(0, this.#rows.findIndex((row) => !row.disabled));
|
|
163
429
|
this.edytor.overlay.invalidate();
|
|
164
430
|
};
|
|
431
|
+
/** Whether a menu is open (reactive). */
|
|
432
|
+
get isOpen() {
|
|
433
|
+
return this.menu !== null;
|
|
434
|
+
}
|
|
165
435
|
/** Close the menu; the editor takes the keys back. */
|
|
166
436
|
close = () => {
|
|
167
437
|
this.menu = null;
|
|
168
438
|
this.edytor.overlay.invalidate();
|
|
169
439
|
takeKeys(this.edytor);
|
|
170
440
|
};
|
|
171
|
-
/**
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
if (menu.kind === 'row') {
|
|
180
|
-
const index = grid.rows.findIndex((r) => r.id === menu.row);
|
|
181
|
-
const row = this.edytor.idToBlock.get(menu.row);
|
|
182
|
-
if (index < 0 || !row)
|
|
183
|
-
return [];
|
|
184
|
-
const last = grid.rows.length - 1;
|
|
185
|
-
return [
|
|
186
|
-
{
|
|
187
|
-
id: 'insert-above',
|
|
188
|
-
label: labels.insertAbove,
|
|
189
|
-
icon: 'action.up',
|
|
190
|
-
isEnabled: () => true,
|
|
191
|
-
run: () => insertRow(table, index, true)
|
|
192
|
-
},
|
|
193
|
-
{
|
|
194
|
-
id: 'insert-below',
|
|
195
|
-
label: labels.insertBelow,
|
|
196
|
-
icon: 'action.down',
|
|
197
|
-
isEnabled: () => true,
|
|
198
|
-
run: () => insertRow(table, index + 1, true)
|
|
199
|
-
},
|
|
200
|
-
{
|
|
201
|
-
id: 'move-up',
|
|
202
|
-
label: labels.moveUp,
|
|
203
|
-
icon: 'action.up',
|
|
204
|
-
isEnabled: () => index > 0,
|
|
205
|
-
run: () => moveRows(table, [row], index - 1)
|
|
206
|
-
},
|
|
207
|
-
{
|
|
208
|
-
id: 'move-down',
|
|
209
|
-
label: labels.moveDown,
|
|
210
|
-
icon: 'action.down',
|
|
211
|
-
isEnabled: () => index < last,
|
|
212
|
-
run: () => moveRows(table, [row], index + 1)
|
|
213
|
-
},
|
|
214
|
-
{
|
|
215
|
-
id: 'delete-row',
|
|
216
|
-
label: labels.deleteRow,
|
|
217
|
-
icon: 'action.delete',
|
|
218
|
-
danger: true,
|
|
219
|
-
isEnabled: () => true,
|
|
220
|
-
run: () => deleteRows(table, [row])
|
|
221
|
-
}
|
|
222
|
-
];
|
|
223
|
-
}
|
|
224
|
-
const index = menu.column;
|
|
225
|
-
const column = grid.columns[index];
|
|
226
|
-
if (column === undefined)
|
|
441
|
+
/**
|
|
442
|
+
* The open menu's rows: insert before and after, move back and forth,
|
|
443
|
+
* delete (whether each can run now; the last deletes).
|
|
444
|
+
*/
|
|
445
|
+
get #rows() {
|
|
446
|
+
const kind = this.menu?.kind;
|
|
447
|
+
const at = kind && this.#source(kind);
|
|
448
|
+
if (!at)
|
|
227
449
|
return [];
|
|
228
|
-
const
|
|
450
|
+
const { table, grid, id, index } = at;
|
|
451
|
+
const row = kind === 'row';
|
|
452
|
+
const block = this.edytor.idToBlock.get(id);
|
|
453
|
+
const last = (row ? grid.rows : grid.columns).length - 1;
|
|
454
|
+
const insert = (to) => (row ? insertRow(table, to, true) : insertColumn(table, to));
|
|
455
|
+
const move = (to) => (row ? moveRows(table, [block], to) : moveColumn(table, id, to));
|
|
456
|
+
const [before, after, back, forth] = row
|
|
457
|
+
? ['above', 'below', 'up', 'down']
|
|
458
|
+
: ['left', 'right', 'left', 'right'];
|
|
229
459
|
return [
|
|
460
|
+
{ id: `insert-${before}`, disabled: false, run: () => insert(index) },
|
|
461
|
+
{ id: `insert-${after}`, disabled: false, run: () => insert(index + 1) },
|
|
462
|
+
{ id: `move-${back}`, disabled: index === 0, run: () => move(index - 1) },
|
|
463
|
+
{ id: `move-${forth}`, disabled: index === last, run: () => move(index + 1) },
|
|
230
464
|
{
|
|
231
|
-
id:
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
isEnabled: () => true,
|
|
235
|
-
run: () => insertColumn(table, index)
|
|
236
|
-
},
|
|
237
|
-
{
|
|
238
|
-
id: 'insert-right',
|
|
239
|
-
label: labels.insertRight,
|
|
240
|
-
icon: 'table.right',
|
|
241
|
-
isEnabled: () => true,
|
|
242
|
-
run: () => insertColumn(table, index + 1)
|
|
243
|
-
},
|
|
244
|
-
{
|
|
245
|
-
id: 'move-left',
|
|
246
|
-
label: labels.moveLeft,
|
|
247
|
-
icon: 'table.left',
|
|
248
|
-
isEnabled: () => index > 0,
|
|
249
|
-
run: () => moveColumn(table, index, index - 1)
|
|
250
|
-
},
|
|
251
|
-
{
|
|
252
|
-
id: 'move-right',
|
|
253
|
-
label: labels.moveRight,
|
|
254
|
-
icon: 'table.right',
|
|
255
|
-
isEnabled: () => index < last,
|
|
256
|
-
run: () => moveColumn(table, index, index + 1)
|
|
257
|
-
},
|
|
258
|
-
{
|
|
259
|
-
id: 'delete-column',
|
|
260
|
-
label: labels.deleteColumn,
|
|
261
|
-
icon: 'action.delete',
|
|
262
|
-
danger: true,
|
|
263
|
-
isEnabled: () => true,
|
|
264
|
-
run: () => deleteColumn(table, index)
|
|
465
|
+
id: `delete-${kind}`,
|
|
466
|
+
disabled: false,
|
|
467
|
+
run: () => (row ? deleteRows(table, [block]) : deleteColumn(table, id))
|
|
265
468
|
}
|
|
266
469
|
];
|
|
267
470
|
}
|
|
268
|
-
/**
|
|
269
|
-
|
|
270
|
-
|
|
471
|
+
/**
|
|
472
|
+
* The open menu's rows for your `menu`: each the row shape every menu
|
|
473
|
+
* shares (`run` runs it and closes the menu, `select` makes it the
|
|
474
|
+
* keyboard's, `option` its attributes), whether it can run now
|
|
475
|
+
* (`disabled`) and whether it deletes (`danger`).
|
|
476
|
+
*/
|
|
477
|
+
get items() {
|
|
478
|
+
return this.#rows.map(({ id, disabled, run }, index) => ({
|
|
479
|
+
item: { id },
|
|
480
|
+
id: this.rowId(index),
|
|
481
|
+
selected: index === this.index,
|
|
482
|
+
disabled,
|
|
483
|
+
danger: id.startsWith('delete'),
|
|
484
|
+
run: () => {
|
|
485
|
+
if (disabled)
|
|
486
|
+
return;
|
|
487
|
+
this.menu = this.hovered = null;
|
|
488
|
+
takeKeys(this.edytor);
|
|
489
|
+
run();
|
|
490
|
+
this.edytor.overlay.invalidate();
|
|
491
|
+
},
|
|
492
|
+
select: () => {
|
|
493
|
+
if (!disabled)
|
|
494
|
+
this.index = index;
|
|
495
|
+
},
|
|
496
|
+
option: this.option(index)
|
|
497
|
+
}));
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* The attachment of the open menu's row at `index`
|
|
501
|
+
* (`{@attach chrome.option(index)}`). Its id, `menuitem` role,
|
|
502
|
+
* `aria-disabled` when it cannot run now; the keyboard's row scrolls into
|
|
503
|
+
* view. The menu's element takes
|
|
504
|
+
* `data-edytor-table-menu` (the kind it is open on) from `popup`.
|
|
505
|
+
*/
|
|
506
|
+
option(index) {
|
|
507
|
+
const extra = this.#rows[index]?.disabled ? { 'aria-disabled': true } : {};
|
|
508
|
+
return optionAttachment(this.rowId(index), 'menuitem', index === this.index, extra);
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* The element that holds the menu's keyboard (`{@attach chrome.keys}`,
|
|
512
|
+
* the menu's own): it takes the focus when it mounts and names the
|
|
513
|
+
* keyboard's row (`aria-activedescendant`); ArrowDown and ArrowUp walk
|
|
514
|
+
* the rows that can run (around the ends), Home and End reach the first
|
|
515
|
+
* and last, Enter or Space runs the row, Escape and Tab close the menu
|
|
516
|
+
* and give the keys back to the editor. No key reaches the page behind.
|
|
517
|
+
*/
|
|
518
|
+
keys = (node) => untrack(() => {
|
|
519
|
+
if (!node.hasAttribute('tabindex'))
|
|
520
|
+
node.tabIndex = -1;
|
|
521
|
+
return holdKeys(node, this.#keydown, () => this.rowId(this.index));
|
|
522
|
+
});
|
|
523
|
+
/** The menu's keys (`keys`). */
|
|
524
|
+
#keydown = (event) => {
|
|
525
|
+
if (event.defaultPrevented || event.isComposing)
|
|
271
526
|
return;
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
527
|
+
const items = this.items;
|
|
528
|
+
const menu = {
|
|
529
|
+
at: this.index,
|
|
530
|
+
count: items.length,
|
|
531
|
+
to: (index) => (this.index = index),
|
|
532
|
+
pick: () => items[this.index]?.run(),
|
|
533
|
+
close: this.close
|
|
534
|
+
};
|
|
535
|
+
if (menuKey(event, menu, { usable: (index) => !items[index].disabled }))
|
|
536
|
+
event.stopPropagation();
|
|
277
537
|
};
|
|
278
|
-
/**
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
538
|
+
/**
|
|
539
|
+
* The `kind` grip's attachment (`{@attach}` it on a grip's element; a
|
|
540
|
+
* `grip` snippet's payload carries it): in an editable view, dragging it
|
|
541
|
+
* moves its row or column within its table (`table.drag`); a click with
|
|
542
|
+
* no drag opens or closes its menu; ArrowDown opens the menu, Escape
|
|
543
|
+
* closes it and gives the keys back to the editor. It carries
|
|
544
|
+
* `aria-haspopup`, `aria-expanded`, `aria-controls` while its menu is
|
|
545
|
+
* open, and `data-dragging` during its drag. A press on it is never
|
|
546
|
+
* prevented: that would stop the native drag.
|
|
547
|
+
*/
|
|
548
|
+
gripOf = (kind) => (this.#grips[kind] ??= (node) => untrack(() => this.#grip(node, kind)));
|
|
549
|
+
#grips = {};
|
|
550
|
+
#grip = (node, kind) => {
|
|
551
|
+
node.setAttribute('aria-haspopup', 'menu');
|
|
552
|
+
$effect(() => {
|
|
553
|
+
const open = this.menu?.kind === kind;
|
|
554
|
+
attribute(node, 'aria-expanded', String(open));
|
|
555
|
+
attribute(node, 'aria-controls', open ? this.listId : undefined);
|
|
556
|
+
attribute(node, 'data-dragging', this.moving?.kind === kind ? 'true' : undefined);
|
|
557
|
+
});
|
|
558
|
+
const off = all(listen(node, 'click', () => this.toggle(kind)), listen(node, 'keydown', (event) => {
|
|
559
|
+
// Escape gives the keys back to the editor (closing the menu if open).
|
|
560
|
+
if (event.key === 'Escape')
|
|
561
|
+
this.close();
|
|
562
|
+
else if (event.key === 'ArrowDown' && this.menu?.kind !== kind)
|
|
563
|
+
this.toggle(kind);
|
|
564
|
+
else
|
|
565
|
+
return;
|
|
566
|
+
event.preventDefault();
|
|
567
|
+
event.stopPropagation();
|
|
568
|
+
}), draggable({
|
|
569
|
+
element: node,
|
|
570
|
+
canDrag: () => !this.edytor.readonly && this.edytor.dispatcher.permits() && this.#source(kind) !== null,
|
|
571
|
+
getInitialData: () => ({ [MOVE]: this }),
|
|
572
|
+
// The editor's own drag: no view takes it as a foreign drop.
|
|
573
|
+
getInitialDataForExternal: () => {
|
|
574
|
+
const source = this.#source(kind);
|
|
575
|
+
return {
|
|
576
|
+
[EDYTOR_BLOCK_DRAG_MIME]: (kind === 'row' ? source?.id : source?.table.id) ?? ''
|
|
577
|
+
};
|
|
578
|
+
},
|
|
579
|
+
onGenerateDragPreview: ({ nativeSetDragImage, location }) => this.#begin(kind, node, location.current.input, nativeSetDragImage),
|
|
580
|
+
// The drag library tells the source before the drop target: the drop runs first.
|
|
581
|
+
onDrop: () => queueMicrotask(() => {
|
|
582
|
+
for (const release of this.#releases.splice(0))
|
|
583
|
+
release();
|
|
584
|
+
this.moving = null;
|
|
585
|
+
this.edytor.overlay.invalidate();
|
|
586
|
+
})
|
|
587
|
+
}));
|
|
588
|
+
return off;
|
|
286
589
|
};
|
|
287
|
-
/**
|
|
288
|
-
|
|
590
|
+
/**
|
|
591
|
+
* The `+` under the table (`row`: a row at its end, the caret in its
|
|
592
|
+
* first cell) or beside it (a column at its end).
|
|
593
|
+
* @internal
|
|
594
|
+
*/
|
|
595
|
+
add = (kind) => {
|
|
289
596
|
const table = this.block(this.table);
|
|
290
597
|
const grid = gridOf(table);
|
|
291
598
|
if (!table || !grid)
|
|
292
599
|
return;
|
|
293
600
|
takeKeys(this.edytor);
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
event.preventDefault();
|
|
299
|
-
if (isLonePress(this.edytor, event))
|
|
300
|
-
this.start(event, column);
|
|
601
|
+
if (kind === 'row')
|
|
602
|
+
insertRow(table, grid.rows.length, true);
|
|
603
|
+
else
|
|
604
|
+
insertColumn(table, grid.columns.length);
|
|
301
605
|
};
|
|
302
606
|
/**
|
|
303
|
-
* Press on column `column`'s band
|
|
304
|
-
* the
|
|
305
|
-
*
|
|
607
|
+
* Press on column `column`'s band (its `pointerdown`, or its lone
|
|
608
|
+
* `mousedown`): the drag starts; the preview follows the pointer and the
|
|
609
|
+
* release writes the width (`#release`); Escape, a cancel or the view
|
|
610
|
+
* turning readonly drop the preview, nothing written.
|
|
611
|
+
* @internal
|
|
306
612
|
*/
|
|
307
613
|
start = (event, column) => {
|
|
308
|
-
const
|
|
309
|
-
const
|
|
310
|
-
if (
|
|
311
|
-
return;
|
|
312
|
-
const col = layout.columns[column];
|
|
313
|
-
if (!col)
|
|
614
|
+
const drag = this.band.drag ? null : this.#resize(column, event.clientX, event.clientX);
|
|
615
|
+
const shown = this.layout?.columns[column]?.width;
|
|
616
|
+
if (!drag || shown === undefined)
|
|
314
617
|
return;
|
|
315
|
-
|
|
316
|
-
event.
|
|
317
|
-
const target = event.currentTarget;
|
|
318
|
-
const pointer = event.type === 'pointerdown';
|
|
319
|
-
if (pointer)
|
|
320
|
-
target?.setPointerCapture?.(event.pointerId);
|
|
321
|
-
this.drag = {
|
|
322
|
-
table: layout.table,
|
|
323
|
-
column,
|
|
324
|
-
from: event.clientX,
|
|
325
|
-
at: event.clientX,
|
|
326
|
-
width: col.width
|
|
327
|
-
};
|
|
328
|
-
const document = target?.ownerDocument ?? edytor.node?.ownerDocument;
|
|
329
|
-
const tracked = pointer ? document : document?.defaultView;
|
|
330
|
-
const [moves, ups] = pointer ? ['pointermove', 'pointerup'] : ['mousemove', 'mouseup'];
|
|
331
|
-
const move = (moved) => {
|
|
332
|
-
if (!this.drag)
|
|
333
|
-
return;
|
|
334
|
-
if (!edytor.dispatcher.permits())
|
|
335
|
-
return end(moved);
|
|
336
|
-
this.drag.at = moved.clientX;
|
|
337
|
-
edytor.overlay.invalidate();
|
|
338
|
-
};
|
|
339
|
-
const end = (ended) => {
|
|
340
|
-
tracked?.removeEventListener(moves, move);
|
|
341
|
-
tracked?.removeEventListener(ups, end);
|
|
342
|
-
tracked?.removeEventListener('pointercancel', end);
|
|
343
|
-
document?.removeEventListener('keydown', escape, true);
|
|
344
|
-
const drag = this.drag;
|
|
345
|
-
if (drag && ended.type === ups) {
|
|
346
|
-
drag.at = ended.clientX;
|
|
347
|
-
this.release(drag);
|
|
348
|
-
takeKeys(edytor);
|
|
349
|
-
}
|
|
350
|
-
this.drag = null;
|
|
351
|
-
edytor.overlay.invalidate();
|
|
352
|
-
};
|
|
353
|
-
const escape = (key) => {
|
|
354
|
-
if (key.key !== 'Escape')
|
|
355
|
-
return;
|
|
356
|
-
key.preventDefault();
|
|
357
|
-
key.stopPropagation();
|
|
358
|
-
end(key);
|
|
359
|
-
};
|
|
360
|
-
this.#cancel = () => end(new Event('cancel'));
|
|
361
|
-
tracked?.addEventListener(moves, move);
|
|
362
|
-
tracked?.addEventListener(ups, end);
|
|
363
|
-
if (pointer)
|
|
364
|
-
tracked?.addEventListener('pointercancel', end);
|
|
365
|
-
document?.addEventListener('keydown', escape, true);
|
|
366
|
-
edytor.overlay.invalidate();
|
|
367
|
-
};
|
|
368
|
-
#cancel = null;
|
|
369
|
-
/** The view turned readonly mid-drag: the preview goes, nothing written. */
|
|
370
|
-
lock = () => {
|
|
371
|
-
if (this.drag && !this.edytor.dispatcher.permits())
|
|
372
|
-
this.#cancel?.();
|
|
618
|
+
// The press starts from the width the grid shows.
|
|
619
|
+
this.band.start(event, { ...drag, width: shown, max: Math.max(drag.max, shown) }, (drag) => drag && this.#release(drag));
|
|
373
620
|
};
|
|
374
621
|
/**
|
|
375
622
|
* A key on a focused band: ArrowRight/ArrowLeft widen or narrow the
|
|
376
|
-
* column by 8px (Shift: 32px)
|
|
623
|
+
* column by 8px (Shift: 32px) from its stored width, as far as the room
|
|
624
|
+
* leaves it (`table.width.fit`); each press is one width write.
|
|
625
|
+
* @internal
|
|
377
626
|
*/
|
|
378
627
|
key = (event, column) => {
|
|
379
|
-
event
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
}
|
|
384
|
-
const step = { ArrowLeft: -1, ArrowRight: 1 }[event.key];
|
|
385
|
-
if (step === undefined)
|
|
386
|
-
return;
|
|
387
|
-
event.preventDefault();
|
|
388
|
-
const layout = this.layout;
|
|
389
|
-
const col = layout?.columns[column];
|
|
390
|
-
if (!layout || !col || this.drag)
|
|
391
|
-
return;
|
|
392
|
-
const by = step * (event.shiftKey ? 32 : 8);
|
|
393
|
-
this.release({ table: layout.table, column, from: 0, at: by, width: col.width });
|
|
628
|
+
const step = bandKey(this.edytor, this.band, event, { ArrowLeft: -1, ArrowRight: 1 });
|
|
629
|
+
const drag = step && this.#resize(column, 0, step * (event.shiftKey ? 32 : 8));
|
|
630
|
+
if (drag)
|
|
631
|
+
this.#release(drag);
|
|
394
632
|
};
|
|
395
633
|
/**
|
|
396
|
-
* The release: column `drag.column`'s width,
|
|
397
|
-
*
|
|
398
|
-
*
|
|
399
|
-
*
|
|
400
|
-
*
|
|
634
|
+
* The release: column `drag.column`'s width, and its right neighbour's
|
|
635
|
+
* when the column took from it (`table.width.neighbour`), one command;
|
|
636
|
+
* nothing when neither changed, or when the table does not list the
|
|
637
|
+
* column. A width is written on its column's entry by its item id (the
|
|
638
|
+
* first entry naming it), never by position: the stored array may hold
|
|
639
|
+
* an entry the grid does not show.
|
|
401
640
|
*/
|
|
402
|
-
release(drag) {
|
|
641
|
+
#release(drag) {
|
|
403
642
|
const table = this.block(drag.table);
|
|
404
|
-
const
|
|
405
|
-
if (!table ||
|
|
643
|
+
const columns = gridOf(table)?.columns;
|
|
644
|
+
if (!table || !columns || columns[drag.column] === undefined)
|
|
406
645
|
return;
|
|
407
|
-
const
|
|
408
|
-
const
|
|
409
|
-
const
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
646
|
+
const entries = entriesOf(table);
|
|
647
|
+
const items = table.edytor.facade.dataItemIds(table.id, ['columns']);
|
|
648
|
+
const ops = [this.#dragWidth(drag), this.#nextWidth(drag)].flatMap((width, i) => {
|
|
649
|
+
const at = entryIndex(entries, columns[drag.column + i]);
|
|
650
|
+
const item = items[at];
|
|
651
|
+
return at < 0 || item === undefined || width === undefined
|
|
652
|
+
? []
|
|
653
|
+
: width === widthOf(entries[at], this.columnWidth)
|
|
654
|
+
? []
|
|
655
|
+
: [{ path: ['columns', item, 'width'], value: width }];
|
|
656
|
+
});
|
|
657
|
+
if (ops.length)
|
|
658
|
+
this.edytor.patchData(table.id, ops);
|
|
659
|
+
}
|
|
660
|
+
/** The drop target and auto-scroll of the drag in progress, released when it ends. */
|
|
661
|
+
#releases = [];
|
|
662
|
+
/**
|
|
663
|
+
* The drag starts: what it moves; its ghost, the row's cells side by side
|
|
664
|
+
* or the column's one under the other, at their columns' widths (the
|
|
665
|
+
* blocks' ghost, `dragPreview`); the page as its drop target; auto-scroll.
|
|
666
|
+
*/
|
|
667
|
+
#begin(kind, node, pointer, nativeSetDragImage) {
|
|
668
|
+
const source = this.#source(kind);
|
|
669
|
+
const root = this.edytor.node;
|
|
670
|
+
if (!source || !root)
|
|
413
671
|
return;
|
|
414
|
-
const
|
|
415
|
-
|
|
672
|
+
const { table, grid, id, index } = source;
|
|
673
|
+
this.menu = null;
|
|
674
|
+
this.moving = { kind, table: table.id, id, gap: null };
|
|
675
|
+
const widths = this.#widthsOf(table);
|
|
676
|
+
const cells = (kind === 'row' ? grid.rows[index].cells : grid.rows.map((r) => r.cells[index])).flatMap((cell) => (cell && this.edytor.idToBlock.get(cell)?.node) || []);
|
|
677
|
+
if (nativeSetDragImage && cells.length) {
|
|
678
|
+
const preview = dragPreview(root, cells, pointer, kind === 'row' ? widths : [widths[index]]);
|
|
679
|
+
setCustomNativeDragPreview({
|
|
680
|
+
nativeSetDragImage,
|
|
681
|
+
getOffset: preview.offset,
|
|
682
|
+
render: ({ container }) => container.append(preview.element)
|
|
683
|
+
});
|
|
684
|
+
}
|
|
685
|
+
const ours = (data) => data[MOVE] === this;
|
|
686
|
+
// The page is the target: the line follows the pointer from the grips, outside the grid.
|
|
687
|
+
this.#releases.push(dropTargetForElements({
|
|
688
|
+
element: node.ownerDocument.body,
|
|
689
|
+
canDrop: ({ source }) => ours(source.data),
|
|
690
|
+
onDragEnter: ({ location }) => this.#aim(location.current.input),
|
|
691
|
+
onDrag: ({ location }) => this.#aim(location.current.input),
|
|
692
|
+
onDragLeave: () => this.#aim(null),
|
|
693
|
+
onDrop: ({ location }) => this.#drop(location.current.input)
|
|
694
|
+
}));
|
|
695
|
+
const scroller = table.node?.querySelector('[data-edytor-table-scroll]');
|
|
696
|
+
if (scroller)
|
|
697
|
+
this.#releases.push(autoScrollFor(scroller, ours));
|
|
698
|
+
this.edytor.overlay.invalidate();
|
|
699
|
+
}
|
|
700
|
+
/**
|
|
701
|
+
* Where the moving row or column would land at `input` (`table.drag`):
|
|
702
|
+
* its gap, by the rows' (columns') middles, and its position once moved;
|
|
703
|
+
* `null` outside the table (past its box and the gutter) and at its own
|
|
704
|
+
* place (the gap before or after it).
|
|
705
|
+
*/
|
|
706
|
+
#landing(input) {
|
|
707
|
+
const move = this.moving;
|
|
708
|
+
const table = this.block(move?.table);
|
|
709
|
+
const grid = gridOf(table);
|
|
710
|
+
const node = gridNode(table);
|
|
711
|
+
const box = table?.node?.getBoundingClientRect();
|
|
712
|
+
if (!move || !input || !box || !grid || !node)
|
|
713
|
+
return null;
|
|
714
|
+
const { clientX: x, clientY: y } = input;
|
|
715
|
+
if (x < box.left - GUTTER ||
|
|
716
|
+
x > box.right + GUTTER ||
|
|
717
|
+
y < box.top - GUTTER ||
|
|
718
|
+
y > box.bottom + GUTTER)
|
|
719
|
+
return null;
|
|
720
|
+
// The gap: the rows' (columns', from the grid's left border) middles before the pointer.
|
|
721
|
+
let gap = 0;
|
|
722
|
+
let from;
|
|
723
|
+
if (move.kind === 'row') {
|
|
724
|
+
from = grid.rows.findIndex((r) => r.id === move.id);
|
|
725
|
+
for (const row of grid.rows) {
|
|
726
|
+
const rect = this.edytor.idToBlock.get(row.id)?.node?.getBoundingClientRect();
|
|
727
|
+
if (rect && y > rect.top + rect.height / 2)
|
|
728
|
+
gap++;
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
else {
|
|
732
|
+
from = grid.columns.indexOf(move.id);
|
|
733
|
+
let left = node.getBoundingClientRect().left + px(styleOf(node)?.borderLeftWidth);
|
|
734
|
+
for (const width of trackWidths(node))
|
|
735
|
+
if (x > (left += width) - width / 2)
|
|
736
|
+
gap++;
|
|
737
|
+
}
|
|
738
|
+
if (from < 0 || gap === from || gap === from + 1)
|
|
739
|
+
return null;
|
|
740
|
+
return { gap, to: gap > from ? gap - 1 : gap };
|
|
741
|
+
}
|
|
742
|
+
/** The pointer moved during the drag: the drop line follows it. */
|
|
743
|
+
#aim(input) {
|
|
744
|
+
const move = this.moving;
|
|
745
|
+
const gap = this.#landing(input)?.gap ?? null;
|
|
746
|
+
if (!move || gap === move.gap)
|
|
747
|
+
return;
|
|
748
|
+
move.gap = gap;
|
|
749
|
+
this.edytor.overlay.invalidate();
|
|
750
|
+
}
|
|
751
|
+
/**
|
|
752
|
+
* The drop: the row or column moves to the gap at the pointer (`moveRows`,
|
|
753
|
+
* `moveColumn`: one command, one undo step), the keys go to the editor;
|
|
754
|
+
* nothing where no line shows.
|
|
755
|
+
*/
|
|
756
|
+
#drop(input) {
|
|
757
|
+
const move = this.moving;
|
|
758
|
+
const landing = this.#landing(input);
|
|
759
|
+
const table = this.block(move?.table);
|
|
760
|
+
if (!move)
|
|
761
|
+
return;
|
|
762
|
+
move.gap = null;
|
|
763
|
+
if (!landing || !table)
|
|
416
764
|
return;
|
|
417
|
-
|
|
765
|
+
if (move.kind === 'row') {
|
|
766
|
+
const row = this.edytor.idToBlock.get(move.id);
|
|
767
|
+
if (row)
|
|
768
|
+
moveRows(table, [row], landing.to);
|
|
769
|
+
}
|
|
770
|
+
else
|
|
771
|
+
moveColumn(table, move.id, landing.to);
|
|
772
|
+
takeKeys(this.edytor);
|
|
418
773
|
}
|
|
419
774
|
}
|
|
420
|
-
const sameLayout = (a, b) => a === b || (a !== null && b !== null && JSON.stringify(a) === JSON.stringify(b));
|