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
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* The resize bands of the hovered layout and the guide of a drag
|
|
6
|
-
* (`ColumnResize`), in the overlay: each band
|
|
7
|
-
* the block handles (their `+` and grip
|
|
6
|
+
* (`ColumnResize`), in the overlay: each band centered in its gap, above
|
|
7
|
+
* the block handles (their `+` and grip flush with the
|
|
8
|
+
* column, `gaps.ts`);
|
|
8
9
|
* hovered, it shows a gray guide in its middle: where the guide shows, a
|
|
9
10
|
* press resizes. A band is a focusable separator: its arrows resize
|
|
10
11
|
* (`resize.key`), focused it shows its guide in the resize color.
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
|
+
import { columnsForms } from '../../export/forms.js';
|
|
2
3
|
import './columns.css';
|
|
3
4
|
import type { BlockSnippetPayload, BlockView, EditorCommand, Plugin } from '../../plugins.js';
|
|
4
5
|
import type { Edytor } from '../../edytor.svelte.js';
|
|
5
6
|
import type { Block } from '../../block/block.svelte.js';
|
|
6
|
-
|
|
7
|
+
|
|
7
8
|
import { convertToKind, wrapBlocks, wrappable, type KindRow } from '../../kinds.js';
|
|
8
9
|
import {
|
|
9
10
|
getSelectedBlocksInDocumentOrder,
|
|
10
11
|
liftLayouts
|
|
11
12
|
} from '../../selection/replaceSelection.js';
|
|
12
13
|
import ColumnResizeStrips from './ColumnResize.svelte';
|
|
13
|
-
import { ColumnResize
|
|
14
|
+
import { ColumnResize } from './resize.svelte.js';
|
|
14
15
|
import { hoverChrome } from '../bands.svelte.js';
|
|
15
16
|
import { all, listen } from '../../utils/listen.js';
|
|
16
17
|
import { columnsEnglish, keywordsOf, labelsOf } from '../../labels.js';
|
|
@@ -23,12 +24,6 @@
|
|
|
23
24
|
minWidth?: number;
|
|
24
25
|
};
|
|
25
26
|
|
|
26
|
-
/** A weight read back from HTML (`data-width`), when it is one. */
|
|
27
|
-
const parsedWidth = (element: HTMLElement): Record<string, number> => {
|
|
28
|
-
const width = Number(element.getAttribute('data-width'));
|
|
29
|
-
return Number.isFinite(width) && width > 0 ? { width } : {};
|
|
30
|
-
};
|
|
31
|
-
|
|
32
27
|
/**
|
|
33
28
|
* Whether `block` sits in a layout's column, at any depth: no layout goes
|
|
34
29
|
* there (`layout.nest`). A `+` menu's stand-in (no id yet) answers by
|
|
@@ -165,7 +160,7 @@
|
|
|
165
160
|
ColumnResizeStrips,
|
|
166
161
|
{ resize },
|
|
167
162
|
'edytor-column-resizers',
|
|
168
|
-
// Above the block handles (5): the band
|
|
163
|
+
// Above the block handles (5): the band centered in the gap at every height.
|
|
169
164
|
6,
|
|
170
165
|
resize.measure
|
|
171
166
|
)
|
|
@@ -174,15 +169,12 @@
|
|
|
174
169
|
},
|
|
175
170
|
blocks: {
|
|
176
171
|
columns: {
|
|
177
|
-
...
|
|
172
|
+
...columnsForms().columns,
|
|
178
173
|
snippet: columns,
|
|
179
|
-
element: { tag: 'div', attributes: { 'data-edytor-columns': '' } }
|
|
180
|
-
html: (_, __, children) => `<div data-edytor-columns>${children}</div>`,
|
|
181
|
-
plain: (_, __, children) => children,
|
|
182
|
-
parse: (element) => (element.hasAttribute('data-edytor-columns') ? {} : undefined)
|
|
174
|
+
element: { tag: 'div', attributes: { 'data-edytor-columns': '' } }
|
|
183
175
|
},
|
|
184
176
|
column: {
|
|
185
|
-
...
|
|
177
|
+
...columnsForms().column,
|
|
186
178
|
snippet: column,
|
|
187
179
|
// Its weight as shown: a resize drag's preview (this view only), else `data.width`.
|
|
188
180
|
element: (data, id) => ({
|
|
@@ -191,12 +183,7 @@
|
|
|
191
183
|
'data-edytor-column': '',
|
|
192
184
|
style: `flex: ${resize.weight(id, data)} 1 0px`
|
|
193
185
|
}
|
|
194
|
-
})
|
|
195
|
-
html: (block, _, children) =>
|
|
196
|
-
`<div data-edytor-column data-width="${weightOf(block.data)}">${children}</div>`,
|
|
197
|
-
plain: (_, __, children) => children,
|
|
198
|
-
parse: (element) =>
|
|
199
|
-
element.hasAttribute('data-edytor-column') ? parsedWidth(element) : undefined
|
|
186
|
+
})
|
|
200
187
|
}
|
|
201
188
|
}
|
|
202
189
|
};
|
|
@@ -19,11 +19,13 @@ export type Gap = {
|
|
|
19
19
|
*/
|
|
20
20
|
export declare const gapBefore: (column: Block) => Gap | null;
|
|
21
21
|
/**
|
|
22
|
-
* The resize band of `gap`:
|
|
23
|
-
*
|
|
24
|
-
* a column's block takes the
|
|
25
|
-
*
|
|
26
|
-
* (
|
|
22
|
+
* The resize band of `gap`: `BAND` px (the gap's width when narrower)
|
|
23
|
+
* centered in it, its guide on the gap's middle line (Notion's). The handle
|
|
24
|
+
* of a column's block takes the gap's right part (`handleSpan`): its box
|
|
25
|
+
* from the band to the block, its `+` and grip flush with the block
|
|
26
|
+
* (Notion's "+ ⋮⋮", over the band where the gap is narrower than they are).
|
|
27
|
+
* At the default 46px gap (`--edytor-columns-gap`): the band 18–28, the
|
|
28
|
+
* handle's box 28–46.
|
|
27
29
|
*/
|
|
28
30
|
export declare const bandOf: ({ left, right }: Gap) => {
|
|
29
31
|
left: number;
|
|
@@ -27,13 +27,18 @@ export const gapBefore = (column) => {
|
|
|
27
27
|
return null;
|
|
28
28
|
};
|
|
29
29
|
/**
|
|
30
|
-
* The resize band of `gap`:
|
|
31
|
-
*
|
|
32
|
-
* a column's block takes the
|
|
33
|
-
*
|
|
34
|
-
* (
|
|
30
|
+
* The resize band of `gap`: `BAND` px (the gap's width when narrower)
|
|
31
|
+
* centered in it, its guide on the gap's middle line (Notion's). The handle
|
|
32
|
+
* of a column's block takes the gap's right part (`handleSpan`): its box
|
|
33
|
+
* from the band to the block, its `+` and grip flush with the block
|
|
34
|
+
* (Notion's "+ ⋮⋮", over the band where the gap is narrower than they are).
|
|
35
|
+
* At the default 46px gap (`--edytor-columns-gap`): the band 18–28, the
|
|
36
|
+
* handle's box 28–46.
|
|
35
37
|
*/
|
|
36
|
-
export const bandOf = ({ left, right }) =>
|
|
38
|
+
export const bandOf = ({ left, right }) => {
|
|
39
|
+
const width = Math.min(BAND, right - left);
|
|
40
|
+
return { left: left + (right - left - width) / 2, width };
|
|
41
|
+
};
|
|
37
42
|
/** The width a column block's handle spans in `gap`: from the band's right edge to the block at `blockLeft`. */
|
|
38
43
|
export const handleSpan = (gap, blockLeft) => {
|
|
39
44
|
const band = bandOf(gap);
|
|
@@ -3,8 +3,8 @@ import type { Edytor } from '../../edytor.svelte.js';
|
|
|
3
3
|
import { BandDrag } from '../bands.svelte.js';
|
|
4
4
|
/** The guide line's width (the hover guide's and the drag's). */
|
|
5
5
|
export declare const GUIDE = 2;
|
|
6
|
-
|
|
7
|
-
export
|
|
6
|
+
import { weightOf } from '../../export/forms.js';
|
|
7
|
+
export { weightOf };
|
|
8
8
|
/** The resize band in the gap between the columns `left` and `right` (`bandOf`), layer-relative. */
|
|
9
9
|
export type Strip = {
|
|
10
10
|
/** The layout, and the columns on each side. */
|
|
@@ -40,9 +40,9 @@ type Drag = {
|
|
|
40
40
|
/**
|
|
41
41
|
* The column resize (`docs/columns-plan.md`, "Resize"), chrome in the
|
|
42
42
|
* overlay: while the pointer is over a layout (not readonly, not stacked),
|
|
43
|
-
* a band in each gap between two shown columns (`bandOf`:
|
|
44
|
-
*
|
|
45
|
-
* grip sit together
|
|
43
|
+
* a band in each gap between two shown columns (`bandOf`: `BAND` px centered
|
|
44
|
+
* in the gap, the layout's height), above the block handles,
|
|
45
|
+
* whose `+` and grip sit together flush with the block (`gaps.ts`, one
|
|
46
46
|
* measurement):
|
|
47
47
|
* wherever its gray guide shows (`--edytor-columns-resize-color`, Notion's,
|
|
48
48
|
* at any height, block rows included), a press resizes. Dragging one
|
|
@@ -119,4 +119,3 @@ export declare class ColumnResize {
|
|
|
119
119
|
/** A band took (`true`) or lost the focus: its layout's bands stay while it holds it. */
|
|
120
120
|
focus: (strip: Strip, focused: boolean) => void;
|
|
121
121
|
}
|
|
122
|
-
export {};
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
import { pin } from '../../surface/overlay.js';
|
|
2
2
|
import { BandDrag, bandKey } from '../bands.svelte.js';
|
|
3
3
|
import { bandOf, gapBefore } from './gaps.js';
|
|
4
|
-
import { stacks } from '
|
|
4
|
+
import { stacks } from '../../dnd/stacking.js';
|
|
5
5
|
import { columnsEnglish, labelsOf } from '../../labels.js';
|
|
6
6
|
/** The guide line's width (the hover guide's and the drag's). */
|
|
7
7
|
export const GUIDE = 2;
|
|
8
|
-
|
|
9
|
-
export
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
import { weightOf } from '../../export/forms.js';
|
|
9
|
+
export { weightOf };
|
|
10
|
+
/** The band's middle in a gap `width` px wide, from the gap's left. */
|
|
11
|
+
const middleOf = (width) => {
|
|
12
|
+
const band = bandOf({ left: 0, right: width });
|
|
13
|
+
return band.left + band.width / 2;
|
|
12
14
|
};
|
|
13
15
|
/**
|
|
14
16
|
* The column resize (`docs/columns-plan.md`, "Resize"), chrome in the
|
|
15
17
|
* overlay: while the pointer is over a layout (not readonly, not stacked),
|
|
16
|
-
* a band in each gap between two shown columns (`bandOf`:
|
|
17
|
-
*
|
|
18
|
-
* grip sit together
|
|
18
|
+
* a band in each gap between two shown columns (`bandOf`: `BAND` px centered
|
|
19
|
+
* in the gap, the layout's height), above the block handles,
|
|
20
|
+
* whose `+` and grip sit together flush with the block (`gaps.ts`, one
|
|
19
21
|
* measurement):
|
|
20
22
|
* wherever its gray guide shows (`--edytor-columns-resize-color`, Notion's,
|
|
21
23
|
* at any height, block rows included), a press resizes. Dragging one
|
|
@@ -119,12 +121,8 @@ export class ColumnResize {
|
|
|
119
121
|
const strips = this.shown ? this.#gaps(origin) : [];
|
|
120
122
|
const drag = this.band.drag;
|
|
121
123
|
const guide = drag && {
|
|
122
|
-
// Where the hover guide showed: the band's middle,
|
|
123
|
-
x: drag.start +
|
|
124
|
-
this.#widthAt(drag) +
|
|
125
|
-
bandOf({ left: 0, right: drag.gap }).width / 2 -
|
|
126
|
-
GUIDE / 2 -
|
|
127
|
-
origin.left,
|
|
124
|
+
// Where the hover guide showed: the band's middle, the gap's (`bandOf`).
|
|
125
|
+
x: drag.start + this.#widthAt(drag) + middleOf(drag.gap) - GUIDE / 2 - origin.left,
|
|
128
126
|
top: drag.top - origin.top,
|
|
129
127
|
height: drag.height
|
|
130
128
|
};
|
|
@@ -74,6 +74,12 @@ export declare class CommentsController {
|
|
|
74
74
|
readonly resolved: PlacedThread[];
|
|
75
75
|
/** The threads the sidebar shows: the open ones, the resolved ones on demand, the active one. */
|
|
76
76
|
readonly shown: PlacedThread[];
|
|
77
|
+
/**
|
|
78
|
+
* Where the thread being written, else the active one, stands
|
|
79
|
+
* (`ChromeAnchor`): the first line of its text, by which a card may
|
|
80
|
+
* place itself (the sidebar places its cards in the margin).
|
|
81
|
+
*/
|
|
82
|
+
readonly anchor: import("../chrome.js").ChromeAnchor;
|
|
77
83
|
/** The view may write: it may start, answer, resolve and delete comments. */
|
|
78
84
|
get canComment(): boolean;
|
|
79
85
|
/** One thread, by id. */
|
|
@@ -4,6 +4,9 @@ import { showText } from '../planned.js';
|
|
|
4
4
|
import { COMMENT_MARK, blockCommentRuns, commentId, joinAnchors } from '../../crdt/protocols/comments.js';
|
|
5
5
|
import { CommentThreads } from '../../collaboration/comments/threads.js';
|
|
6
6
|
import { takeKeys } from '../../events/onFocus.js';
|
|
7
|
+
import { rangeRects } from '../../collaboration/remoteSelection.js';
|
|
8
|
+
import { runOf } from '../../components/Ranges.svelte';
|
|
9
|
+
import { virtualAnchor } from '../chrome.js';
|
|
7
10
|
const avatarColors = ['#e16259', '#d9730d', '#cb912f', '#448361', '#337ea9', '#9065b0', '#c14c8a'];
|
|
8
11
|
/**
|
|
9
12
|
* The comments plugin's state and actions (`plugins/comments`): the
|
|
@@ -92,6 +95,23 @@ export class CommentsController {
|
|
|
92
95
|
/** The threads the sidebar shows: the open ones, the resolved ones on demand, the active one. */
|
|
93
96
|
shown = $derived(this.threads.filter((thread) => thread.runs.length > 0 &&
|
|
94
97
|
(!thread.resolved || this.showResolved || thread.id === this.active)));
|
|
98
|
+
/**
|
|
99
|
+
* Where the thread being written, else the active one, stands
|
|
100
|
+
* (`ChromeAnchor`): the first line of its text, by which a card may
|
|
101
|
+
* place itself (the sidebar places its cards in the margin).
|
|
102
|
+
*/
|
|
103
|
+
anchor = virtualAnchor(() => {
|
|
104
|
+
const { edytor } = this;
|
|
105
|
+
const run = this.draft
|
|
106
|
+
? this.draftRuns()[0]
|
|
107
|
+
: this.active
|
|
108
|
+
? this.anchors.get(this.active)?.[0]
|
|
109
|
+
: undefined;
|
|
110
|
+
const [rect] = run
|
|
111
|
+
? runOf(edytor, run.block, run.offset, run.length).flatMap(({ start, end }) => rangeRects(edytor, start, end, new DOMRect()))
|
|
112
|
+
: [];
|
|
113
|
+
return rect && new DOMRect(rect.left, rect.top, rect.width, rect.height);
|
|
114
|
+
}, () => this.edytor.node);
|
|
95
115
|
/** The view may write: it may start, answer, resolve and delete comments. */
|
|
96
116
|
get canComment() {
|
|
97
117
|
return this.edytor.dispatcher.permits();
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
|
+
import { equationForms } from '../../export/forms.js';
|
|
3
|
+
import './equation.css';
|
|
2
4
|
import type {
|
|
3
5
|
BlockSnippetPayload,
|
|
4
6
|
InlineBlockSnippetPayload,
|
|
@@ -7,17 +9,15 @@
|
|
|
7
9
|
} from '../../plugins.js';
|
|
8
10
|
import type { Edytor } from '../../edytor.svelte.js';
|
|
9
11
|
import { InlineBlock } from '../../block/inlineBlock.svelte.js';
|
|
10
|
-
|
|
12
|
+
|
|
11
13
|
import { equationEnglish, keywordsOf, labelsOf } from '../../labels.js';
|
|
12
14
|
import { id } from '../../utils.js';
|
|
13
15
|
import EquationView from './EquationView.svelte';
|
|
14
|
-
import EquationEditorPanel from './EquationEditor.svelte';
|
|
15
16
|
import {
|
|
16
17
|
EquationEditor,
|
|
17
18
|
EquationRenderer,
|
|
18
19
|
equationViews,
|
|
19
20
|
expressionOf,
|
|
20
|
-
parseEquation,
|
|
21
21
|
type EquationData,
|
|
22
22
|
type EquationErrorPayload,
|
|
23
23
|
type EquationPlaceholderPayload,
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
type KatexLoader
|
|
28
28
|
} from './equation.svelte.js';
|
|
29
29
|
import { katexLoaderOf } from './katex.js';
|
|
30
|
-
import { withRulesAndTriggers } from '../triggers/triggers.js';
|
|
30
|
+
import { placeAtom, withRulesAndTriggers } from '../triggers/triggers.js';
|
|
31
31
|
|
|
32
32
|
export type {
|
|
33
33
|
EquationData,
|
|
@@ -100,13 +100,8 @@
|
|
|
100
100
|
/** `$$E=mc^2$$` typed in text: an inline equation (Notion). */
|
|
101
101
|
const dollars: InputRule = {
|
|
102
102
|
find: /\$\$([^$\n]*[^$\s][^$\n]*)\$\$$/,
|
|
103
|
-
replace: ([, tex],
|
|
104
|
-
remove(() => {
|
|
105
|
-
const atom = { type: INLINE, data: { expression: tex!.trim() } };
|
|
106
|
-
const written = edytor.insertInline(block.id, from, atom).status === 'applied';
|
|
107
|
-
if (written) caret(from + 1);
|
|
108
|
-
return written;
|
|
109
|
-
})
|
|
103
|
+
replace: ([, tex], ctx) =>
|
|
104
|
+
ctx.remove(() => placeAtom(ctx, { type: INLINE, data: { expression: tex!.trim() } }))
|
|
110
105
|
};
|
|
111
106
|
|
|
112
107
|
/** The equation a block selection or an atom selection stands for, if any. */
|
|
@@ -142,6 +137,8 @@
|
|
|
142
137
|
(edytor) => {
|
|
143
138
|
const labels = labelsOf(edytor, 'equation', equationEnglish);
|
|
144
139
|
const renderer = new EquationRenderer(katexLoaderOf(options.katex), options.macros);
|
|
140
|
+
/** The kinds' forms: MathML by KaTeX once it is loaded. */
|
|
141
|
+
const forms = equationForms(renderer.mathml);
|
|
145
142
|
// The records read with no view (`plugin(undefined)`) keep no state.
|
|
146
143
|
if (edytor && !equationViews.has(edytor))
|
|
147
144
|
equationViews.set(edytor, {
|
|
@@ -159,7 +156,7 @@
|
|
|
159
156
|
if (!view || !owns()) return;
|
|
160
157
|
const { editor } = view;
|
|
161
158
|
const { panel } = options;
|
|
162
|
-
return panel && editor.panel.mount(node,
|
|
159
|
+
return panel && editor.panel.mount(node, panel, editor, () => editor.target !== null);
|
|
163
160
|
},
|
|
164
161
|
// A block equation this view just created empty (a slash pick, Turn into) opens its editor.
|
|
165
162
|
onAfterOperation: (change) => {
|
|
@@ -206,7 +203,7 @@
|
|
|
206
203
|
],
|
|
207
204
|
blocks: {
|
|
208
205
|
equation: {
|
|
209
|
-
...
|
|
206
|
+
...forms.blocks.equation,
|
|
210
207
|
snippet: equation,
|
|
211
208
|
empty: { content: [], children: [] },
|
|
212
209
|
presets: [
|
|
@@ -223,19 +220,13 @@
|
|
|
223
220
|
]),
|
|
224
221
|
group: 'Advanced blocks'
|
|
225
222
|
}
|
|
226
|
-
]
|
|
227
|
-
html: (block) =>
|
|
228
|
-
`<div data-edytor-equation>${renderer.mathml(expressionOf(block.data), true)}</div>`,
|
|
229
|
-
plain: (block) => expressionOf(block.data),
|
|
230
|
-
parse: (element) => parseEquation(element, true)
|
|
223
|
+
]
|
|
231
224
|
}
|
|
232
225
|
},
|
|
233
226
|
inlineBlocks: {
|
|
234
227
|
[INLINE]: {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
html: (data) => renderer.mathml(expressionOf(data), false),
|
|
238
|
-
parse: (element) => parseEquation(element, false)
|
|
228
|
+
...forms.inlineBlocks.inlineEquation,
|
|
229
|
+
snippet: inlineEquation
|
|
239
230
|
}
|
|
240
231
|
}
|
|
241
232
|
},
|
|
@@ -273,11 +264,3 @@
|
|
|
273
264
|
role="presentation"><EquationView expression={expressionOf(block.data)} display={false} /></span
|
|
274
265
|
>
|
|
275
266
|
{/snippet}
|
|
276
|
-
|
|
277
|
-
<style>
|
|
278
|
-
/* A wide equation scrolls in its block; its look is a theme's. */
|
|
279
|
-
[data-edytor-equation] {
|
|
280
|
-
overflow-x: auto;
|
|
281
|
-
overflow-y: hidden;
|
|
282
|
-
}
|
|
283
|
-
</style>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import './equation.css';
|
|
1
2
|
import type { Plugin } from '../../plugins.js';
|
|
2
3
|
import { EquationEditor, type EquationData, type EquationErrorPayload, type EquationPlaceholderPayload, type EquationPluginOptions, type EquationTarget, type KatexLike, type KatexLoader } from './equation.svelte.js';
|
|
3
4
|
export type { EquationData, EquationEditor, EquationErrorPayload, EquationPlaceholderPayload, EquationPluginOptions, EquationTarget, KatexLike, KatexLoader };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/* Loaded by the plugin's module (a component's own <style> is dropped when only
|
|
2
|
+
its module is used: the plugin factory, never the component). */
|
|
3
|
+
/* A wide equation scrolls in its block; its look is a theme's. */
|
|
4
|
+
[data-edytor-equation] {
|
|
5
|
+
overflow-x: auto;
|
|
6
|
+
overflow-y: hidden;
|
|
7
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type Snippet } from 'svelte';
|
|
2
2
|
import type { Attachment } from 'svelte/attachments';
|
|
3
3
|
import type { Edytor } from '../../edytor.svelte.js';
|
|
4
|
+
export { TEX, expressionOf, parseEquation, sourceMathml, type EquationData } from './tex.js';
|
|
4
5
|
/** The part of KaTeX the plugin uses: `katex.renderToString`. */
|
|
5
6
|
export type KatexLike = {
|
|
6
7
|
renderToString: (tex: string, options?: Record<string, unknown>) => string;
|
|
@@ -66,20 +67,12 @@ export type EquationErrorPayload = {
|
|
|
66
67
|
/** The view's word for it (`equation.invalid`). */
|
|
67
68
|
label: string;
|
|
68
69
|
};
|
|
69
|
-
/** The data of a block equation and of an inline one: its TeX source. */
|
|
70
|
-
export type EquationData = {
|
|
71
|
-
expression?: string;
|
|
72
|
-
};
|
|
73
70
|
/** What drawing an equation gives: KaTeX's markup, its error, or nothing yet (the source shows). */
|
|
74
71
|
export type Drawn = {
|
|
75
72
|
html: string;
|
|
76
73
|
} | {
|
|
77
74
|
error: string;
|
|
78
75
|
} | null;
|
|
79
|
-
/** The MathML annotation that carries an equation's TeX source. */
|
|
80
|
-
export declare const TEX = "application/x-tex";
|
|
81
|
-
/** An equation's TeX source: its `expression`, a string. */
|
|
82
|
-
export declare const expressionOf: (data: unknown) => string;
|
|
83
76
|
/**
|
|
84
77
|
* KaTeX for one plugin: loaded once, the first time an equation is drawn in
|
|
85
78
|
* a browser, and reactive (an equation drawn before it loads shows its
|
|
@@ -104,13 +97,6 @@ export declare class EquationRenderer {
|
|
|
104
97
|
mathml: (tex: string, display: boolean) => string;
|
|
105
98
|
private options;
|
|
106
99
|
}
|
|
107
|
-
/**
|
|
108
|
-
* HTML import: the TeX source an equation's element carries — a `<math>`'s
|
|
109
|
-
* `application/x-tex` annotation (or its `alttext`), alone or in KaTeX's
|
|
110
|
-
* markup (`.katex`, `.katex-display`) — when the element is an equation of
|
|
111
|
-
* the display asked (`display="block"`: a block), else `undefined`.
|
|
112
|
-
*/
|
|
113
|
-
export declare const parseEquation: (element: HTMLElement, display: boolean) => EquationData | undefined;
|
|
114
100
|
/** The equation being edited: a block equation, or an inline one (`atom`) in block `block`. */
|
|
115
101
|
export type EquationTarget = {
|
|
116
102
|
block: string;
|
|
@@ -141,6 +127,12 @@ export declare class EquationEditor {
|
|
|
141
127
|
target: EquationTarget | null;
|
|
142
128
|
/** The view is readonly (reactive): the editor closes. */
|
|
143
129
|
get readonly(): boolean;
|
|
130
|
+
/**
|
|
131
|
+
* Where the panel stands: the edited equation (`ChromeAnchor`; Notion
|
|
132
|
+
* centers it under a block equation, `display`, and starts it under an
|
|
133
|
+
* inline one).
|
|
134
|
+
*/
|
|
135
|
+
get anchor(): import("../chrome.js").ChromeAnchor;
|
|
144
136
|
/** A block equation is edited (a field of several lines). */
|
|
145
137
|
get display(): boolean;
|
|
146
138
|
/** The edited equation's TeX source (reactive through its block's cell). */
|
|
@@ -3,15 +3,10 @@ import { blockSelection } from '../../session/selection.js';
|
|
|
3
3
|
import { InlineBlock } from '../../block/inlineBlock.svelte.js';
|
|
4
4
|
import { takeKeys } from '../../events/onFocus.js';
|
|
5
5
|
import { Anchored } from '../anchored.svelte.js';
|
|
6
|
-
import {
|
|
6
|
+
import { expressionOf, sourceMathml } from './tex.js';
|
|
7
|
+
export { TEX, expressionOf, parseEquation, sourceMathml } from './tex.js';
|
|
7
8
|
import { all, listen } from '../../utils/listen.js';
|
|
8
|
-
|
|
9
|
-
export const TEX = 'application/x-tex';
|
|
10
|
-
/** An equation's TeX source: its `expression`, a string. */
|
|
11
|
-
export const expressionOf = (data) => {
|
|
12
|
-
const value = data?.expression;
|
|
13
|
-
return typeof value === 'string' ? value : '';
|
|
14
|
-
};
|
|
9
|
+
import { keysOf } from '../list.svelte.js';
|
|
15
10
|
/** The cap of the drawings each renderer keeps. */
|
|
16
11
|
const CACHE = 256;
|
|
17
12
|
/**
|
|
@@ -73,9 +68,7 @@ export class EquationRenderer {
|
|
|
73
68
|
// TeX KaTeX cannot read: the source as text, below.
|
|
74
69
|
}
|
|
75
70
|
}
|
|
76
|
-
|
|
77
|
-
return (`<span class="katex"><math xmlns="http://www.w3.org/1998/Math/MathML"${display ? ' display="block"' : ''}>` +
|
|
78
|
-
`<semantics><mrow><mtext>${source}</mtext></mrow><annotation encoding="${TEX}">${source}</annotation></semantics></math></span>`);
|
|
71
|
+
return sourceMathml(tex, display);
|
|
79
72
|
};
|
|
80
73
|
options = (display, output) => ({
|
|
81
74
|
displayMode: display,
|
|
@@ -97,29 +90,6 @@ export class EquationRenderer {
|
|
|
97
90
|
}, (error) => console.error('[edytor] KaTeX failed to load', error));
|
|
98
91
|
};
|
|
99
92
|
}
|
|
100
|
-
/**
|
|
101
|
-
* HTML import: the TeX source an equation's element carries — a `<math>`'s
|
|
102
|
-
* `application/x-tex` annotation (or its `alttext`), alone or in KaTeX's
|
|
103
|
-
* markup (`.katex`, `.katex-display`) — when the element is an equation of
|
|
104
|
-
* the display asked (`display="block"`: a block), else `undefined`.
|
|
105
|
-
*/
|
|
106
|
-
export const parseEquation = (element, display) => {
|
|
107
|
-
const own = element.localName === 'math';
|
|
108
|
-
const wrapper = element.classList.contains('katex') ||
|
|
109
|
-
element.classList.contains('katex-display') ||
|
|
110
|
-
element.hasAttribute('data-edytor-equation');
|
|
111
|
-
if (!own && !wrapper)
|
|
112
|
-
return undefined;
|
|
113
|
-
const math = own ? element : element.querySelector('math');
|
|
114
|
-
if (!math)
|
|
115
|
-
return undefined;
|
|
116
|
-
const block = math.getAttribute('display') === 'block' || element.classList.contains('katex-display');
|
|
117
|
-
if (block !== display)
|
|
118
|
-
return undefined;
|
|
119
|
-
const tex = math.querySelector(`annotation[encoding="${TEX}"]`)?.textContent ??
|
|
120
|
-
math.getAttribute('alttext');
|
|
121
|
-
return tex?.trim() ? { expression: tex.trim() } : undefined;
|
|
122
|
-
};
|
|
123
93
|
/**
|
|
124
94
|
* One view's equation editor (Notion's): a click on an equation of an
|
|
125
95
|
* editable view (Enter on a selected one, or a new empty one) opens its
|
|
@@ -161,12 +131,12 @@ export class EquationEditor {
|
|
|
161
131
|
return this.edytor.readonly;
|
|
162
132
|
}
|
|
163
133
|
/**
|
|
164
|
-
* Where the panel stands:
|
|
165
|
-
*
|
|
166
|
-
*
|
|
134
|
+
* Where the panel stands: the edited equation (`ChromeAnchor`; Notion
|
|
135
|
+
* centers it under a block equation, `display`, and starts it under an
|
|
136
|
+
* inline one).
|
|
167
137
|
*/
|
|
168
|
-
get
|
|
169
|
-
return this.
|
|
138
|
+
get anchor() {
|
|
139
|
+
return this.panel.anchor;
|
|
170
140
|
}
|
|
171
141
|
/** A block equation is edited (a field of several lines). */
|
|
172
142
|
get display() {
|
|
@@ -216,7 +186,6 @@ export class EquationEditor {
|
|
|
216
186
|
if (!target)
|
|
217
187
|
return;
|
|
218
188
|
this.target = null;
|
|
219
|
-
this.panel.box = null;
|
|
220
189
|
this.edytor.overlay.invalidate();
|
|
221
190
|
const block = this.#block(target);
|
|
222
191
|
if (!block)
|
|
@@ -248,16 +217,10 @@ export class EquationEditor {
|
|
|
248
217
|
* them. Focus leaving the panel for somewhere else closes it.
|
|
249
218
|
*/
|
|
250
219
|
field = (node) => untrack(() => {
|
|
251
|
-
const keydown = (
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
if (!enter && event.key !== 'Escape')
|
|
256
|
-
return;
|
|
257
|
-
event.preventDefault();
|
|
258
|
-
event.stopPropagation();
|
|
259
|
-
this.close();
|
|
260
|
-
};
|
|
220
|
+
const keydown = keysOf({
|
|
221
|
+
Enter: (event) => !(event.shiftKey && this.display) && this.close(),
|
|
222
|
+
Escape: () => this.close()
|
|
223
|
+
}, true);
|
|
261
224
|
const element = node;
|
|
262
225
|
const off = listen(element, 'keydown', keydown);
|
|
263
226
|
const off2 = listen(element, 'focusout', this.panel.blurred);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** The data of a block equation and of an inline one: its TeX source. */
|
|
2
|
+
export type EquationData = {
|
|
3
|
+
expression?: string;
|
|
4
|
+
};
|
|
5
|
+
/** The MathML annotation that carries an equation's TeX source. */
|
|
6
|
+
export declare const TEX = "application/x-tex";
|
|
7
|
+
/** An equation's TeX source: its `expression`, a string. */
|
|
8
|
+
export declare const expressionOf: (data: unknown) => string;
|
|
9
|
+
/** MathML whose `application/x-tex` annotation is `tex`, the source as its text, in KaTeX's `katex` class. */
|
|
10
|
+
export declare const sourceMathml: (tex: string, display: boolean) => string;
|
|
11
|
+
/**
|
|
12
|
+
* HTML import: the TeX source an equation's element carries — a `<math>`'s
|
|
13
|
+
* `application/x-tex` annotation (or its `alttext`), alone or in KaTeX's
|
|
14
|
+
* markup (`.katex`, `.katex-display`) — when the element is an equation of
|
|
15
|
+
* the display asked (`display="block"`: a block), else `undefined`.
|
|
16
|
+
*/
|
|
17
|
+
export declare const parseEquation: (element: HTMLElement, display: boolean) => EquationData | undefined;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An equation's pure forms: its data, its TeX source, the MathML that
|
|
3
|
+
* carries the source (`sourceMathml`, the clipboard's form before KaTeX
|
|
4
|
+
* loads and the export's on a server) and its HTML import. No Svelte.
|
|
5
|
+
*/
|
|
6
|
+
import { escapeHtml } from '../../clipboard/serializeClipboardFragment.js';
|
|
7
|
+
/** The MathML annotation that carries an equation's TeX source. */
|
|
8
|
+
export const TEX = 'application/x-tex';
|
|
9
|
+
/** An equation's TeX source: its `expression`, a string. */
|
|
10
|
+
export const expressionOf = (data) => {
|
|
11
|
+
const value = data?.expression;
|
|
12
|
+
return typeof value === 'string' ? value : '';
|
|
13
|
+
};
|
|
14
|
+
/** MathML whose `application/x-tex` annotation is `tex`, the source as its text, in KaTeX's `katex` class. */
|
|
15
|
+
export const sourceMathml = (tex, display) => {
|
|
16
|
+
const source = escapeHtml(tex);
|
|
17
|
+
return (`<span class="katex"><math xmlns="http://www.w3.org/1998/Math/MathML"${display ? ' display="block"' : ''}>` +
|
|
18
|
+
`<semantics><mrow><mtext>${source}</mtext></mrow><annotation encoding="${TEX}">${source}</annotation></semantics></math></span>`);
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* HTML import: the TeX source an equation's element carries — a `<math>`'s
|
|
22
|
+
* `application/x-tex` annotation (or its `alttext`), alone or in KaTeX's
|
|
23
|
+
* markup (`.katex`, `.katex-display`) — when the element is an equation of
|
|
24
|
+
* the display asked (`display="block"`: a block), else `undefined`.
|
|
25
|
+
*/
|
|
26
|
+
export const parseEquation = (element, display) => {
|
|
27
|
+
const own = element.localName === 'math';
|
|
28
|
+
const wrapper = element.classList.contains('katex') ||
|
|
29
|
+
element.classList.contains('katex-display') ||
|
|
30
|
+
element.hasAttribute('data-edytor-equation');
|
|
31
|
+
if (!own && !wrapper)
|
|
32
|
+
return undefined;
|
|
33
|
+
const math = own ? element : element.querySelector('math');
|
|
34
|
+
if (!math)
|
|
35
|
+
return undefined;
|
|
36
|
+
const block = math.getAttribute('display') === 'block' || element.classList.contains('katex-display');
|
|
37
|
+
if (block !== display)
|
|
38
|
+
return undefined;
|
|
39
|
+
const tex = math.querySelector(`annotation[encoding="${TEX}"]`)?.textContent ??
|
|
40
|
+
math.getAttribute('alttext');
|
|
41
|
+
return tex?.trim() ? { expression: tex.trim() } : undefined;
|
|
42
|
+
};
|