edytor 1.0.0 → 3.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 +26 -69
- package/dist/block/block.svelte.d.ts +6 -4
- package/dist/block/block.svelte.js +12 -8
- package/dist/block/inlineBlock.svelte.d.ts +6 -2
- package/dist/block/inlineBlock.svelte.js +7 -2
- 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/room/admission.js +3 -3
- package/dist/cloudflare/room/context.d.ts +7 -1
- package/dist/cloudflare/routeDocumentSocket.d.ts +17 -0
- package/dist/cloudflare/routeDocumentSocket.js +53 -0
- package/dist/collaboration/awarenessSelection.d.ts +22 -1
- package/dist/collaboration/awarenessSelection.js +42 -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/Block.svelte +3 -1
- package/dist/components/Edytor.svelte +38 -20
- package/dist/components/Edytor.svelte.d.ts +9 -4
- package/dist/components/InlineBlock.svelte +1 -1
- package/dist/crdt/admission.d.ts +5 -10
- package/dist/crdt/admission.js +5 -11
- package/dist/crdt/data.d.ts +10 -0
- package/dist/crdt/data.js +20 -2
- package/dist/crdt/doc/funnel.d.ts +7 -6
- package/dist/crdt/doc/funnel.js +10 -9
- package/dist/crdt/doc/gate.d.ts +0 -17
- package/dist/crdt/doc/gate.js +2 -41
- package/dist/crdt/doc/history.js +2 -2
- package/dist/crdt/doc/reads.d.ts +7 -0
- package/dist/crdt/doc/reads.js +11 -1
- package/dist/crdt/document.d.ts +13 -14
- package/dist/crdt/document.js +17 -19
- package/dist/crdt/edytor-doc.d.ts +22 -4
- package/dist/crdt/edytor-doc.js +5 -8
- package/dist/crdt/index.d.ts +9 -3
- package/dist/crdt/index.js +2 -2
- package/dist/crdt/operations.d.ts +1 -1
- package/dist/crdt/operations.js +1 -0
- package/dist/crdt/props.d.ts +32 -0
- package/dist/crdt/props.js +172 -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 +10 -9
- package/dist/crdt/providers/room.js +13 -10
- package/dist/crdt/providers/websocket.d.ts +1 -1
- package/dist/crdt/providers/websocket.js +28 -29
- package/dist/crdt/semantics.js +3 -1
- package/dist/dnd/autoScroll.d.ts +15 -7
- package/dist/dnd/autoScroll.js +10 -15
- package/dist/{plugins/blockHandles → dnd}/dropIndicator.d.ts +2 -2
- package/dist/{plugins/blockHandles → dnd}/dropIndicator.js +2 -5
- package/dist/dnd/external.d.ts +6 -0
- package/dist/dnd/external.js +17 -0
- package/dist/{plugins/blockHandles → dnd}/geometry.d.ts +4 -2
- package/dist/{plugins/blockHandles → dnd}/geometry.js +3 -4
- package/dist/dnd/placement.d.ts +200 -0
- package/dist/dnd/placement.js +426 -0
- 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 +19 -9
- package/dist/edytor.svelte.js +28 -33
- package/dist/events/beforeInputCommands.d.ts +2 -2
- package/dist/events/beforeInputCommands.js +8 -4
- package/dist/events/onBeforeInput.js +1 -1
- package/dist/events/onDrop.js +25 -10
- package/dist/events/onInput.d.ts +0 -12
- package/dist/events/onInput.js +1 -67
- package/dist/events/onPaste.d.ts +2 -1
- package/dist/events/onPaste.js +8 -3
- 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 +4 -4
- package/dist/index.js +2 -2
- package/dist/kinds.js +1 -1
- package/dist/labels.d.ts +2 -0
- package/dist/labels.js +2 -1
- package/dist/plugins/anchored.svelte.d.ts +21 -25
- package/dist/plugins/anchored.svelte.js +23 -39
- package/dist/plugins/arrowMove/arrowMove.d.ts +1 -1
- package/dist/plugins/arrowMove/arrowMove.js +1 -1
- package/dist/plugins/blockHandles/BlockHandleController.svelte.d.ts +2 -122
- package/dist/plugins/blockHandles/BlockHandleController.svelte.js +48 -414
- package/dist/plugins/blockHandles/BlockHandles.svelte +14 -32
- package/dist/plugins/blockHandles/blockHandlesPlugin.js +2 -1
- 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/CodeHeader.svelte +5 -3
- package/dist/plugins/code/CodePlugin.svelte +15 -12
- 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/code/languages.d.ts +0 -3
- package/dist/plugins/code/languages.js +0 -2
- package/dist/plugins/columns/ColumnResize.svelte +3 -2
- package/dist/plugins/columns/ColumnsPlugin.svelte +8 -21
- package/dist/plugins/columns/gaps.d.ts +7 -5
- package/dist/plugins/columns/gaps.js +11 -6
- package/dist/plugins/columns/resize.svelte.d.ts +5 -6
- package/dist/plugins/columns/resize.svelte.js +12 -14
- 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 +13 -30
- package/dist/plugins/equation/EquationPlugin.svelte.d.ts +1 -0
- package/dist/plugins/equation/equation.css +7 -0
- 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 +43 -0
- package/dist/plugins/fileDrop.js +122 -0
- 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 +56 -84
- package/dist/plugins/image/ImagePlugin.svelte.d.ts +13 -1
- package/dist/plugins/image/controls.svelte.js +16 -2
- package/dist/plugins/image/image.css +17 -0
- 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 +4 -5
- package/dist/plugins/index.js +0 -1
- package/dist/plugins/list.svelte.d.ts +9 -0
- package/dist/plugins/list.svelte.js +18 -0
- package/dist/plugins/markdownShortcuts.js +5 -5
- package/dist/plugins/marquee/marqueePlugin.js +0 -4
- package/dist/plugins/media/AudioPlugin.svelte +13 -1
- package/dist/plugins/media/AudioPlugin.svelte.d.ts +11 -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 +12 -20
- package/dist/plugins/media/FilePlugin.svelte.d.ts +9 -0
- package/dist/plugins/media/MediaEmpty.svelte +2 -55
- package/dist/plugins/media/MediaEmpty.svelte.d.ts +18 -14
- package/dist/plugins/media/SourceBlock.svelte +178 -52
- package/dist/plugins/media/SourceBlock.svelte.d.ts +13 -6
- package/dist/plugins/media/UploadPreview.svelte +32 -0
- package/dist/plugins/media/UploadPreview.svelte.d.ts +11 -0
- package/dist/plugins/media/VideoPlugin.svelte +13 -1
- package/dist/plugins/media/VideoPlugin.svelte.d.ts +11 -1
- package/dist/plugins/media/empty.svelte.d.ts +13 -4
- package/dist/plugins/media/empty.svelte.js +32 -26
- package/dist/plugins/media/media.d.ts +9 -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/upload.css +23 -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 +50 -38
- package/dist/plugins/mention/MentionPlugin.svelte.d.ts +11 -2
- package/dist/plugins/mention/mention.css +6 -0
- package/dist/plugins/page/PagePlugin.svelte +2 -9
- package/dist/plugins/page/page.js +1 -1
- package/dist/plugins/pageLink/PageLinkPlugin.svelte +126 -28
- package/dist/plugins/pageLink/PageLinkPlugin.svelte.d.ts +13 -1
- package/dist/plugins/pageLink/pageLink.css +6 -0
- package/dist/plugins/richtext/RichTextPlugin.svelte +99 -204
- package/dist/plugins/richtext/RichTextPlugin.svelte.d.ts +1 -0
- 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/richtext/richtext.css +6 -0
- 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 +33 -56
- 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 +48 -32
- package/dist/plugins/uploads.svelte.js +119 -43
- package/dist/plugins.d.ts +66 -14
- 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/attempt.d.ts +16 -6
- package/dist/session/attempt.js +1 -0
- package/dist/session/bindings.js +35 -32
- package/dist/session/commands.d.ts +7 -11
- package/dist/session/commands.js +15 -19
- package/dist/session/history.js +1 -0
- package/dist/session/inputRules.d.ts +6 -3
- package/dist/session/inputRules.js +10 -6
- package/dist/session/moves.d.ts +33 -0
- package/dist/session/moves.js +71 -1
- package/dist/session/navigation.d.ts +7 -0
- package/dist/session/navigation.js +20 -11
- package/dist/session/props.d.ts +28 -0
- package/dist/session/props.js +65 -0
- package/dist/session/suggestions.svelte.d.ts +0 -11
- package/dist/session/suggestions.svelte.js +15 -3
- package/dist/session/uploads.d.ts +29 -0
- package/dist/session/uploads.js +10 -0
- package/dist/surface/lines.js +1 -3
- package/dist/surface/observer.svelte.d.ts +17 -1
- package/dist/surface/observer.svelte.js +72 -17
- package/dist/surface/overlay.d.ts +0 -14
- package/dist/surface/overlay.js +0 -25
- package/dist/surface/projector.svelte.js +1 -1
- package/dist/text/text.svelte.js +3 -13
- package/dist/themes/notion.css +9 -0
- 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 +18 -1
- 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
- /package/dist/{plugins/columns → dnd}/stacking.d.ts +0 -0
- /package/dist/{plugins/columns → dnd}/stacking.js +0 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { isTextPart } from '../block/contentRange.js';
|
|
2
|
+
import { contentOf } from '../clipboard/serializeClipboardFragment.js';
|
|
3
|
+
/** Characters markdown reads as syntax inside a line: escaped in exported text. */
|
|
4
|
+
const MD_SPECIAL = /[\\`*_[\]~<]/g;
|
|
5
|
+
/** A line start markdown reads as a block (a heading, a list item, a quote, a rule): escaped. */
|
|
6
|
+
const MD_LINE_START = /^(\s*)(#{1,6}(?=\s|$)|[-+](?=\s)|\d+(?=[.)]\s)|>|=+\s*$|-{3,}\s*$)/;
|
|
7
|
+
/** Text as markdown: its syntax characters escaped, a soft break a hard break (`\` + newline). */
|
|
8
|
+
const escapeMarkdown = (text) => text.replace(MD_SPECIAL, (c) => `\\${c}`).replace(/\n/g, '\\\n');
|
|
9
|
+
/** The delimiters a mark's value exports as, or none. */
|
|
10
|
+
const delimitersOf = (mark, value) => typeof mark.markdown === 'function' ? mark.markdown(value) : mark.markdown;
|
|
11
|
+
/** A code span's fence: one backtick more than the longest run inside it. */
|
|
12
|
+
const codeFence = (text) => '`'.repeat(Math.max(0, ...[...text.matchAll(/`+/g)].map((m) => m[0].length)) + 1);
|
|
13
|
+
/**
|
|
14
|
+
* Rich text as inline markdown. Marks open in their registration order
|
|
15
|
+
* reversed (the first registered innermost, as HTML wraps them), a mark
|
|
16
|
+
* spanning several runs opens once (`**a *b***`), a mark without a
|
|
17
|
+
* `markdown` form is left out, and a delimiter never sits on a space
|
|
18
|
+
* (`** x**` is no emphasis): the spaces move outside it.
|
|
19
|
+
*/
|
|
20
|
+
const inlineMarkdown = (content = [], kinds) => {
|
|
21
|
+
// A code span holds no markup: it opens last, innermost.
|
|
22
|
+
const order = [...kinds.marks.keys()]
|
|
23
|
+
.reverse()
|
|
24
|
+
.sort((a, b) => Number(a === 'code') - Number(b === 'code'));
|
|
25
|
+
/** The open marks, outermost first: name, value key and closing delimiter. */
|
|
26
|
+
const open = [];
|
|
27
|
+
let out = '';
|
|
28
|
+
const closeTo = (depth) => {
|
|
29
|
+
// A delimiter closes after the text's last non-space: trailing spaces move out.
|
|
30
|
+
const spaces = /[ \t]*$/.exec(out)[0];
|
|
31
|
+
out = out.slice(0, out.length - spaces.length);
|
|
32
|
+
while (open.length > depth)
|
|
33
|
+
out += open.pop().close;
|
|
34
|
+
out += spaces;
|
|
35
|
+
};
|
|
36
|
+
for (const part of content) {
|
|
37
|
+
if (!isTextPart(part)) {
|
|
38
|
+
closeTo(0);
|
|
39
|
+
const atom = kinds.inlineBlocks.get(part.type);
|
|
40
|
+
out += atom?.markdown?.(part.data) ?? escapeMarkdown(atom?.plain?.(part.data) ?? '');
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
const wanted = order
|
|
44
|
+
.map((name) => {
|
|
45
|
+
const mark = kinds.marks.get(name);
|
|
46
|
+
const value = part.marks?.[name];
|
|
47
|
+
const delimiters = value ? delimitersOf(mark, value) : undefined;
|
|
48
|
+
return delimiters && { name, key: JSON.stringify(value), delimiters };
|
|
49
|
+
})
|
|
50
|
+
.filter((m) => !!m);
|
|
51
|
+
// Keep the open marks this run still has, in order; close from the first it lacks.
|
|
52
|
+
let keep = 0;
|
|
53
|
+
while (keep < open.length &&
|
|
54
|
+
wanted.some((m) => m.name === open[keep].name && m.key === open[keep].key))
|
|
55
|
+
keep++;
|
|
56
|
+
// A mark opening inside an open code span would be literal: the span closes first.
|
|
57
|
+
const opening = wanted.some((m) => !open.slice(0, keep).some((o) => o.name === m.name));
|
|
58
|
+
const span = open.findIndex((m) => m.name === 'code');
|
|
59
|
+
if (opening && span !== -1 && span < keep)
|
|
60
|
+
keep = span;
|
|
61
|
+
closeTo(keep);
|
|
62
|
+
const code = wanted.some((m) => m.name === 'code');
|
|
63
|
+
const raw = part.text;
|
|
64
|
+
const lead = /^[ \t]*/.exec(raw)[0];
|
|
65
|
+
const body = raw.slice(lead.length);
|
|
66
|
+
out += lead;
|
|
67
|
+
if (!body)
|
|
68
|
+
continue;
|
|
69
|
+
for (const mark of wanted)
|
|
70
|
+
if (!open.some((m) => m.name === mark.name)) {
|
|
71
|
+
const [start, end] = mark.delimiters;
|
|
72
|
+
const fence = mark.name === 'code' ? codeFence(body) : '';
|
|
73
|
+
const pad = fence && /^`|`$/.test(body) ? ' ' : '';
|
|
74
|
+
out += fence ? fence + pad : start;
|
|
75
|
+
open.push({ name: mark.name, key: mark.key, close: fence ? pad + fence : end });
|
|
76
|
+
}
|
|
77
|
+
out += code ? body : escapeMarkdown(body);
|
|
78
|
+
}
|
|
79
|
+
closeTo(0);
|
|
80
|
+
return out;
|
|
81
|
+
};
|
|
82
|
+
/** Every line of `text` prefixed with `prefix` (an empty line with its trimmed form). */
|
|
83
|
+
const indent = (text, prefix) => text
|
|
84
|
+
.split('\n')
|
|
85
|
+
.map((line) => (line ? prefix + line : prefix.trimEnd()))
|
|
86
|
+
.join('\n');
|
|
87
|
+
/** A list item's markdown (`- `, `1. `, `- [ ] `): its block's first line starts one. */
|
|
88
|
+
const LIST_LINE = /^(?:[-*+]|\d+[.)])\s/;
|
|
89
|
+
/**
|
|
90
|
+
* Sibling blocks as markdown: a blank line between blocks, a single
|
|
91
|
+
* newline between items of one list (a tight list).
|
|
92
|
+
*/
|
|
93
|
+
const siblingsMarkdown = (blocks, kinds) => {
|
|
94
|
+
let out = '';
|
|
95
|
+
let previous = null;
|
|
96
|
+
let run = 0;
|
|
97
|
+
let type = null;
|
|
98
|
+
for (const block of blocks) {
|
|
99
|
+
run = block.type === type ? run + 1 : 1;
|
|
100
|
+
type = block.type;
|
|
101
|
+
const md = blockMarkdown(block, kinds, run);
|
|
102
|
+
if (!md)
|
|
103
|
+
continue;
|
|
104
|
+
if (previous !== null)
|
|
105
|
+
out += LIST_LINE.test(previous) && LIST_LINE.test(md) ? '\n' : '\n\n';
|
|
106
|
+
out += md;
|
|
107
|
+
previous = md;
|
|
108
|
+
}
|
|
109
|
+
return out;
|
|
110
|
+
};
|
|
111
|
+
/** A block and its subtree as markdown, by its kind's form. */
|
|
112
|
+
const blockMarkdown = (block, kinds, index) => {
|
|
113
|
+
const kind = kinds.blocks.get(block.type);
|
|
114
|
+
const content = inlineMarkdown(block.content, kinds);
|
|
115
|
+
const children = siblingsMarkdown(block.children ?? [], kinds);
|
|
116
|
+
if (kind?.markdown) {
|
|
117
|
+
const context = {
|
|
118
|
+
index,
|
|
119
|
+
indent,
|
|
120
|
+
inline: (parts) => inlineMarkdown(parts, kinds)
|
|
121
|
+
};
|
|
122
|
+
return kind.markdown(block, content, children, context);
|
|
123
|
+
}
|
|
124
|
+
if (kind?.plain) {
|
|
125
|
+
const plain = kind.plain(block, contentOf(block.content, kinds, false), '');
|
|
126
|
+
return [plain && escapeMarkdown(plain), children].filter(Boolean).join('\n\n');
|
|
127
|
+
}
|
|
128
|
+
// A paragraph: its text, a leading block marker escaped (`\# not a heading`).
|
|
129
|
+
const text = content.replace(MD_LINE_START, (_, space, marker) => /^\d/.test(marker) ? `${space}${marker}\\` : `${space}\\${marker}`);
|
|
130
|
+
return [text, children].filter(Boolean).join('\n\n');
|
|
131
|
+
};
|
|
132
|
+
/** Blocks as markdown (`toMarkdown`), by each kind's, mark's and atom's `markdown` form. */
|
|
133
|
+
export const blocksToMarkdown = (blocks, kinds) => siblingsMarkdown(blocks, kinds);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MDX-lite tags as markdown (`toMarkdown`): a block written as
|
|
3
|
+
* `<Name a="x" n={1} on={true} />`, the tag `fromMarkdown` reads back.
|
|
4
|
+
*/
|
|
5
|
+
import type { SerializableContent } from '../utils/json.js';
|
|
6
|
+
/**
|
|
7
|
+
* A component tag, for a kind's `markdown` form: `mdxComponent('Endpoint',
|
|
8
|
+
* block.data, content, children)`. Each data value that has a literal is an
|
|
9
|
+
* attribute (a string `"x"`, a number `{1}`, a boolean `{true}`); others
|
|
10
|
+
* (objects, arrays, `null`, a string holding a newline or both quotes) are
|
|
11
|
+
* left out. No text and no children: a self-closing tag. Text only: the
|
|
12
|
+
* text inside the tag on one line. Children: the tag on its own lines, the
|
|
13
|
+
* text first (a paragraph), then the children.
|
|
14
|
+
*/
|
|
15
|
+
export declare const mdxComponent: (name: string, data?: Record<string, SerializableContent> | undefined, content?: string, children?: string) => string;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const ATTRIBUTE = /^[A-Za-z_][\w:-]*$/;
|
|
2
|
+
/** A data value as an attribute, or `null` when MDX-lite has no literal for it. */
|
|
3
|
+
const attribute = (name, value) => {
|
|
4
|
+
if (!ATTRIBUTE.test(name))
|
|
5
|
+
return null;
|
|
6
|
+
if (typeof value === 'boolean' || (typeof value === 'number' && Number.isFinite(value)))
|
|
7
|
+
return `${name}={${value}}`;
|
|
8
|
+
if (typeof value !== 'string' || /\n/.test(value))
|
|
9
|
+
return null;
|
|
10
|
+
if (!value.includes('"'))
|
|
11
|
+
return `${name}="${value}"`;
|
|
12
|
+
return value.includes("'") ? null : `${name}='${value}'`;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* A component tag, for a kind's `markdown` form: `mdxComponent('Endpoint',
|
|
16
|
+
* block.data, content, children)`. Each data value that has a literal is an
|
|
17
|
+
* attribute (a string `"x"`, a number `{1}`, a boolean `{true}`); others
|
|
18
|
+
* (objects, arrays, `null`, a string holding a newline or both quotes) are
|
|
19
|
+
* left out. No text and no children: a self-closing tag. Text only: the
|
|
20
|
+
* text inside the tag on one line. Children: the tag on its own lines, the
|
|
21
|
+
* text first (a paragraph), then the children.
|
|
22
|
+
*/
|
|
23
|
+
export const mdxComponent = (name, data = {}, content = '', children = '') => {
|
|
24
|
+
const attributes = Object.entries(data)
|
|
25
|
+
.map(([key, value]) => attribute(key, value))
|
|
26
|
+
.filter((part) => part !== null);
|
|
27
|
+
const open = `<${[name, ...attributes].join(' ')}`;
|
|
28
|
+
if (!content && !children)
|
|
29
|
+
return `${open} />`;
|
|
30
|
+
if (!children)
|
|
31
|
+
return `${open}>${content}</${name}>`;
|
|
32
|
+
return `${open}>\n${[content, children].filter(Boolean).join('\n\n')}\n</${name}>`;
|
|
33
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -35,17 +35,17 @@ export { InlineBlock } from './block/inlineBlock.svelte.js';
|
|
|
35
35
|
export { Text } from './text/text.svelte.js';
|
|
36
36
|
export type { BlockMoveDirection, BlockMovePosition, BlockMoveRequest } from './session/moves.js';
|
|
37
37
|
export type { HotKey, HotKeyCombination } from './session/keymap.js';
|
|
38
|
-
export type { Plugin, KindPreset, KindMenuAction, EditorCommand, BlockDefinition, MarkDefinition, InlineBlockDefinition, BlockSnippetPayload, MarkSnippetPayload, InlineBlockSnippetPayload, Placeholder, PlaceholderView, ChangePayload, Commands, AfterOperationPayload, Prevent, InputRule, InputRuleContext, Trigger, TriggerContext, TextRuleContext } from './plugins.js';
|
|
38
|
+
export type { Plugin, KindPreset, KindMenuAction, EditorCommand, BlockDefinition, MarkdownContext, MarkDefinition, InlineBlockDefinition, BlockSnippetPayload, MarkSnippetPayload, InlineBlockSnippetPayload, Placeholder, PlaceholderView, ChangePayload, Commands, AfterOperationPayload, Prevent, InputRule, InputRuleContext, Trigger, TriggerContext, TextRuleContext } from './plugins.js';
|
|
39
39
|
export type { Caret } from './selection/selection.svelte.js';
|
|
40
40
|
export { PreventionError, isPrevention } from './utils.js';
|
|
41
41
|
export type { CommandResult } from './session/commands.js';
|
|
42
42
|
export { convertToKind, turnCommands, wrapBlocks, wrappable, type KindRow } from './kinds.js';
|
|
43
43
|
export { textToBlocks, type TextToBlocksOptions } from './clipboard/textBlocks.js';
|
|
44
44
|
export type { Suggestion, Suggestions, SuggestionAt, SuggestionContent, SuggestionOptions, SuggestionRange, SuggestionStatus, SuggestionsAt, ResolvedAt } from './session/suggestions.svelte.js';
|
|
45
|
-
export { createRichTextPlugin, richTextOperations, richTextPlaceholder, CALLOUT_ICONS, createCalloutIconsPlugin,
|
|
45
|
+
export { createRichTextPlugin, richTextOperations, richTextPlaceholder, CALLOUT_ICONS, createCalloutIconsPlugin, type CalloutIconPicker, type CalloutIconsOptions, type RichTextPluginOptions, type TodoCheckboxPayload, type CalloutIconPayload, type EmptyBodyPayload, createArrowMovePlugin, createCodePlugin, CODE_LANGUAGES, loadCodeLanguage, type CodeLanguage, type CodePluginOptions, type CodeHeader, type LanguageMenu, type LanguageMenuItem, type LanguageRow, createMarkdownShortcutsPlugin, createMentionPlugin, type MentionItem, type MentionData, type MentionPluginOptions, createPageLinkPlugin, type PageLinkItem, type PageLinkData, type PageLinkPluginOptions, type TriggerMenuController, withRulesAndTriggers, BLOCK_ACTIVATE_EVENT, BLOCK_ADD_EVENT, type BlockActivation, type BlockAddition, createBlockHandlesPlugin, type BlockHandlesOptions, type BlockHandleSnippetPayload, type BlockHandleController, createSlashMenuPlugin, type SlashMenuOptions, type SlashMenuController, createToolbarPlugin, type ToolbarOptions, type ToolbarController, createBlockMenuPlugin, type BlockMenuOptions, type BlockMenuController, type BlockMenuAction, type BlockMenuColor, createSuggestionsPlugin, createSuggestionBarPlugin, type SuggestionBarOptions, type SuggestionBarPayload, createImagePlugin, type ImagePluginOptions, safeImageSrc, storableImageSrc, MAX_INLINE_IMAGE_BYTES, createColumnsPlugin, type ColumnsPluginOptions, createEmbedPlugin, EMBED_PROVIDERS, EMBED_SANDBOX, EMBED_ALLOW, embedSourceOf, type EmbedProvider, type EmbedPluginOptions, type EmbedFallbackPayload, createBookmarkPlugin, type BookmarkPluginOptions, type BookmarkPreview, type BookmarkCardPayload, createFilePlugin, type FilePluginOptions, type FileRowPayload, createVideoPlugin, type VideoPluginOptions, createAudioPlugin, type AudioPluginOptions, safeWebUrl, safeMediaSrc, type MediaKind, createMediaEmptyPlugin, type MediaEmptyOptions, createImageToolbarPlugin, type ImageToolbar, type ImageToolbarOptions, type MediaEmptyController, type MediaEmptyFailure, type UrlPasteController, type UrlPasteOffer, type UrlPasteOption, type ImageControls, type ImageBox, type ChromeAnchor, type MenuItemPayload, createFindPlugin, findController, findMatches, type FindPluginOptions, type FindController, type ReplaceMatches, type FindMatch, type FindOptions, createMarqueePlugin, type MarqueePluginOptions, type MarqueeBoxPayload, createCommentsPlugin, commentsController, type CommentsPluginOptions, type CommentCardPayload, type CommentsController, type CommentDraft, type CommentNotice, type CommentUser, type PlacedThread, createPagePlugin, type PagePluginOptions, type PageBlockLinkPayload, createTocPlugin, type TocPluginOptions, type TocHeadingLevel, type TocEntryPayload, type TocEmptyPayload, createTablePlugin, type TablePluginOptions, insertTableRow, deleteTableRows, insertTableColumn, deleteTableColumn, moveTableColumn, moveTableRows, fillTableCell, type TableChrome, type TableMenu, type TableMenuRow, type TableMenuItem, type TableGripPayload, type TableAddPayload, tableBlock, type TableBlockOptions, createEquationPlugin, KATEX_CDN, KATEX_VERSION, type EquationPluginOptions, type EquationData, type EquationEditor, type EquationErrorPayload, type EquationPlaceholderPayload, type EquationTarget, type KatexLike, type KatexLoader } from './plugins/index.js';
|
|
46
46
|
export { BLOCK_COLORS, setBlockColor, type BlockColorField } from './block/colors.js';
|
|
47
47
|
export { englishLabels, type Labels, type PartialLabels } from './labels.js';
|
|
48
|
-
export { EdytorDocument, createDocument, loadDocument, attachDocument, defaultSemantics, semanticsOf, mergeSemantics, SemanticConflictError, DocumentNotReadyError, DocumentDestroyedError, SchemaMismatchError, UndecodableUpdateError,
|
|
48
|
+
export { EdytorDocument, createDocument, loadDocument, attachDocument, defaultSemantics, semanticsOf, mergeSemantics, SemanticConflictError, DocumentNotReadyError, DocumentDestroyedError, SchemaMismatchError, UndecodableUpdateError, SyncRefusedError, type CreateDocumentOptions, type LoadDocumentOptions, type DocumentActor, type DocumentReadiness, type KindSemantics, type JSONDoc, type JSONBlock, type JSONText, type JSONInlineBlock, type OpResult, type Plan, type Prepared, type DocChange } from './crdt/index.js';
|
|
49
49
|
export { createIndexeddbSync, createWebsocketSync, clearDocument, prefetch, lastUpdated, documentSnapshot, DEFAULT_PRESENCE_THROTTLE, type EdytorSync, type EdytorSyncPayload, type IndexeddbSyncOptions, type WebsocketSync, type WebsocketSyncOptions, type PresenceOptions, type PresenceShare } from './collaboration/index.js';
|
|
50
50
|
export { createCommentsClient, createMemoryCommentsClient, CommentRequestError, commentAnchors, type CommentDocument, type CommentFeed, type CommentResult, type CommentsClient, type CommentsClientOptions, type MemoryCommentsClient, type MemoryCommentsClientOptions, type CommentChange, type CommentRequest, type CommentRun, type CommentSnapshot, type CommentThread, type ThreadComment } from './collaboration/comments/index.js';
|
|
51
51
|
export { VersionHistory, createHistoryClient, HistoryRequestError, versionDiff, type HistoryClient, type HistoryClientOptions, type HistoryRestoreResult, type HistoryUndoResult, type HistoryVersion, type VersionHistoryStatus, type VersionHistoryOptions, type VersionChange, type VersionDiff } from './collaboration/history/index.js';
|
|
@@ -60,7 +60,7 @@ export type { Key, Modifier, Modifiers } from './session/keymap.js';
|
|
|
60
60
|
export type { TriggerRange } from './plugins/triggers/TriggerController.svelte.js';
|
|
61
61
|
export type { RichTextLink, RichTextMark } from './plugins/richtext/richTextOperations.js';
|
|
62
62
|
export type { KindUpload, UploadReport, Uploader } from './plugins/uploads.svelte.js';
|
|
63
|
-
export type { AwarenessLike, PresenceWriter } from './collaboration/awarenessSelection.js';
|
|
63
|
+
export type { AwarenessLike, PresencePeer, PresenceSource, PresenceWriter } from './collaboration/awarenessSelection.js';
|
|
64
64
|
export type { DataPatch } from './crdt/data.js';
|
|
65
65
|
export type { AnchorAffinity, BlockRole, DocAnchor, TextRange } from './crdt/doc/types.js';
|
|
66
66
|
export type { Flow, FlowLine, FlowTarget } from './crdt/flow.js';
|
package/dist/index.js
CHANGED
|
@@ -35,7 +35,7 @@ export { PreventionError, isPrevention } from './utils.js';
|
|
|
35
35
|
export { convertToKind, turnCommands, wrapBlocks, wrappable } from './kinds.js';
|
|
36
36
|
export { textToBlocks } from './clipboard/textBlocks.js';
|
|
37
37
|
// ── The bundled plugins ────────────────────────────────────────────────
|
|
38
|
-
export { createRichTextPlugin, richTextOperations, richTextPlaceholder, CALLOUT_ICONS, createCalloutIconsPlugin,
|
|
38
|
+
export { createRichTextPlugin, richTextOperations, richTextPlaceholder, CALLOUT_ICONS, createCalloutIconsPlugin, createArrowMovePlugin, createCodePlugin, CODE_LANGUAGES, loadCodeLanguage, createMarkdownShortcutsPlugin, createMentionPlugin, createPageLinkPlugin, withRulesAndTriggers, BLOCK_ACTIVATE_EVENT, BLOCK_ADD_EVENT, createBlockHandlesPlugin, createSlashMenuPlugin, createToolbarPlugin, createBlockMenuPlugin, createSuggestionsPlugin, createSuggestionBarPlugin, createImagePlugin, safeImageSrc, storableImageSrc, MAX_INLINE_IMAGE_BYTES, createColumnsPlugin, createEmbedPlugin, EMBED_PROVIDERS, EMBED_SANDBOX, EMBED_ALLOW, embedSourceOf, createBookmarkPlugin, createFilePlugin, createVideoPlugin, createAudioPlugin, safeWebUrl, safeMediaSrc, createMediaEmptyPlugin, createImageToolbarPlugin, createFindPlugin, findController, findMatches, createMarqueePlugin, createCommentsPlugin, commentsController, createPagePlugin, createTocPlugin, createTablePlugin, insertTableRow, deleteTableRows, insertTableColumn, deleteTableColumn, moveTableColumn, moveTableRows, fillTableCell, tableBlock, createEquationPlugin, KATEX_CDN, KATEX_VERSION } from './plugins/index.js';
|
|
39
39
|
export { BLOCK_COLORS, setBlockColor } from './block/colors.js';
|
|
40
40
|
// ── Localization ───────────────────────────────────────────────────────
|
|
41
41
|
export { englishLabels } from './labels.js';
|
|
@@ -44,7 +44,7 @@ export { englishLabels } from './labels.js';
|
|
|
44
44
|
// The application names of `edytor/crdt/edytor`: a Svelte app builds,
|
|
45
45
|
// loads and catches its documents from here. The facade's full vocabulary
|
|
46
46
|
// stays on that entry.
|
|
47
|
-
export { EdytorDocument, createDocument, loadDocument, attachDocument, defaultSemantics, semanticsOf, mergeSemantics, SemanticConflictError, DocumentNotReadyError, DocumentDestroyedError, SchemaMismatchError, UndecodableUpdateError,
|
|
47
|
+
export { EdytorDocument, createDocument, loadDocument, attachDocument, defaultSemantics, semanticsOf, mergeSemantics, SemanticConflictError, DocumentNotReadyError, DocumentDestroyedError, SchemaMismatchError, UndecodableUpdateError, SyncRefusedError } from './crdt/index.js';
|
|
48
48
|
// ── Sync and presence ──────────────────────────────────────────────────
|
|
49
49
|
export { createIndexeddbSync, createWebsocketSync, clearDocument, prefetch, lastUpdated, documentSnapshot, DEFAULT_PRESENCE_THROTTLE } from './collaboration/index.js';
|
|
50
50
|
// ── Comment threads ────────────────────────────────────────────────────
|
package/dist/kinds.js
CHANGED
|
@@ -209,7 +209,7 @@ export const convertToKind = (edytor, block, row, caret = row.replaces) => {
|
|
|
209
209
|
let line = kind.children?.length ? at?.children[0] : at;
|
|
210
210
|
while (line && !line.rendersContent && !line.definition.void && line.children[0])
|
|
211
211
|
line = line.children[0];
|
|
212
|
-
edytor.dispatcher.
|
|
212
|
+
edytor.dispatcher.caretIn(line?.firstText, 0);
|
|
213
213
|
}
|
|
214
214
|
return true;
|
|
215
215
|
};
|
package/dist/labels.d.ts
CHANGED
|
@@ -116,6 +116,8 @@ export type MediaLabels = {
|
|
|
116
116
|
audio: string;
|
|
117
117
|
/** A file's size, in bytes. */
|
|
118
118
|
fileSize: (bytes: number) => string;
|
|
119
|
+
/** A file that is uploading (its block's status, beside the progress). */
|
|
120
|
+
uploading: string;
|
|
119
121
|
};
|
|
120
122
|
export type CodeLabels = {
|
|
121
123
|
/** The preset (a language's name is its `CodePluginOptions.languages` row's). */
|
package/dist/labels.js
CHANGED
|
@@ -118,7 +118,8 @@ export const mediaEnglish = /* @__PURE__ */ frozen({
|
|
|
118
118
|
file: 'File',
|
|
119
119
|
video: 'Video',
|
|
120
120
|
audio: 'Audio',
|
|
121
|
-
fileSize: bytes
|
|
121
|
+
fileSize: bytes,
|
|
122
|
+
uploading: 'Uploading…'
|
|
122
123
|
});
|
|
123
124
|
/** The `code` section in English. */
|
|
124
125
|
export const codeEnglish = /* @__PURE__ */ frozen({ code: 'Code' });
|
|
@@ -1,47 +1,43 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* A panel the
|
|
3
|
-
*
|
|
4
|
-
* equation): the
|
|
5
|
-
* one rule that closes the panel without
|
|
6
|
-
* a press or a focus outside the panel
|
|
7
|
-
* readonly.
|
|
2
|
+
* A panel the app draws by an element of the page (the code language list
|
|
3
|
+
* by its button, the callout icon picker by its icon, the equation editor
|
|
4
|
+
* by its equation): that element as the panel's `anchor`, which the app's
|
|
5
|
+
* markup places itself by, and the one rule that closes the panel without
|
|
6
|
+
* moving the keys: its anchor gone, a press or a focus outside the panel
|
|
7
|
+
* and its anchor, the view turning readonly.
|
|
8
8
|
*/
|
|
9
|
-
import type {
|
|
9
|
+
import type { Snippet } from 'svelte';
|
|
10
10
|
import type { Edytor } from '../edytor.svelte.js';
|
|
11
|
-
import { type LayerBox } from '../surface/overlay.js';
|
|
12
11
|
export declare class Anchored {
|
|
13
12
|
#private;
|
|
14
13
|
private edytor;
|
|
15
14
|
/** The overlay host's name: its element is `[data-<name>]`. */
|
|
16
15
|
private name;
|
|
17
|
-
/** The element the panel stands
|
|
18
|
-
private
|
|
16
|
+
/** The element the panel stands by: `null` when it left the page, `undefined` while closed. */
|
|
17
|
+
private element;
|
|
19
18
|
/** Close the panel, the keys where they are. */
|
|
20
19
|
private dismiss;
|
|
21
|
-
/** The anchor's box in the overlay's frame while the panel is open, else `null` (reactive). */
|
|
22
|
-
box: LayerBox | null;
|
|
23
20
|
constructor(edytor: Edytor,
|
|
24
21
|
/** The overlay host's name: its element is `[data-<name>]`. */
|
|
25
22
|
name: string,
|
|
26
|
-
/** The element the panel stands
|
|
27
|
-
|
|
23
|
+
/** The element the panel stands by: `null` when it left the page, `undefined` while closed. */
|
|
24
|
+
element: () => Element | null | undefined,
|
|
28
25
|
/** Close the panel, the keys where they are. */
|
|
29
26
|
dismiss: () => void);
|
|
30
|
-
/** Where the panel stands:
|
|
31
|
-
|
|
32
|
-
left: number;
|
|
33
|
-
top: number;
|
|
34
|
-
} | null;
|
|
27
|
+
/** Where the panel stands: its element's box, read on every call (`ChromeAnchor`). */
|
|
28
|
+
readonly anchor: import("./chrome.js").ChromeAnchor;
|
|
35
29
|
/**
|
|
36
30
|
* Focus left a field of the panel (its `focusout`): for somewhere outside
|
|
37
|
-
* the panel and its
|
|
38
|
-
* to the background), it stays.
|
|
31
|
+
* the panel and its element, it closes; with no new focus (the window
|
|
32
|
+
* went to the background), it stays.
|
|
39
33
|
*/
|
|
40
34
|
blurred: (event: FocusEvent) => void;
|
|
41
35
|
/**
|
|
42
|
-
* Mount the
|
|
43
|
-
*
|
|
44
|
-
*
|
|
36
|
+
* Mount the app's `snippet` with `payload` in the overlay at `zIndex`
|
|
37
|
+
* (above the block handles, 5, by default) while `shown` holds, with a
|
|
38
|
+
* press listener (capture) on `node`'s document, the anchor-gone rule
|
|
39
|
+
* (on the overlay's frames) and the readonly rule. Answers the teardown,
|
|
40
|
+
* which closes it.
|
|
45
41
|
*/
|
|
46
|
-
mount: <
|
|
42
|
+
mount: <T>(node: HTMLElement, snippet: Snippet<[T]>, payload: T, shown: () => unknown, zIndex?: number) => () => void;
|
|
47
43
|
}
|
|
@@ -1,71 +1,55 @@
|
|
|
1
1
|
import { onPress } from '../events/onFocus.js';
|
|
2
|
-
import {
|
|
2
|
+
import { mountChrome, virtualAnchor } from './chrome.js';
|
|
3
3
|
export class Anchored {
|
|
4
4
|
edytor;
|
|
5
5
|
name;
|
|
6
|
-
|
|
6
|
+
element;
|
|
7
7
|
dismiss;
|
|
8
|
-
/** The anchor's box in the overlay's frame while the panel is open, else `null` (reactive). */
|
|
9
|
-
box = $state.raw(null);
|
|
10
8
|
constructor(edytor,
|
|
11
9
|
/** The overlay host's name: its element is `[data-<name>]`. */
|
|
12
10
|
name,
|
|
13
|
-
/** The element the panel stands
|
|
14
|
-
|
|
11
|
+
/** The element the panel stands by: `null` when it left the page, `undefined` while closed. */
|
|
12
|
+
element,
|
|
15
13
|
/** Close the panel, the keys where they are. */
|
|
16
14
|
dismiss) {
|
|
17
15
|
this.edytor = edytor;
|
|
18
16
|
this.name = name;
|
|
19
|
-
this.
|
|
17
|
+
this.element = element;
|
|
20
18
|
this.dismiss = dismiss;
|
|
21
19
|
}
|
|
22
|
-
/** Where the panel stands:
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
return box && { left: box.x + (center ? box.width / 2 : 0), top: box.y + box.height + gap };
|
|
26
|
-
};
|
|
27
|
-
/** `at` is outside the panel's host and its anchor: the panel closes. */
|
|
20
|
+
/** Where the panel stands: its element's box, read on every call (`ChromeAnchor`). */
|
|
21
|
+
anchor = virtualAnchor(() => this.element()?.getBoundingClientRect(), () => this.element());
|
|
22
|
+
/** `at` is outside the panel's host and its element: the panel closes. */
|
|
28
23
|
#outside = (at, host) => {
|
|
29
24
|
if (!(at instanceof Node))
|
|
30
25
|
return;
|
|
31
|
-
if (!host?.contains(at) && !this.
|
|
26
|
+
if (!host?.contains(at) && !this.element()?.contains(at))
|
|
32
27
|
this.dismiss();
|
|
33
28
|
};
|
|
34
29
|
/**
|
|
35
30
|
* Focus left a field of the panel (its `focusout`): for somewhere outside
|
|
36
|
-
* the panel and its
|
|
37
|
-
* to the background), it stays.
|
|
31
|
+
* the panel and its element, it closes; with no new focus (the window
|
|
32
|
+
* went to the background), it stays.
|
|
38
33
|
*/
|
|
39
34
|
blurred = (event) => this.#outside(event.relatedTarget, event.currentTarget?.closest(`[data-${this.name}]`));
|
|
40
35
|
/**
|
|
41
|
-
* Mount the
|
|
42
|
-
*
|
|
43
|
-
*
|
|
36
|
+
* Mount the app's `snippet` with `payload` in the overlay at `zIndex`
|
|
37
|
+
* (above the block handles, 5, by default) while `shown` holds, with a
|
|
38
|
+
* press listener (capture) on `node`'s document, the anchor-gone rule
|
|
39
|
+
* (on the overlay's frames) and the readonly rule. Answers the teardown,
|
|
40
|
+
* which closes it.
|
|
44
41
|
*/
|
|
45
|
-
mount = (node,
|
|
42
|
+
mount = (node, snippet, payload, shown, zIndex = 7) => {
|
|
46
43
|
const { edytor } = this;
|
|
47
|
-
const offPress = onPress(edytor, node.ownerDocument, (event) => this.
|
|
44
|
+
const offPress = onPress(edytor, node.ownerDocument, (event) => this.element() !== undefined &&
|
|
48
45
|
this.#outside(event.target, event.target?.closest?.(`[data-${this.name}]`)), true);
|
|
49
|
-
const unmount = edytor
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (anchor === null)
|
|
55
|
-
return this.dismiss();
|
|
56
|
-
if (!sameValues(box, this.box))
|
|
57
|
-
this.box = box;
|
|
58
|
-
};
|
|
59
|
-
});
|
|
60
|
-
const offLock = $effect.root(() => {
|
|
61
|
-
$effect(() => {
|
|
62
|
-
if (edytor.readonly)
|
|
63
|
-
this.dismiss();
|
|
64
|
-
});
|
|
65
|
-
});
|
|
46
|
+
const unmount = mountChrome(edytor, snippet, payload, shown, {
|
|
47
|
+
name: this.name,
|
|
48
|
+
zIndex,
|
|
49
|
+
measure: () => (this.element() === null ? this.dismiss : undefined)
|
|
50
|
+
}, this.dismiss);
|
|
66
51
|
return () => {
|
|
67
52
|
offPress();
|
|
68
|
-
offLock();
|
|
69
53
|
unmount();
|
|
70
54
|
this.dismiss();
|
|
71
55
|
};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { Plugin } from '../../plugins.js';
|
|
2
|
-
/** Block moves from the keyboard (Mod+Up/Down, Mod+Shift+Up/Down): a default
|
|
2
|
+
/** Block moves from the keyboard (Mod+Up/Down, Mod+Shift+Up/Down): apps list it (`createArrowMovePlugin()`), it is not a default. */
|
|
3
3
|
export declare const createArrowMovePlugin: () => Plugin;
|
|
@@ -24,7 +24,7 @@ const move = (direction, caret = false) => ({ edytor, prevent }) => {
|
|
|
24
24
|
selectMoved(edytor, moved, selected);
|
|
25
25
|
});
|
|
26
26
|
};
|
|
27
|
-
/** Block moves from the keyboard (Mod+Up/Down, Mod+Shift+Up/Down): a default
|
|
27
|
+
/** Block moves from the keyboard (Mod+Up/Down, Mod+Shift+Up/Down): apps list it (`createArrowMovePlugin()`), it is not a default. */
|
|
28
28
|
export const createArrowMovePlugin = () => branded('arrowMove', () => ({
|
|
29
29
|
hotkeys: {
|
|
30
30
|
'mod+arrowdown': move('down'),
|
|
@@ -53,6 +53,8 @@ export declare class BlockHandleController {
|
|
|
53
53
|
private group;
|
|
54
54
|
/** The drop bar and the nest backdrop in the overlay, while our drag runs. */
|
|
55
55
|
private readonly indicator;
|
|
56
|
+
/** Where a drop lands (the one resolution a file drag reads too). */
|
|
57
|
+
private readonly drop;
|
|
56
58
|
/** The selection the drag in progress replaced when it started: its undo step restores it. */
|
|
57
59
|
private held;
|
|
58
60
|
/** The handle the drag in progress started from: its width is the handle column's. */
|
|
@@ -100,57 +102,6 @@ export declare class BlockHandleController {
|
|
|
100
102
|
registerHandle(element: HTMLElement, block: Block): () => void;
|
|
101
103
|
/** A candidate drop target; registered at once when our drag is in progress. */
|
|
102
104
|
addDropTarget(node: HTMLElement, target: Block): () => void;
|
|
103
|
-
/**
|
|
104
|
-
* The editor's content column (`start`…`end`, the root's content box:
|
|
105
|
-
* where its blocks' boxes start and end), the width of the handle column
|
|
106
|
-
* left of it (the drag's handle, measured: `+`, grip and the gap to the
|
|
107
|
-
* block) and how far the drag reaches past them (`dropReach`, the
|
|
108
|
-
* `--edytor-drop-reach` the root inherits).
|
|
109
|
-
*/
|
|
110
|
-
private gutter;
|
|
111
|
-
/**
|
|
112
|
-
* A placement in the editor's margins at the pointer (`dnd.reach`), within
|
|
113
|
-
* the editor's height, for the row the content's near edge shows at the
|
|
114
|
-
* pointer's height (`rowAt`: a nested block's own row; over a layout, the
|
|
115
|
-
* row of its first column on the left, of its last on the right, never
|
|
116
|
-
* another), by the zone the pointer is in (`marginAt`):
|
|
117
|
-
* - the handle column left of the blocks (`gutter`): that row's reorder
|
|
118
|
-
* (`reorder`): a drag straight down the handles reorders, row after
|
|
119
|
-
* row, gaps included (never a beside band);
|
|
120
|
-
* - the first `BESIDE_MARGIN` px past it on the left, and past the
|
|
121
|
-
* content's right edge: the beside band of that side (`beside`, as if
|
|
122
|
-
* the pointer were at that edge) when the document has a layout kind
|
|
123
|
-
* and the row offers one (a refused band shows nothing);
|
|
124
|
-
* - elsewhere within the reach (and there without a band): the reorder,
|
|
125
|
-
* on the left the handle column's, on the right the one the row's
|
|
126
|
-
* right edge offers (its halves as just inside the content, so nothing
|
|
127
|
-
* jumps as the pointer leaves it).
|
|
128
|
-
* `undefined` past the reach, above or below the editor, and inside the
|
|
129
|
-
* content (the blocks' own targets answer there).
|
|
130
|
-
*/
|
|
131
|
-
private margin;
|
|
132
|
-
/**
|
|
133
|
-
* The halves of `row` (`zones`) at the pointer, the one it is in first:
|
|
134
|
-
* the top half of `rect` (its own row by default) before, the bottom one
|
|
135
|
-
* after; with `plain`, only before or after a block — never inside one.
|
|
136
|
-
*/
|
|
137
|
-
private halves;
|
|
138
|
-
/**
|
|
139
|
-
* The first placement of `halves` the document takes (a refused one gives
|
|
140
|
-
* way to the next, then to the other half's), `blocked` when the first
|
|
141
|
-
* half took none; `null` when none fits.
|
|
142
|
-
*/
|
|
143
|
-
private pick;
|
|
144
|
-
/**
|
|
145
|
-
* The handle column's reorder over `row` at the pointer: its plain halves
|
|
146
|
-
* (`halves`, the pointer's x picking the level); `null` when neither half
|
|
147
|
-
* fits. Over an item of a container the dragged blocks do not fit in (a
|
|
148
|
-
* paragraph over a list's item: the document refuses every placement at
|
|
149
|
-
* the item's level), the container is the row: its whole box, the upper
|
|
150
|
-
* half before it, the lower half after it (round 4), so a drag down the
|
|
151
|
-
* handles meets the list as one row it can pass.
|
|
152
|
-
*/
|
|
153
|
-
private reorder;
|
|
154
105
|
/** The blocks a drop of `source` moves: the drag's own group, fixed when it started. */
|
|
155
106
|
private moving;
|
|
156
107
|
/** The blocks the selection covers when `source` is one of them, else `source` alone. */
|
|
@@ -168,75 +119,6 @@ export declare class BlockHandleController {
|
|
|
168
119
|
* else `source`.
|
|
169
120
|
*/
|
|
170
121
|
private select;
|
|
171
|
-
/** Whether the drag of `source` may land at a placement. */
|
|
172
|
-
private fits;
|
|
173
|
-
/**
|
|
174
|
-
* The block whose row the pointer is on over `node`: the last shown drop
|
|
175
|
-
* target in it whose row starts at or above the pointer (beside a nested
|
|
176
|
-
* block, over its ancestors' indent, the pointer is on that block's
|
|
177
|
-
* row), else `target`, over its own row (`emptied`). A layout's columns
|
|
178
|
-
* sit side by side: only the one under the pointer is measured (between
|
|
179
|
-
* two of them, the layout is the row: its gap).
|
|
180
|
-
*/
|
|
181
|
-
private rowAt;
|
|
182
|
-
/** Whether the document has a layout kind: only then are there beside placements. */
|
|
183
|
-
private get layouts();
|
|
184
|
-
/**
|
|
185
|
-
* The block a beside placement over `block` stands beside: the document's
|
|
186
|
-
* own resolution (`facade.besideAt`, `placeBeside`'s): a list item's list,
|
|
187
|
-
* a code line's code block, a toggle's child itself, an item itself.
|
|
188
|
-
*/
|
|
189
|
-
private besideOf;
|
|
190
|
-
/** The item (and its layout) a beside placement at `outer` (`besideOf`) adds a column beside. */
|
|
191
|
-
private layoutOf;
|
|
192
|
-
/**
|
|
193
|
-
* Notion's beside bands over `row` (`docs/columns-plan.md`, "View layer"), only while the
|
|
194
|
-
* pointer is within its own row's height, the document has a layout kind
|
|
195
|
-
* and the layout the drop makes or grows does not stack (`stacks`):
|
|
196
|
-
* - right: the row's last 15% (at least 32px), and the slop past it;
|
|
197
|
-
* - left: the slop left of the row (its sticky margin, left of its text
|
|
198
|
-
* column), only for a row whose parent is the root or a column (a
|
|
199
|
-
* list's item: its list's) — a nested row keeps the pointer's x for its
|
|
200
|
-
* levels (`zones`) — and only
|
|
201
|
-
* inside the editor (a column's gap): left of the editor's blocks is the
|
|
202
|
-
* handle column, which reorders (`margin`);
|
|
203
|
-
* - over a layout's gap (the row is the layout): right of the column
|
|
204
|
-
* before it, a new column between.
|
|
205
|
-
* `undefined` outside the bands (the hitbox's halves stand), else the
|
|
206
|
-
* placement, or `null` when the document refuses it: a refused band shows
|
|
207
|
-
* nothing.
|
|
208
|
-
*/
|
|
209
|
-
private beside;
|
|
210
|
-
/** Where the editor's blocks start (`gutter`), or `fallback` without a host. */
|
|
211
|
-
private inside;
|
|
212
|
-
/** The children a block shows: none for a closed toggle's, or a container's items. */
|
|
213
|
-
private shown;
|
|
214
|
-
/**
|
|
215
|
-
* Over a dragged block, the parent it leaves when that parent shows no
|
|
216
|
-
* other child: the gap under the parent's own row, which reparents as
|
|
217
|
-
* the parent's lower half does (`zones`). Else `row`.
|
|
218
|
-
*/
|
|
219
|
-
private emptied;
|
|
220
|
-
/**
|
|
221
|
-
* The placements over `row`, each half's in preference order (a refused
|
|
222
|
-
* one gives way to the next, then to the other half's):
|
|
223
|
-
* - the top half: before it;
|
|
224
|
-
* - the bottom half of a block whose children show (not a closed toggle):
|
|
225
|
-
* its first child's slot. Pragmatic drag and drop's tree rule: an
|
|
226
|
-
* expanded item offers no "after" on its own row;
|
|
227
|
-
* - else, after it at the level whose text column is nearest the pointer:
|
|
228
|
-
* the last block of a nested group reparents to any ancestor it ends,
|
|
229
|
-
* down to the root. Past one nesting step right of its text start,
|
|
230
|
-
* inside it (its last child) first. A block every shown child of which
|
|
231
|
-
* is dragged is not expanded: its levels, never inside it when the drag
|
|
232
|
-
* moves only its children (they would stay where they are).
|
|
233
|
-
* None over a dragged block's own row or its subtree: released there, the
|
|
234
|
-
* drag changes nothing (its levels would outdent it) — unless it empties
|
|
235
|
-
* its parent's shown children (`emptied`): that parent's row. Over the
|
|
236
|
-
* hint of the row's empty body (`body.hint`: an open toggle's, a
|
|
237
|
-
* callout's), inside it first, either half.
|
|
238
|
-
*/
|
|
239
|
-
private zones;
|
|
240
122
|
/**
|
|
241
123
|
* The placement a drop target record offers: the page's margins
|
|
242
124
|
* (`margin`), else a beside band of the row first (`beside`; `false` when
|
|
@@ -245,7 +127,5 @@ export declare class BlockHandleController {
|
|
|
245
127
|
* live.
|
|
246
128
|
*/
|
|
247
129
|
private placement;
|
|
248
|
-
/** The dragged block that is `row` or holds it: its row offers nothing (it moves with the drag). */
|
|
249
|
-
private carrier;
|
|
250
130
|
}
|
|
251
131
|
export {};
|