edytor 2.0.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -4
- package/dist/block/block.svelte.js +2 -4
- package/dist/clipboard/htmlFlow.d.ts +20 -7
- package/dist/clipboard/htmlFlow.js +23 -15
- package/dist/clipboard/serializeClipboardFragment.d.ts +37 -4
- package/dist/clipboard/serializeClipboardFragment.js +6 -4
- package/dist/clipboard/textBlocks.d.ts +8 -0
- package/dist/clipboard/textBlocks.js +6 -2
- package/dist/cloudflare/DocumentRoom.d.ts +13 -9
- package/dist/cloudflare/DocumentRoom.js +10 -6
- package/dist/cloudflare/room/admission.js +3 -3
- package/dist/cloudflare/room/context.d.ts +28 -27
- package/dist/cloudflare/room/context.js +2 -2
- package/dist/cloudflare/room/purge.d.ts +6 -3
- package/dist/cloudflare/room/purge.js +44 -19
- package/dist/cloudflare/room/updates.d.ts +3 -4
- package/dist/cloudflare/room/updates.js +6 -8
- package/dist/cloudflare/routeDocumentSocket.d.ts +17 -0
- package/dist/cloudflare/routeDocumentSocket.js +53 -0
- package/dist/collaboration/comments/client.d.ts +1 -1
- package/dist/collaboration/comments/client.js +1 -1
- package/dist/collaboration/remoteSelection.js +3 -3
- package/dist/components/Edytor.svelte +2 -10
- package/dist/components/Edytor.svelte.d.ts +1 -3
- package/dist/crdt/admission.d.ts +5 -10
- package/dist/crdt/admission.js +5 -11
- package/dist/crdt/attribution/attribution.d.ts +31 -12
- package/dist/crdt/attribution/attribution.js +56 -18
- package/dist/crdt/attribution/block.d.ts +3 -3
- package/dist/crdt/attribution/block.js +7 -8
- package/dist/crdt/attribution/index.d.ts +1 -1
- package/dist/crdt/attribution/index.js +1 -1
- package/dist/crdt/data.d.ts +62 -31
- package/dist/crdt/data.js +211 -103
- package/dist/crdt/doc/delete.d.ts +1 -1
- package/dist/crdt/doc/delete.js +13 -30
- package/dist/crdt/doc/funnel.d.ts +7 -6
- package/dist/crdt/doc/funnel.js +39 -33
- package/dist/crdt/doc/gate.d.ts +3 -20
- package/dist/crdt/doc/gate.js +2 -41
- package/dist/crdt/doc/history.d.ts +25 -9
- package/dist/crdt/doc/history.js +152 -42
- package/dist/crdt/doc/layout.js +11 -22
- package/dist/crdt/doc/meta.js +12 -17
- package/dist/crdt/doc/moves.d.ts +1 -1
- package/dist/crdt/doc/moves.js +52 -32
- package/dist/crdt/doc/reads.js +2 -2
- package/dist/crdt/doc/seed.js +2 -2
- package/dist/crdt/doc/split-merge.js +12 -15
- package/dist/crdt/doc/steps.d.ts +25 -13
- package/dist/crdt/doc/steps.js +52 -122
- package/dist/crdt/doc/types.d.ts +21 -9
- package/dist/crdt/document.d.ts +21 -19
- package/dist/crdt/document.js +26 -23
- package/dist/crdt/edytor-doc.d.ts +66 -68
- package/dist/crdt/edytor-doc.js +21 -20
- package/dist/crdt/engine-api.d.ts +33 -1
- package/dist/crdt/engine.d.ts +0 -1
- package/dist/crdt/engine.js +1 -4
- package/dist/crdt/flow.d.ts +1 -1
- package/dist/crdt/flow.js +25 -27
- package/dist/crdt/index.d.ts +29 -28
- package/dist/crdt/index.js +3 -3
- package/dist/crdt/placement/display.d.ts +5 -30
- package/dist/crdt/placement/display.js +39 -144
- package/dist/crdt/placement/keys.d.ts +58 -0
- package/dist/crdt/placement/keys.js +90 -0
- package/dist/crdt/placement/model.d.ts +119 -118
- package/dist/crdt/placement/model.js +242 -142
- package/dist/crdt/placement/resolve.d.ts +123 -35
- package/dist/crdt/placement/resolve.js +187 -153
- package/dist/crdt/placement/slots.d.ts +134 -0
- package/dist/crdt/placement/slots.js +152 -0
- package/dist/crdt/protocol.d.ts +2 -2
- package/dist/crdt/protocol.js +2 -2
- package/dist/crdt/providers/index.d.ts +1 -1
- package/dist/crdt/providers/room.d.ts +26 -11
- package/dist/crdt/providers/room.js +77 -27
- package/dist/crdt/providers/websocket.d.ts +1 -1
- package/dist/crdt/providers/websocket.js +33 -32
- package/dist/crdt/purge.d.ts +17 -8
- package/dist/crdt/purge.js +236 -126
- package/dist/crdt/restore.d.ts +2 -2
- package/dist/crdt/restore.js +18 -34
- package/dist/crdt/schema.d.ts +22 -21
- package/dist/crdt/schema.js +29 -23
- package/dist/crdt/semantics.js +3 -1
- package/dist/crdt/storage.d.ts +1 -1
- package/dist/crdt/storage.js +1 -1
- package/dist/crdt/structs.d.ts +15 -15
- package/dist/crdt/structs.js +8 -22
- package/dist/crdt/text/index/cache.js +4 -0
- package/dist/crdt/text/index/claims.js +12 -0
- package/dist/crdt/text/index/fold.d.ts +2 -3
- package/dist/crdt/text/index/fold.js +194 -44
- package/dist/crdt/text/index/layout.js +5 -8
- package/dist/crdt/text/index/placement.d.ts +26 -18
- package/dist/crdt/text/index/placement.js +404 -138
- package/dist/crdt/text/index/records.d.ts +3 -3
- package/dist/crdt/text/index/records.js +24 -31
- package/dist/crdt/text/index/shared.d.ts +11 -3
- package/dist/crdt/text/index/shared.js +12 -3
- package/dist/crdt/text/index/state.d.ts +21 -17
- package/dist/crdt/text/index/state.js +15 -17
- package/dist/crdt/text/index/streams.d.ts +10 -5
- package/dist/crdt/text/index/streams.js +78 -27
- package/dist/crdt/text/items.d.ts +10 -3
- package/dist/crdt/text/items.js +7 -0
- package/dist/crdt/text/model.d.ts +77 -62
- package/dist/crdt/text/model.js +84 -169
- package/dist/crdt/text/ranges.d.ts +1 -1
- package/dist/crdt/text/ranges.js +3 -3
- package/dist/crdt/text/rows.d.ts +13 -7
- package/dist/crdt/text/rows.js +24 -7
- package/dist/crdt/text/runs.d.ts +17 -12
- package/dist/crdt/text/runs.js +24 -7
- package/dist/crdt/text/streams.d.ts +26 -13
- package/dist/crdt/text/streams.js +41 -14
- package/dist/crdt/vendor/yjs/UPSTREAM.md +568 -21
- package/dist/crdt/vendor/yjs/dts/global.d.ts +2 -0
- package/dist/crdt/vendor/yjs/dts/index.d.ts +1 -1
- package/dist/crdt/vendor/yjs/dts/structs/AbstractStruct.d.ts +7 -0
- package/dist/crdt/vendor/yjs/dts/structs/Item.d.ts +194 -10
- package/dist/crdt/vendor/yjs/dts/utils/Doc.d.ts +6 -3
- package/dist/crdt/vendor/yjs/dts/utils/StructStore.d.ts +5 -18
- package/dist/crdt/vendor/yjs/dts/utils/Transaction.d.ts +15 -1
- package/dist/crdt/vendor/yjs/dts/utils/UpdateDecoder.d.ts +14 -6
- package/dist/crdt/vendor/yjs/dts/utils/UpdateEncoder.d.ts +33 -6
- package/dist/crdt/vendor/yjs/dts/utils/ids.d.ts +1 -65
- package/dist/crdt/vendor/yjs/dts/utils/marks.d.ts +6 -1
- package/dist/crdt/vendor/yjs/dts/ynode.d.ts +43 -7
- package/dist/crdt/vendor/yjs/global.d.ts +2 -0
- package/dist/crdt/vendor/yjs/src/index.js +1 -1
- package/dist/crdt/vendor/yjs/src/structs/AbstractStruct.js +10 -0
- package/dist/crdt/vendor/yjs/src/structs/Item.js +610 -51
- package/dist/crdt/vendor/yjs/src/utils/BlockSet.js +18 -9
- package/dist/crdt/vendor/yjs/src/utils/Doc.js +5 -3
- package/dist/crdt/vendor/yjs/src/utils/StructStore.js +5 -0
- package/dist/crdt/vendor/yjs/src/utils/Transaction.js +36 -13
- package/dist/crdt/vendor/yjs/src/utils/UpdateDecoder.js +88 -18
- package/dist/crdt/vendor/yjs/src/utils/UpdateEncoder.js +119 -32
- package/dist/crdt/vendor/yjs/src/utils/encoding.js +13 -1
- package/dist/crdt/vendor/yjs/src/utils/ids.js +7 -7
- package/dist/crdt/vendor/yjs/src/utils/marks.js +193 -8
- package/dist/crdt/vendor/yjs/src/utils/redo.js +1 -1
- package/dist/crdt/vendor/yjs/src/utils/transaction-helpers.js +1 -1
- package/dist/crdt/vendor/yjs/src/utils/updates.js +3 -3
- package/dist/crdt/vendor/yjs/src/ynode.js +177 -12
- package/dist/dnd/autoScroll.d.ts +15 -7
- package/dist/dnd/autoScroll.js +10 -15
- package/dist/dnd/dropIndicator.js +2 -5
- package/dist/dnd/external.d.ts +6 -0
- package/dist/dnd/external.js +17 -0
- package/dist/dnd/geometry.d.ts +2 -0
- package/dist/dnd/geometry.js +3 -4
- package/dist/dnd/placement.d.ts +1 -1
- package/dist/dnd/pragmatic.d.ts +3 -1
- package/dist/dnd/pragmatic.js +12 -2
- package/dist/dnd/vendor/pragmatic/UPSTREAM.md +51 -18
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/drop-target-for-external.d.ts +4 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/drop-target-for-external.js +6 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/element-adapter.d.ts +0 -2
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/element-adapter.js +4 -22
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/external-adapter-types.d.ts +26 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/external-adapter.d.ts +30 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/external-adapter.js +203 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/get-available-items.js +13 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/get-available-types.js +9 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/is-an-available-type.js +19 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/monitor-for-external.d.ts +4 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/monitor-for-external.js +6 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/honey-pot-fix/make-honey-pot-fix.js +4 -16
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/internal-types.d.ts +1 -8
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/make-adapter/make-drop-target.js +5 -6
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/make-adapter/make-monitor.js +2 -3
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/element/custom-native-drag-preview/set-custom-native-drag-preview.d.ts +1 -1
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/element/custom-native-drag-preview/set-custom-native-drag-preview.js +6 -24
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/contains-files.d.ts +2 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/contains-files.js +5 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/get-files.d.ts +3 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/get-files.js +12 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/native-types.d.ts +12 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/changing-window/is-entering-window-in-safari.js +10 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/changing-window/is-entering-window.js +55 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/entry-point/external.d.ts +4 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/entry-point/external.js +8 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/internal-types.d.ts +0 -4
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/over-element/get-scroll-by.js +16 -72
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/over-element/try-scroll.js +1 -9
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/configuration.js +4 -29
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/get-scroll-change.js +2 -3
- package/dist/edytor.svelte.d.ts +2 -5
- package/dist/edytor.svelte.js +21 -32
- package/dist/events/beforeInputCommands.js +2 -2
- package/dist/events/onBeforeInput.js +1 -1
- package/dist/events/onDrop.d.ts +0 -6
- package/dist/events/onDrop.js +10 -23
- package/dist/events/onInput.d.ts +0 -12
- package/dist/events/onInput.js +1 -67
- package/dist/events/onPageHide.d.ts +3 -0
- package/dist/events/onPageHide.js +16 -0
- package/dist/export/forms.d.ts +627 -0
- package/dist/export/forms.js +749 -0
- package/dist/export/index.d.ts +170 -0
- package/dist/export/index.js +161 -0
- package/dist/export/markdown.d.ts +41 -0
- package/dist/export/markdown.js +585 -0
- package/dist/export/markdownWriter.d.ts +9 -0
- package/dist/export/markdownWriter.js +133 -0
- package/dist/export/mdx.d.ts +15 -0
- package/dist/export/mdx.js +33 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/kinds.js +1 -1
- package/dist/plugins/anchored.svelte.d.ts +21 -25
- package/dist/plugins/anchored.svelte.js +23 -39
- package/dist/plugins/blockHandles/BlockHandleController.svelte.js +24 -32
- package/dist/plugins/blockHandles/dragPreview.d.ts +26 -7
- package/dist/plugins/blockHandles/dragPreview.js +33 -0
- package/dist/plugins/blockMenu/BlockMenuController.svelte.d.ts +5 -0
- package/dist/plugins/blockMenu/BlockMenuController.svelte.js +7 -2
- package/dist/plugins/blockMenu/blockMenuPlugin.js +5 -50
- package/dist/plugins/chrome.d.ts +27 -5
- package/dist/plugins/chrome.js +24 -9
- package/dist/plugins/code/CodePlugin.svelte +12 -9
- package/dist/plugins/code/header.svelte.js +7 -11
- package/dist/plugins/code/languageMenu.svelte.d.ts +5 -2
- package/dist/plugins/code/languageMenu.svelte.js +13 -20
- package/dist/plugins/columns/ColumnsPlugin.svelte +7 -20
- package/dist/plugins/columns/resize.svelte.d.ts +2 -3
- package/dist/plugins/columns/resize.svelte.js +2 -5
- package/dist/plugins/comments/CommentsController.svelte.d.ts +6 -0
- package/dist/plugins/comments/CommentsController.svelte.js +20 -0
- package/dist/plugins/equation/EquationPlugin.svelte +12 -22
- package/dist/plugins/equation/equation.svelte.d.ts +7 -15
- package/dist/plugins/equation/equation.svelte.js +13 -50
- package/dist/plugins/equation/tex.d.ts +17 -0
- package/dist/plugins/equation/tex.js +42 -0
- package/dist/plugins/fileDrop.d.ts +38 -23
- package/dist/plugins/fileDrop.js +82 -76
- package/dist/plugins/find/FindController.svelte.d.ts +5 -0
- package/dist/plugins/find/FindController.svelte.js +14 -14
- package/dist/plugins/find/findPlugin.js +1 -15
- package/dist/plugins/image/ImageChrome.svelte +8 -2
- package/dist/plugins/image/ImagePlugin.svelte +15 -52
- package/dist/plugins/image/controls.svelte.js +16 -2
- package/dist/plugins/image/toolbar.svelte.d.ts +5 -4
- package/dist/plugins/image/toolbar.svelte.js +21 -31
- package/dist/plugins/index.d.ts +1 -1
- package/dist/plugins/list.svelte.d.ts +9 -0
- package/dist/plugins/list.svelte.js +18 -0
- package/dist/plugins/marquee/marqueePlugin.js +0 -4
- package/dist/plugins/media/AudioPlugin.svelte +1 -1
- package/dist/plugins/media/BookmarkPlugin.svelte +6 -97
- package/dist/plugins/media/EmbedPlugin.svelte +5 -90
- package/dist/plugins/media/EmptySlot.svelte +36 -20
- package/dist/plugins/media/EmptySlot.svelte.d.ts +6 -15
- package/dist/plugins/media/FilePlugin.svelte +1 -19
- package/dist/plugins/media/MediaEmpty.svelte +2 -55
- package/dist/plugins/media/MediaEmpty.svelte.d.ts +18 -14
- package/dist/plugins/media/SourceBlock.svelte +142 -52
- package/dist/plugins/media/SourceBlock.svelte.d.ts +10 -4
- package/dist/plugins/media/VideoPlugin.svelte +1 -1
- package/dist/plugins/media/empty.svelte.js +2 -7
- package/dist/plugins/media/media.d.ts +2 -63
- package/dist/plugins/media/media.js +1 -194
- package/dist/plugins/media/sources.d.ts +60 -0
- package/dist/plugins/media/sources.js +165 -0
- package/dist/plugins/media/urlPaste.svelte.d.ts +2 -1
- package/dist/plugins/media/urlPaste.svelte.js +12 -21
- package/dist/plugins/mention/MentionPlugin.svelte +8 -35
- package/dist/plugins/page/PagePlugin.svelte +2 -9
- package/dist/plugins/page/page.js +1 -1
- package/dist/plugins/pageLink/PageLinkPlugin.svelte +6 -13
- package/dist/plugins/richtext/RichTextPlugin.svelte +85 -197
- package/dist/plugins/richtext/body.js +1 -1
- package/dist/plugins/richtext/calloutIcons.svelte.d.ts +2 -2
- package/dist/plugins/richtext/calloutIcons.svelte.js +5 -7
- package/dist/plugins/richtext/richTextOperations.d.ts +1 -19
- package/dist/plugins/richtext/richTextOperations.js +3 -49
- package/dist/plugins/slashMenu/SlashMenuController.svelte.d.ts +2 -0
- package/dist/plugins/slashMenu/SlashMenuController.svelte.js +7 -0
- package/dist/plugins/slashMenu/slashMenuPlugin.js +5 -14
- package/dist/plugins/table/TableChrome.svelte +2 -3
- package/dist/plugins/table/TablePlugin.svelte +20 -54
- package/dist/plugins/table/chrome.svelte.d.ts +5 -2
- package/dist/plugins/table/chrome.svelte.js +30 -54
- package/dist/plugins/table/table.js +3 -3
- package/dist/plugins/toc/TocPlugin.svelte +2 -4
- package/dist/plugins/toolbar/ToolbarController.svelte.d.ts +7 -0
- package/dist/plugins/toolbar/ToolbarController.svelte.js +20 -13
- package/dist/plugins/toolbar/toolbarPlugin.js +19 -53
- package/dist/plugins/triggers/TriggerController.svelte.d.ts +7 -2
- package/dist/plugins/triggers/TriggerController.svelte.js +11 -4
- package/dist/plugins/triggers/place.js +1 -2
- package/dist/plugins/triggers/triggers.d.ts +6 -1
- package/dist/plugins/triggers/triggers.js +12 -13
- package/dist/plugins/uploads.svelte.d.ts +5 -2
- package/dist/plugins/uploads.svelte.js +25 -15
- package/dist/plugins.d.ts +26 -0
- package/dist/plugins.js +0 -24
- package/dist/selection/replaceSelection.js +2 -2
- package/dist/selection/selection.svelte.d.ts +4 -10
- package/dist/selection/selection.svelte.js +7 -11
- package/dist/session/bindings.js +1 -1
- package/dist/session/commands.d.ts +7 -11
- package/dist/session/commands.js +13 -19
- package/dist/session/inputRules.js +1 -1
- package/dist/session/navigation.js +1 -1
- package/dist/session/suggestions.svelte.d.ts +0 -11
- package/dist/session/suggestions.svelte.js +15 -3
- package/dist/session/uploads.d.ts +8 -8
- package/dist/surface/lines.js +1 -3
- package/dist/surface/observer.svelte.d.ts +17 -1
- package/dist/surface/observer.svelte.js +74 -19
- package/dist/surface/overlay.d.ts +0 -14
- package/dist/surface/overlay.js +0 -25
- package/dist/surface/projector.svelte.d.ts +15 -3
- package/dist/surface/projector.svelte.js +60 -9
- package/dist/text/text.svelte.js +3 -13
- package/dist/utils/sanitize.d.ts +38 -0
- package/dist/utils/sanitize.js +82 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +5 -0
- package/package.json +19 -2
- package/dist/crdt/placement/rank.d.ts +0 -87
- package/dist/crdt/placement/rank.js +0 -332
- package/dist/crdt/placement/source.d.ts +0 -43
- package/dist/crdt/placement/source.js +0 -66
- package/dist/crdt/text/delete-index.d.ts +0 -129
- package/dist/crdt/text/delete-index.js +0 -365
- package/dist/crdt/text/deletes.d.ts +0 -76
- package/dist/crdt/text/deletes.js +0 -362
- package/dist/crdt/text/index/anchored.d.ts +0 -17
- package/dist/crdt/text/index/anchored.js +0 -197
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/max-z-index.js +0 -3
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/supports-popover.js +0 -16
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/is-axis-allowed.js +0 -3
- package/dist/plugins/code/LanguageMenu.svelte +0 -25
- package/dist/plugins/code/LanguageMenu.svelte.d.ts +0 -9
- package/dist/plugins/equation/EquationEditor.svelte +0 -27
- package/dist/plugins/equation/EquationEditor.svelte.d.ts +0 -9
- package/dist/plugins/image/ImageToolbarHost.svelte +0 -37
- package/dist/plugins/image/ImageToolbarHost.svelte.d.ts +0 -9
- package/dist/plugins/richtext/CalloutIconPicker.svelte +0 -26
- package/dist/plugins/richtext/CalloutIconPicker.svelte.d.ts +0 -9
|
@@ -1,32 +1,29 @@
|
|
|
1
1
|
<script lang="ts" module>
|
|
2
|
-
import type {
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { Block } from '../../block/block.svelte.js';
|
|
4
4
|
import type { Edytor } from '../../edytor.svelte.js';
|
|
5
5
|
import type { MediaKind } from './media.js';
|
|
6
|
-
import
|
|
6
|
+
import { MediaEmptyController, type EmptyView } from './empty.svelte.js';
|
|
7
7
|
|
|
8
|
-
/**
|
|
9
|
-
|
|
10
|
-
Host: Component<{
|
|
11
|
-
block: Block | undefined;
|
|
12
|
-
kind: MediaKind | 'image';
|
|
13
|
-
viewOf: (edytor: Edytor | undefined) => EmptyView | undefined;
|
|
14
|
-
empty: Snippet<[MediaEmptyController]>;
|
|
15
|
-
}>;
|
|
16
|
-
empty: Snippet<[MediaEmptyController]>;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
/** Each view's empty-block chrome (the first media empty plugin listed claims it). */
|
|
20
|
-
export const emptyHosts = new WeakMap<object, EmptyHost>();
|
|
8
|
+
/** Each view's empty-block markup (the first media empty plugin listed claims it). */
|
|
9
|
+
export const emptyHosts = new WeakMap<object, Snippet<[MediaEmptyController]>>();
|
|
21
10
|
</script>
|
|
22
11
|
|
|
23
12
|
<script lang="ts">
|
|
24
13
|
import { getContext, untrack } from 'svelte';
|
|
14
|
+
import { fileUploads } from '../uploads.svelte.js';
|
|
25
15
|
|
|
26
16
|
/**
|
|
27
|
-
* Where an empty image or media block shows its empty state:
|
|
28
|
-
*
|
|
29
|
-
*
|
|
17
|
+
* Where an empty image or media block shows its empty state: a
|
|
18
|
+
* `MediaEmptyController`, which the view's `empty` snippet (the media
|
|
19
|
+
* empty plugin's) draws, when one is listed (else nothing). The view
|
|
20
|
+
* rendering it is the block's, or a suggestion preview's. The kind in the
|
|
21
|
+
* block's view (`viewOf`) stores the link, or an uploaded file's URL
|
|
22
|
+
* (only on a block still empty when it lands). A readonly view, or a
|
|
23
|
+
* suggestion's preview (no `block`), may not write: no control may run
|
|
24
|
+
* `upload`. A pasted or dropped file shows its upload (`pending`); a
|
|
25
|
+
* failed one opens the panel with its error; data answered while the
|
|
26
|
+
* block was not shown fills it as soon as it shows.
|
|
30
27
|
*/
|
|
31
28
|
let {
|
|
32
29
|
block,
|
|
@@ -35,10 +32,29 @@
|
|
|
35
32
|
}: {
|
|
36
33
|
block: Block | undefined;
|
|
37
34
|
kind: MediaKind | 'image';
|
|
35
|
+
/** The kind in a view: how it stores a source. */
|
|
38
36
|
viewOf: (edytor: Edytor | undefined) => EmptyView | undefined;
|
|
39
37
|
} = $props();
|
|
40
38
|
const view = getContext<Edytor>('edytor');
|
|
41
|
-
const
|
|
39
|
+
const empty = untrack(() => emptyHosts.get(block?.edytor ?? view));
|
|
40
|
+
const panel = untrack(() => new MediaEmptyController(block, kind, viewOf(block?.edytor)));
|
|
41
|
+
/** The upload of a pasted or dropped file into this block, if any. */
|
|
42
|
+
const pending = $derived(empty && panel.pending);
|
|
43
|
+
// After the flush that shows the block: never inside the transaction that showed it.
|
|
44
|
+
$effect(() => {
|
|
45
|
+
if (pending?.status === 'landed' && block && !block.edytor.readonly) {
|
|
46
|
+
const id = block.id;
|
|
47
|
+
untrack(() => fileUploads(block.edytor)?.fill(id));
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
// The panel opens on a failed upload, with its error; the user closes it.
|
|
51
|
+
$effect(() => {
|
|
52
|
+
if (pending?.status === 'failed')
|
|
53
|
+
untrack(() => {
|
|
54
|
+
panel.open = true;
|
|
55
|
+
panel.failed = 'upload';
|
|
56
|
+
});
|
|
57
|
+
});
|
|
42
58
|
</script>
|
|
43
59
|
|
|
44
|
-
{#if
|
|
60
|
+
{#if empty}{@render empty(panel)}{/if}
|
|
@@ -1,25 +1,16 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
2
|
import type { Block } from '../../block/block.svelte.js';
|
|
3
3
|
import type { Edytor } from '../../edytor.svelte.js';
|
|
4
4
|
import type { MediaKind } from './media.js';
|
|
5
|
-
import
|
|
6
|
-
/**
|
|
7
|
-
|
|
8
|
-
Host: Component<{
|
|
9
|
-
block: Block | undefined;
|
|
10
|
-
kind: MediaKind | 'image';
|
|
11
|
-
viewOf: (edytor: Edytor | undefined) => EmptyView | undefined;
|
|
12
|
-
empty: Snippet<[MediaEmptyController]>;
|
|
13
|
-
}>;
|
|
14
|
-
empty: Snippet<[MediaEmptyController]>;
|
|
15
|
-
};
|
|
16
|
-
/** Each view's empty-block chrome (the first media empty plugin listed claims it). */
|
|
17
|
-
export declare const emptyHosts: WeakMap<object, EmptyHost>;
|
|
5
|
+
import { MediaEmptyController, type EmptyView } from './empty.svelte.js';
|
|
6
|
+
/** Each view's empty-block markup (the first media empty plugin listed claims it). */
|
|
7
|
+
export declare const emptyHosts: WeakMap<object, Snippet<[MediaEmptyController]>>;
|
|
18
8
|
type $$ComponentProps = {
|
|
19
9
|
block: Block | undefined;
|
|
20
10
|
kind: MediaKind | 'image';
|
|
11
|
+
/** The kind in a view: how it stores a source. */
|
|
21
12
|
viewOf: (edytor: Edytor | undefined) => EmptyView | undefined;
|
|
22
13
|
};
|
|
23
|
-
declare const EmptySlot: Component<$$ComponentProps, {}, "">;
|
|
14
|
+
declare const EmptySlot: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
24
15
|
type EmptySlot = ReturnType<typeof EmptySlot>;
|
|
25
16
|
export default EmptySlot;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { Plugin } from '../../plugins.js';
|
|
4
|
-
import {
|
|
4
|
+
import { type FileRowPayload } from './media.js';
|
|
5
5
|
import { sourcePlugin } from './SourceBlock.svelte';
|
|
6
6
|
import type { Uploader } from '../uploads.svelte.js';
|
|
7
7
|
|
|
@@ -33,24 +33,6 @@
|
|
|
33
33
|
sourcePlugin(
|
|
34
34
|
'file',
|
|
35
35
|
['attachment', 'upload', 'pdf', 'document'],
|
|
36
|
-
{
|
|
37
|
-
html: (block, caption) => {
|
|
38
|
-
const src = safeMediaSrc(block.data?.src);
|
|
39
|
-
const name = String(block.data?.name || (src && fileNameOf(src)) || '');
|
|
40
|
-
const link = src ? `<a href="${escapeHtml(src)}">${escapeHtml(name)}</a>` : '';
|
|
41
|
-
return `<figure data-edytor-file>${link}<figcaption>${caption}</figcaption></figure>`;
|
|
42
|
-
},
|
|
43
|
-
plain: (block, caption) =>
|
|
44
|
-
[safeMediaSrc(block.data?.src), caption].filter(Boolean).join('\n'),
|
|
45
|
-
// Its own export: a `figure[data-edytor-file]` holding the link.
|
|
46
|
-
parse: (el) => {
|
|
47
|
-
if (el.localName !== 'figure' || !el.hasAttribute('data-edytor-file')) return;
|
|
48
|
-
const anchor = el.querySelector('a[href]');
|
|
49
|
-
const src = safeMediaSrc(anchor?.getAttribute('href'));
|
|
50
|
-
const name = anchor?.textContent?.trim().slice(0, 300);
|
|
51
|
-
return src ? { src, name: name || fileNameOf(src) } : undefined;
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
36
|
{ row: options.row },
|
|
55
37
|
options.upload
|
|
56
38
|
);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script lang="ts" module>
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { MediaEmptyController } from './empty.svelte.js';
|
|
3
4
|
import type { Plugin } from '../../plugins.js';
|
|
4
5
|
import { emptyHosts } from './EmptySlot.svelte';
|
|
5
|
-
import Self from './MediaEmpty.svelte';
|
|
6
6
|
|
|
7
7
|
export type MediaEmptyOptions = {
|
|
8
8
|
/**
|
|
@@ -23,60 +23,7 @@
|
|
|
23
23
|
export const createMediaEmptyPlugin =
|
|
24
24
|
({ empty }: MediaEmptyOptions): Plugin =>
|
|
25
25
|
(edytor) => {
|
|
26
|
-
if (edytor && !emptyHosts.has(edytor)) emptyHosts.set(edytor,
|
|
26
|
+
if (edytor && !emptyHosts.has(edytor)) emptyHosts.set(edytor, empty);
|
|
27
27
|
return {};
|
|
28
28
|
};
|
|
29
29
|
</script>
|
|
30
|
-
|
|
31
|
-
<script lang="ts">
|
|
32
|
-
import { untrack } from 'svelte';
|
|
33
|
-
import type { Block } from '../../block/block.svelte.js';
|
|
34
|
-
import type { Edytor } from '../../edytor.svelte.js';
|
|
35
|
-
import type { MediaKind } from './media.js';
|
|
36
|
-
import { MediaEmptyController, type EmptyView } from './empty.svelte.js';
|
|
37
|
-
import { fileUploads } from '../uploads.svelte.js';
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* An image's or a media block's empty state: a `MediaEmptyController`,
|
|
41
|
-
* which the view's `empty` snippet draws. The kind in the
|
|
42
|
-
* block's view (`viewOf`) stores the link, or an uploaded file's URL
|
|
43
|
-
* (only on a block still empty when it lands). A readonly view, or a
|
|
44
|
-
* suggestion's preview (no `block`), may not write: no control may run
|
|
45
|
-
* `upload`. A pasted or dropped file shows its upload (`pending`); a
|
|
46
|
-
* failed one opens the panel with its error; data answered while the
|
|
47
|
-
* block was not shown fills it as soon as it shows.
|
|
48
|
-
*/
|
|
49
|
-
let {
|
|
50
|
-
block,
|
|
51
|
-
kind,
|
|
52
|
-
viewOf,
|
|
53
|
-
empty
|
|
54
|
-
}: {
|
|
55
|
-
block: Block | undefined;
|
|
56
|
-
kind: MediaKind | 'image';
|
|
57
|
-
/** The kind in a view: how it stores a source. */
|
|
58
|
-
viewOf: (edytor: Edytor | undefined) => EmptyView | undefined;
|
|
59
|
-
/** The view's `empty` snippet. */
|
|
60
|
-
empty: Snippet<[MediaEmptyController]>;
|
|
61
|
-
} = $props();
|
|
62
|
-
const panel = untrack(() => new MediaEmptyController(block, kind, viewOf(block?.edytor)));
|
|
63
|
-
/** The upload of a pasted or dropped file into this block, if any. */
|
|
64
|
-
const pending = $derived(panel.pending);
|
|
65
|
-
// After the flush that shows the block: never inside the transaction that showed it.
|
|
66
|
-
$effect(() => {
|
|
67
|
-
if (pending?.status === 'landed' && block && !block.edytor.readonly) {
|
|
68
|
-
const id = block.id;
|
|
69
|
-
untrack(() => fileUploads(block.edytor)?.fill(id));
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
// The panel opens on a failed upload, with its error; the user closes it.
|
|
73
|
-
$effect(() => {
|
|
74
|
-
if (pending?.status === 'failed')
|
|
75
|
-
untrack(() => {
|
|
76
|
-
panel.open = true;
|
|
77
|
-
panel.failed = 'upload';
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
</script>
|
|
81
|
-
|
|
82
|
-
{@render empty(panel)}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { MediaEmptyController } from './empty.svelte.js';
|
|
2
3
|
import type { Plugin } from '../../plugins.js';
|
|
3
4
|
export type MediaEmptyOptions = {
|
|
4
5
|
/**
|
|
@@ -16,18 +17,21 @@ export type MediaEmptyOptions = {
|
|
|
16
17
|
* listed claims the view.
|
|
17
18
|
*/
|
|
18
19
|
export declare const createMediaEmptyPlugin: ({ empty }: MediaEmptyOptions) => Plugin;
|
|
19
|
-
|
|
20
|
-
import
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
20
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
21
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
22
|
+
$$bindings?: Bindings;
|
|
23
|
+
} & Exports;
|
|
24
|
+
(internal: unknown, props: {
|
|
25
|
+
$$events?: Events;
|
|
26
|
+
$$slots?: Slots;
|
|
27
|
+
}): Exports & {
|
|
28
|
+
$set?: any;
|
|
29
|
+
$on?: any;
|
|
30
|
+
};
|
|
31
|
+
z_$$bindings?: Bindings;
|
|
32
|
+
}
|
|
33
|
+
declare const MediaEmpty: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
34
|
+
[evt: string]: CustomEvent<any>;
|
|
35
|
+
}, {}, {}, string>;
|
|
36
|
+
type MediaEmpty = InstanceType<typeof MediaEmpty>;
|
|
33
37
|
export default MediaEmpty;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
|
-
import
|
|
2
|
+
import { capped, mediaForms } from '../../export/forms.js';
|
|
3
|
+
import type { Block } from '../../block/block.svelte.js';
|
|
4
|
+
import type { BlockSnippetPayload, Plugin } from '../../plugins.js';
|
|
3
5
|
import EmptySlot from './EmptySlot.svelte';
|
|
4
6
|
import Control from '../Control.svelte';
|
|
5
7
|
import { labelsOf, mediaEnglish } from '../../labels.js';
|
|
@@ -7,13 +9,18 @@
|
|
|
7
9
|
import UploadPreview from './UploadPreview.svelte';
|
|
8
10
|
import { fileUploads, uploadHooks, type Uploader } from '../uploads.svelte.js';
|
|
9
11
|
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
EMBED_ALLOW,
|
|
13
|
+
EMBED_SANDBOX,
|
|
14
|
+
embedSourceOf,
|
|
15
|
+
fileNameFor,
|
|
12
16
|
fileNameOf,
|
|
17
|
+
safeWebUrl,
|
|
18
|
+
type BookmarkCardPayload,
|
|
19
|
+
type EmbedFallbackPayload,
|
|
20
|
+
type MediaKind,
|
|
13
21
|
mediaControl,
|
|
14
22
|
mediaLink,
|
|
15
23
|
mediaPlugin,
|
|
16
|
-
mediaSourceOf,
|
|
17
24
|
mediaView,
|
|
18
25
|
safeMediaSrc,
|
|
19
26
|
LINK_REL,
|
|
@@ -23,8 +30,47 @@
|
|
|
23
30
|
|
|
24
31
|
type SourceKind = 'video' | 'audio' | 'file';
|
|
25
32
|
|
|
26
|
-
/** The view's file row
|
|
33
|
+
/** The view's markup for a file's row, a bookmark's card, an unplayable embed's link, if the app gave one. */
|
|
27
34
|
const rowOf = mediaControl('file', 'row');
|
|
35
|
+
const cardOf = mediaControl('bookmark', 'card');
|
|
36
|
+
const fallbackOf = mediaControl('embed', 'fallback');
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* The view's embed allowlist: the first embed plugin listed in it (first
|
|
40
|
+
* wins, as for the kind). Never a broader list: no entry plays nothing.
|
|
41
|
+
*/
|
|
42
|
+
const providers = (block: Block | undefined) =>
|
|
43
|
+
mediaView(block?.edytor, 'embed')?.providers ?? [];
|
|
44
|
+
|
|
45
|
+
/** The fields of a bookmark's `preview` it stores and shows: text capped, images `safeWebUrl` only. */
|
|
46
|
+
export const previewData = (preview: Record<string, unknown> | null | undefined) => {
|
|
47
|
+
const fields = {
|
|
48
|
+
title: capped(preview?.title, 300),
|
|
49
|
+
description: capped(preview?.description, 1000),
|
|
50
|
+
image: safeWebUrl(preview?.image) ?? undefined,
|
|
51
|
+
icon: safeWebUrl(preview?.icon) ?? undefined
|
|
52
|
+
};
|
|
53
|
+
return Object.fromEntries(Object.entries(fields).filter(([, value]) => value !== undefined));
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/** A file's row: its source, name and size, and whether it is uploading. */
|
|
57
|
+
const fileRow = (
|
|
58
|
+
block: Block | undefined,
|
|
59
|
+
src: string,
|
|
60
|
+
name: string,
|
|
61
|
+
size: number | undefined,
|
|
62
|
+
progress?: number | null
|
|
63
|
+
): FileRowPayload => ({
|
|
64
|
+
block,
|
|
65
|
+
src,
|
|
66
|
+
name,
|
|
67
|
+
size,
|
|
68
|
+
sizeLabel:
|
|
69
|
+
size === undefined ? '' : labelsOf(block?.edytor, 'media', mediaEnglish).fileSize(size),
|
|
70
|
+
uploading: progress !== undefined,
|
|
71
|
+
progress: progress ?? null,
|
|
72
|
+
link: mediaLink({ draggable: 'false', download: name })
|
|
73
|
+
});
|
|
28
74
|
|
|
29
75
|
/** The files each kind takes: a video, an audio track, any other file. */
|
|
30
76
|
const ACCEPTS: Record<SourceKind, (file: File) => boolean> = {
|
|
@@ -54,24 +100,12 @@
|
|
|
54
100
|
* `src`), and with an `upload` (its uploader), the pasted, dropped and
|
|
55
101
|
* picked files it takes (`media.files`). A video or an audio track
|
|
56
102
|
* exports as its tag in a `figure` and imports from one (bare, or in a
|
|
57
|
-
* `figure`) with a safe `src` or `source
|
|
58
|
-
*
|
|
103
|
+
* `figure`) with a safe `src` or `source`, a file as its link; the file
|
|
104
|
+
* kind brings its `row` markup (`own`).
|
|
59
105
|
*/
|
|
60
106
|
export const sourcePlugin = (
|
|
61
107
|
kind: SourceKind,
|
|
62
108
|
keywords: string[],
|
|
63
|
-
record: Partial<BlockDefinition> = {
|
|
64
|
-
html: (block, caption) => {
|
|
65
|
-
const src = safeMediaSrc(block.data?.src);
|
|
66
|
-
// The tag, then its attributes: `<video src="…" controls></video>`.
|
|
67
|
-
const media = src ? `<${kind}` + ` src="${escapeHtml(src)}" controls></${kind}>` : '';
|
|
68
|
-
return `<figure>${media}<figcaption>${caption}</figcaption></figure>`;
|
|
69
|
-
},
|
|
70
|
-
parse: (el) => {
|
|
71
|
-
const src = mediaSourceOf(claimed(el, kind));
|
|
72
|
-
return src ? { src } : undefined;
|
|
73
|
-
}
|
|
74
|
-
},
|
|
75
109
|
own: Pick<MediaView, 'row'> = {},
|
|
76
110
|
upload?: Uploader
|
|
77
111
|
): Plugin =>
|
|
@@ -98,42 +132,80 @@
|
|
|
98
132
|
filled: (data: Record<string, unknown>) => safeMediaSrc(data.src) !== null
|
|
99
133
|
}
|
|
100
134
|
}),
|
|
101
|
-
...
|
|
135
|
+
...mediaForms()[kind]
|
|
102
136
|
}
|
|
103
137
|
};
|
|
104
138
|
});
|
|
139
|
+
|
|
140
|
+
export { source };
|
|
105
141
|
</script>
|
|
106
142
|
|
|
107
143
|
<!--
|
|
108
|
-
A file (its name and size, linking to it), a video or an
|
|
109
|
-
the browser's player,
|
|
110
|
-
caption below.
|
|
144
|
+
A media block: a file (its name and size, linking to it), a video or an
|
|
145
|
+
audio track in the browser's player, an embed's player (or its link), a
|
|
146
|
+
bookmark's card, or the empty block until it has a source; its caption below.
|
|
111
147
|
-->
|
|
112
148
|
{#snippet source({ block, content }: BlockSnippetPayload<Record<string, unknown>>)}
|
|
113
|
-
{@const
|
|
149
|
+
{@const url = safeWebUrl(block.data.url)}
|
|
150
|
+
{@const src =
|
|
151
|
+
block.type === 'embed' || block.type === 'bookmark' ? url : safeMediaSrc(block.data.src)}
|
|
152
|
+
{@const player =
|
|
153
|
+
block.type === 'embed' && block.handle ? embedSourceOf(url, providers(block.handle)) : null}
|
|
114
154
|
{@const pending =
|
|
115
155
|
block.handle && !src ? fileUploads(block.handle.edytor)?.of(block.id) : undefined}
|
|
116
|
-
{#if
|
|
117
|
-
{@const
|
|
118
|
-
|
|
119
|
-
|
|
156
|
+
{#if player}
|
|
157
|
+
{@const { height, aspectRatio = '16 / 9' } = player.provider}
|
|
158
|
+
<div
|
|
159
|
+
use:block.void
|
|
160
|
+
data-edytor-embed
|
|
161
|
+
style:aspect-ratio={height ? undefined : aspectRatio}
|
|
162
|
+
style:height={height ? `${height}px` : undefined}
|
|
163
|
+
>
|
|
164
|
+
<iframe
|
|
165
|
+
src={player.src}
|
|
166
|
+
title={player.provider.name}
|
|
167
|
+
sandbox={EMBED_SANDBOX}
|
|
168
|
+
allow={EMBED_ALLOW}
|
|
169
|
+
referrerpolicy="strict-origin-when-cross-origin"
|
|
170
|
+
loading="lazy"
|
|
171
|
+
allowfullscreen
|
|
172
|
+
style="display: block; width: 100%; height: 100%; border: 0"
|
|
173
|
+
></iframe>
|
|
174
|
+
</div>
|
|
175
|
+
{:else if url && block.type === 'embed'}
|
|
176
|
+
<!-- A link no provider plays (a peer may store any), or a suggestion's preview (no handle, so no
|
|
177
|
+
view's allowlist): a plain link, never a frame. -->
|
|
178
|
+
<div use:block.void data-edytor-embed-unsupported>
|
|
179
|
+
<Control
|
|
180
|
+
own={fallbackOf}
|
|
181
|
+
initial={link}
|
|
182
|
+
payload={{ block: block.handle, url, link: mediaLink() }}
|
|
183
|
+
/>
|
|
184
|
+
</div>
|
|
185
|
+
{:else if url && block.type === 'bookmark'}
|
|
186
|
+
<div use:block.void data-edytor-bookmark>
|
|
187
|
+
<Control
|
|
188
|
+
own={cardOf}
|
|
189
|
+
initial={card}
|
|
190
|
+
payload={{
|
|
191
|
+
block: block.handle,
|
|
192
|
+
url,
|
|
193
|
+
...previewData(block.data),
|
|
194
|
+
link: mediaLink({ draggable: 'false' })
|
|
195
|
+
} as BookmarkCardPayload}
|
|
196
|
+
/>
|
|
197
|
+
</div>
|
|
198
|
+
{:else if src && block.type === 'file'}
|
|
120
199
|
<div use:block.void data-edytor-file>
|
|
121
200
|
<Control
|
|
122
201
|
own={rowOf}
|
|
123
202
|
{initial}
|
|
124
|
-
payload={
|
|
125
|
-
block
|
|
203
|
+
payload={fileRow(
|
|
204
|
+
block.handle,
|
|
126
205
|
src,
|
|
127
|
-
|
|
128
|
-
size
|
|
129
|
-
|
|
130
|
-
size === undefined
|
|
131
|
-
? ''
|
|
132
|
-
: labelsOf(block.handle?.edytor, 'media', mediaEnglish).fileSize(size),
|
|
133
|
-
uploading: false,
|
|
134
|
-
progress: null,
|
|
135
|
-
link: mediaLink({ draggable: 'false', download: name })
|
|
136
|
-
}}
|
|
206
|
+
fileNameFor(block.data, src),
|
|
207
|
+
typeof block.data.size === 'number' ? block.data.size : undefined
|
|
208
|
+
)}
|
|
137
209
|
/>
|
|
138
210
|
</div>
|
|
139
211
|
{:else if !src && pending?.status === 'uploading' && !emptyHosts.has(block.handle!.edytor)}
|
|
@@ -143,16 +215,13 @@
|
|
|
143
215
|
<Control
|
|
144
216
|
own={rowOf}
|
|
145
217
|
{initial}
|
|
146
|
-
payload={
|
|
147
|
-
block
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
progress: pending.progress,
|
|
154
|
-
link: mediaLink({ draggable: 'false', download: pending.name })
|
|
155
|
-
}}
|
|
218
|
+
payload={fileRow(
|
|
219
|
+
block.handle,
|
|
220
|
+
pending.preview,
|
|
221
|
+
pending.name,
|
|
222
|
+
pending.size,
|
|
223
|
+
pending.progress
|
|
224
|
+
)}
|
|
156
225
|
/>
|
|
157
226
|
{:else}
|
|
158
227
|
<UploadPreview upload={pending} />
|
|
@@ -178,8 +247,8 @@
|
|
|
178
247
|
<div use:block.void data-edytor-media-empty>
|
|
179
248
|
<EmptySlot
|
|
180
249
|
block={block.handle}
|
|
181
|
-
kind={block.type as
|
|
182
|
-
viewOf={(edytor) => mediaView(edytor, block.type as
|
|
250
|
+
kind={block.type as MediaKind}
|
|
251
|
+
viewOf={(edytor) => mediaView(edytor, block.type as MediaKind)}
|
|
183
252
|
/>
|
|
184
253
|
</div>
|
|
185
254
|
{/if}
|
|
@@ -188,6 +257,27 @@
|
|
|
188
257
|
<figcaption>{@render content()}</figcaption>
|
|
189
258
|
{/snippet}
|
|
190
259
|
|
|
260
|
+
<!-- An embed no provider plays: the link itself. -->
|
|
261
|
+
{#snippet link({ url, link }: EmbedFallbackPayload)}
|
|
262
|
+
<a href={url} target="_blank" rel={LINK_REL} {@attach link}>{url}</a>
|
|
263
|
+
{/snippet}
|
|
264
|
+
|
|
265
|
+
<!-- Notion's card: the page's title, description and URL (with its icon) beside its cover. -->
|
|
266
|
+
{#snippet card({ url, title, description, image, icon, link }: BookmarkCardPayload)}
|
|
267
|
+
<a href={url} target="_blank" rel={LINK_REL} draggable="false" {@attach link}>
|
|
268
|
+
<span data-edytor-bookmark-text>
|
|
269
|
+
<span data-edytor-bookmark-title>{title ?? url}</span>
|
|
270
|
+
{#if description}<span data-edytor-bookmark-description>{description}</span>{/if}
|
|
271
|
+
<span data-edytor-bookmark-url>
|
|
272
|
+
{#if icon}<img src={icon} alt="" draggable="false" />{/if}<span>{url}</span>
|
|
273
|
+
</span>
|
|
274
|
+
</span>
|
|
275
|
+
{#if image}
|
|
276
|
+
<span data-edytor-bookmark-cover><img src={image} alt="" draggable="false" /></span>
|
|
277
|
+
{/if}
|
|
278
|
+
</a>
|
|
279
|
+
{/snippet}
|
|
280
|
+
|
|
191
281
|
<!-- A file: its name and size, a link downloading it. -->
|
|
192
282
|
{#snippet initial({ src, name, sizeLabel, link, uploading, progress }: FileRowPayload)}
|
|
193
283
|
<a href={src} target="_blank" rel={LINK_REL} draggable="false" download={name} {@attach link}>
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { BlockSnippetPayload, Plugin } from '../../plugins.js';
|
|
2
2
|
import { type Uploader } from '../uploads.svelte.js';
|
|
3
3
|
import { type MediaView } from './media.js';
|
|
4
|
+
declare const source: ({ block, content }: BlockSnippetPayload<Record<string, unknown>>) => ReturnType<import("svelte").Snippet>;
|
|
4
5
|
type SourceKind = 'video' | 'audio' | 'file';
|
|
6
|
+
/** The fields of a bookmark's `preview` it stores and shows: text capped, images `safeWebUrl` only. */
|
|
7
|
+
export declare const previewData: (preview: Record<string, unknown> | null | undefined) => {
|
|
8
|
+
[k: string]: string | undefined;
|
|
9
|
+
};
|
|
5
10
|
/**
|
|
6
11
|
* The plugin of a kind holding one source (a video, an audio track, an
|
|
7
12
|
* attachment; Notion's): a media kind (`mediaPlugin`) drawn by this
|
|
@@ -10,10 +15,11 @@ type SourceKind = 'video' | 'audio' | 'file';
|
|
|
10
15
|
* `src`), and with an `upload` (its uploader), the pasted, dropped and
|
|
11
16
|
* picked files it takes (`media.files`). A video or an audio track
|
|
12
17
|
* exports as its tag in a `figure` and imports from one (bare, or in a
|
|
13
|
-
* `figure`) with a safe `src` or `source
|
|
14
|
-
*
|
|
18
|
+
* `figure`) with a safe `src` or `source`, a file as its link; the file
|
|
19
|
+
* kind brings its `row` markup (`own`).
|
|
15
20
|
*/
|
|
16
|
-
export declare const sourcePlugin: (kind: SourceKind, keywords: string[],
|
|
21
|
+
export declare const sourcePlugin: (kind: SourceKind, keywords: string[], own?: Pick<MediaView, "row">, upload?: Uploader) => Plugin;
|
|
22
|
+
export { source };
|
|
17
23
|
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
18
24
|
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
19
25
|
$$bindings?: Bindings;
|
|
@@ -20,5 +20,5 @@
|
|
|
20
20
|
* text is the caption.
|
|
21
21
|
*/
|
|
22
22
|
export const createVideoPlugin = ({ upload }: VideoPluginOptions = {}): Plugin =>
|
|
23
|
-
sourcePlugin('video', ['movie', 'mp4', 'clip'],
|
|
23
|
+
sourcePlugin('video', ['movie', 'mp4', 'clip'], {}, upload);
|
|
24
24
|
</script>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { fileUploads } from '../uploads.svelte.js';
|
|
2
2
|
import { listen } from '../../utils/listen.js';
|
|
3
|
+
import { keysOf } from '../list.svelte.js';
|
|
3
4
|
/** Each media kind's icon (the image's too): its menu row, its empty block, its paste offer. */
|
|
4
5
|
export const MEDIA_ICONS = {
|
|
5
6
|
image: '🖼',
|
|
@@ -111,12 +112,6 @@ export class MediaEmptyController {
|
|
|
111
112
|
};
|
|
112
113
|
/** The link field (`{@attach empty.field}`): Enter embeds its `draft`. */
|
|
113
114
|
field = (node) => {
|
|
114
|
-
|
|
115
|
-
if (event.key !== 'Enter' || event.isComposing)
|
|
116
|
-
return;
|
|
117
|
-
event.preventDefault();
|
|
118
|
-
this.embed();
|
|
119
|
-
};
|
|
120
|
-
return listen(node, 'keydown', keydown);
|
|
115
|
+
return listen(node, 'keydown', keysOf({ Enter: () => this.embed() }));
|
|
121
116
|
};
|
|
122
117
|
}
|
|
@@ -101,67 +101,6 @@ export declare const mediaPlugin: (kind: MediaKind, keywords: string[], own: (ed
|
|
|
101
101
|
hooks?: PluginOperations & PluginDefinitions;
|
|
102
102
|
record: Partial<BlockDefinition>;
|
|
103
103
|
}) => Plugin;
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
* reading of it (`sanitizeLinkHref`: ASCII control characters and spaces stripped,
|
|
107
|
-
* tab/newline anywhere), then only an absolute `http:`/`https:` URL with a
|
|
108
|
-
* host. `null` for anything else: a script or `data:` URL, a `mailto:`, a
|
|
109
|
-
* relative path, a bare domain.
|
|
110
|
-
*/
|
|
111
|
-
export declare const safeWebUrl: (value: unknown) => string | null;
|
|
112
|
-
/**
|
|
113
|
-
* A media file's source (a video, an audio track, an attachment): a
|
|
114
|
-
* {@link safeWebUrl}, or a `blob:` URL an upload answered. Never `data:`:
|
|
115
|
-
* an inline file would be stored in the document and sent in every update.
|
|
116
|
-
*/
|
|
117
|
-
export declare const safeMediaSrc: (value: unknown) => string | null;
|
|
118
|
-
/** One allowlisted embed provider: which links it plays, and its player. */
|
|
119
|
-
export type EmbedProvider = {
|
|
120
|
-
/** The provider's name: the frame's `title`. */
|
|
121
|
-
name: string;
|
|
122
|
-
/**
|
|
123
|
-
* The player's URL for a link of this provider, else `null`. It must be
|
|
124
|
-
* `https:` on another origin than the page's: any other answer is
|
|
125
|
-
* refused (the frame has `allow-scripts` and `allow-same-origin`, so a
|
|
126
|
-
* player on the page's origin, or on one that can script it, could lift
|
|
127
|
-
* its own sandbox). Match the host exactly (never a
|
|
128
|
-
* suffix or a substring) and check every id you copy into the player URL.
|
|
129
|
-
*/
|
|
130
|
-
embed: (url: URL) => string | null;
|
|
131
|
-
/** The frame's CSS `aspect-ratio` (default `16 / 9`); ignored with `height`. */
|
|
132
|
-
aspectRatio?: string;
|
|
133
|
-
/** A fixed frame height in pixels (a music player). */
|
|
134
|
-
height?: number;
|
|
135
|
-
};
|
|
136
|
-
/** The frame's `sandbox`: scripts and the provider's own origin, popups that leave it; no top navigation, modals, downloads or forms. */
|
|
137
|
-
export declare const EMBED_SANDBOX = "allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox allow-presentation";
|
|
138
|
-
/** The frame's permissions (`allow`): what a player needs, nothing that reads the viewer. */
|
|
139
|
-
export declare const EMBED_ALLOW = "fullscreen; picture-in-picture; encrypted-media; clipboard-write";
|
|
140
|
-
/**
|
|
141
|
-
* The default allowlist: YouTube (through `youtube-nocookie.com`), Vimeo,
|
|
142
|
-
* Loom, Figma, CodePen and Spotify. A link no provider plays renders no
|
|
143
|
-
* frame. Extend it with `createEmbedPlugin({ providers: [...EMBED_PROVIDERS, mine] })`.
|
|
144
|
-
*/
|
|
145
|
-
export declare const EMBED_PROVIDERS: readonly EmbedProvider[];
|
|
146
|
-
/**
|
|
147
|
-
* The player for `value` (a stored or pasted link): the first provider of
|
|
148
|
-
* `providers` that plays it, and its `https:` player URL. `null` when the
|
|
149
|
-
* link is not a {@link safeWebUrl}, no provider plays it, or the player URL
|
|
150
|
-
* a provider answers is not `https:` or is on the page's own origin. The frame's `src` is always this
|
|
151
|
-
* answer, never the stored value.
|
|
152
|
-
*/
|
|
153
|
-
export declare const embedSourceOf: (value: unknown, providers?: readonly EmbedProvider[]) => {
|
|
154
|
-
src: string;
|
|
155
|
-
provider: EmbedProvider;
|
|
156
|
-
} | null;
|
|
157
|
-
/** A file's display name from its URL's last path segment, decoded. */
|
|
158
|
-
export declare const fileNameOf: (src: string) => string;
|
|
159
|
-
/**
|
|
160
|
-
* The element a media kind's HTML import reads: `element` itself when it
|
|
161
|
-
* is a `tag` (not inside a `figure`, which claims it), or a `figure`'s own
|
|
162
|
-
* `tag` child.
|
|
163
|
-
*/
|
|
164
|
-
export declare const claimed: (element: HTMLElement, tag: string) => HTMLElement | undefined;
|
|
165
|
-
/** An imported `video`'s or `audio`'s source: its `src`, else its first `source`'s. */
|
|
166
|
-
export declare const mediaSourceOf: (element: HTMLElement | undefined) => string | null;
|
|
104
|
+
export * from './sources.js';
|
|
105
|
+
import type { EmbedProvider } from './sources.js';
|
|
167
106
|
export { escapeHtml };
|