@formicoidea/labre-core 0.50.0 → 0.52.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/dist/_pkgs/affine-block-attachment/asset-picker.d.ts +24 -0
- package/dist/_pkgs/affine-block-attachment/asset-picker.js +87 -0
- package/dist/_pkgs/affine-block-attachment/configs/slash-menu.js +3 -20
- package/dist/_pkgs/affine-block-attachment/index.d.ts +1 -0
- package/dist/_pkgs/affine-block-attachment/index.js +1 -0
- package/dist/_pkgs/affine-block-attachment/utils.d.ts +9 -1
- package/dist/_pkgs/affine-block-attachment/utils.js +9 -0
- package/dist/_pkgs/affine-block-bookmark/adapters/markdown/markdown.js +14 -1
- package/dist/_pkgs/affine-block-bookmark/adapters/notion-html.js +5 -1
- package/dist/_pkgs/affine-block-database/adapters/markdown.js +5 -3
- package/dist/_pkgs/affine-block-embed/common/adapters/html.js +5 -3
- package/dist/_pkgs/affine-block-embed/common/adapters/markdown.js +11 -0
- package/dist/_pkgs/affine-block-frame/frame-template.d.ts +58 -0
- package/dist/_pkgs/affine-block-frame/frame-template.js +207 -0
- package/dist/_pkgs/affine-block-frame/frame-toolbar.js +19 -3
- package/dist/_pkgs/affine-block-frame/index.d.ts +1 -0
- package/dist/_pkgs/affine-block-frame/index.js +1 -0
- package/dist/_pkgs/affine-block-frame/translations.d.ts +7 -0
- package/dist/_pkgs/affine-block-frame/translations.js +16 -1
- package/dist/_pkgs/affine-block-frame/view.js +6 -0
- package/dist/_pkgs/affine-block-image/asset-picker.d.ts +63 -0
- package/dist/_pkgs/affine-block-image/asset-picker.js +183 -0
- package/dist/_pkgs/affine-block-image/commands/insert-images.d.ts +5 -0
- package/dist/_pkgs/affine-block-image/commands/insert-images.js +8 -8
- package/dist/_pkgs/affine-block-image/components/page-image-block.d.ts +11 -0
- package/dist/_pkgs/affine-block-image/components/page-image-block.js +81 -12
- package/dist/_pkgs/affine-block-image/configs/replace-action.d.ts +9 -0
- package/dist/_pkgs/affine-block-image/configs/replace-action.js +27 -0
- package/dist/_pkgs/affine-block-image/configs/toolbar.js +6 -0
- package/dist/_pkgs/affine-block-image/crop/crop-controller.d.ts +46 -0
- package/dist/_pkgs/affine-block-image/crop/crop-controller.js +104 -0
- package/dist/_pkgs/affine-block-image/crop/crop-math.d.ts +70 -0
- package/dist/_pkgs/affine-block-image/crop/crop-math.js +141 -0
- package/dist/_pkgs/affine-block-image/crop/crop-overlay.d.ts +57 -0
- package/dist/_pkgs/affine-block-image/crop/crop-overlay.js +343 -0
- package/dist/_pkgs/affine-block-image/crop/crop-toolbar.d.ts +12 -0
- package/dist/_pkgs/affine-block-image/crop/crop-toolbar.js +78 -0
- package/dist/_pkgs/affine-block-image/crop/write-crop.d.ts +16 -0
- package/dist/_pkgs/affine-block-image/crop/write-crop.js +57 -0
- package/dist/_pkgs/affine-block-image/edgeless-clipboard-config.js +4 -1
- package/dist/_pkgs/affine-block-image/effects.js +2 -0
- package/dist/_pkgs/affine-block-image/image-block.d.ts +2 -0
- package/dist/_pkgs/affine-block-image/image-block.js +2 -0
- package/dist/_pkgs/affine-block-image/image-edgeless-block.d.ts +2 -0
- package/dist/_pkgs/affine-block-image/image-edgeless-block.js +36 -8
- package/dist/_pkgs/affine-block-image/image-resize-manager.js +15 -0
- package/dist/_pkgs/affine-block-image/index.d.ts +1 -0
- package/dist/_pkgs/affine-block-image/index.js +1 -0
- package/dist/_pkgs/affine-block-image/translations.d.ts +15 -0
- package/dist/_pkgs/affine-block-image/translations.js +43 -0
- package/dist/_pkgs/affine-block-image/utils.d.ts +13 -0
- package/dist/_pkgs/affine-block-image/utils.js +10 -1
- package/dist/_pkgs/affine-block-root/clipboard/page-clipboard.js +5 -0
- package/dist/_pkgs/affine-block-root/commands/page-export-commands.d.ts +2 -0
- package/dist/_pkgs/affine-block-root/commands/page-export-commands.js +71 -0
- package/dist/_pkgs/affine-block-root/index.d.ts +1 -0
- package/dist/_pkgs/affine-block-root/index.js +1 -0
- package/dist/_pkgs/affine-block-root/view.js +8 -0
- package/dist/_pkgs/affine-block-surface/extensions/drawio-export/capability.d.ts +30 -0
- package/dist/_pkgs/affine-block-surface/extensions/drawio-export/capability.js +44 -0
- package/dist/_pkgs/affine-block-surface/extensions/drawio-export/colors.d.ts +26 -0
- package/dist/_pkgs/affine-block-surface/extensions/drawio-export/colors.js +82 -0
- package/dist/_pkgs/affine-block-surface/extensions/drawio-export/command.d.ts +18 -0
- package/dist/_pkgs/affine-block-surface/extensions/drawio-export/command.js +91 -0
- package/dist/_pkgs/affine-block-surface/extensions/drawio-export/index.d.ts +3 -0
- package/dist/_pkgs/affine-block-surface/extensions/drawio-export/index.js +3 -0
- package/dist/_pkgs/affine-block-surface/extensions/drawio-export/writer.d.ts +50 -0
- package/dist/_pkgs/affine-block-surface/extensions/drawio-export/writer.js +732 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-manager/draw-image-block.d.ts +12 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-manager/draw-image-block.js +15 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-manager/export-manager.js +7 -1
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/command.d.ts +7 -1
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/command.js +60 -1
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/index.d.ts +2 -2
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/index.js +2 -2
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/marker-version.d.ts +6 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/marker-version.js +8 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/render.d.ts +28 -1
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/render.js +66 -6
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/svg-context.d.ts +2 -7
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/svg-context.js +2 -6
- package/dist/_pkgs/affine-block-surface/extensions/index.d.ts +2 -0
- package/dist/_pkgs/affine-block-surface/extensions/index.js +2 -0
- package/dist/_pkgs/affine-block-surface/extensions/interchange-export.d.ts +84 -0
- package/dist/_pkgs/affine-block-surface/extensions/interchange-export.js +150 -0
- package/dist/_pkgs/affine-block-surface/extensions/interchange-import.js +24 -2
- package/dist/_pkgs/affine-block-surface/extensions/interchange.d.ts +23 -2
- package/dist/_pkgs/affine-block-surface/extensions/interchange.js +4 -1
- package/dist/_pkgs/affine-block-surface/extensions/legend-role.d.ts +18 -0
- package/dist/_pkgs/affine-block-surface/extensions/legend-role.js +20 -0
- package/dist/_pkgs/affine-block-surface/extensions/legend.d.ts +2 -19
- package/dist/_pkgs/affine-block-surface/extensions/legend.js +2 -18
- package/dist/_pkgs/affine-block-surface/extensions/svg-sanitize.d.ts +67 -0
- package/dist/_pkgs/affine-block-surface/extensions/svg-sanitize.js +235 -0
- package/dist/_pkgs/affine-block-surface/extensions/svg-sketch-translations.d.ts +1 -0
- package/dist/_pkgs/affine-block-surface/extensions/svg-sketch-translations.js +9 -0
- package/dist/_pkgs/affine-block-surface/extensions/svg-sketch.d.ts +17 -13
- package/dist/_pkgs/affine-block-surface/extensions/svg-sketch.js +52 -80
- package/dist/_pkgs/affine-block-surface/extensions/xml-element.d.ts +98 -0
- package/dist/_pkgs/affine-block-surface/extensions/xml-element.js +261 -0
- package/dist/_pkgs/affine-block-surface/extensions/xml-reader.d.ts +238 -0
- package/dist/_pkgs/affine-block-surface/extensions/xml-reader.js +570 -0
- package/dist/_pkgs/affine-block-surface/framework-background/def.js +1 -1
- package/dist/_pkgs/affine-block-surface/index.d.ts +1 -0
- package/dist/_pkgs/affine-block-surface/index.js +1 -0
- package/dist/_pkgs/affine-block-surface/interchange-headless.d.ts +29 -0
- package/dist/_pkgs/affine-block-surface/interchange-headless.js +32 -0
- package/dist/_pkgs/affine-block-surface/view.js +22 -2
- package/dist/_pkgs/affine-block-table/adapters/utils.js +24 -1
- package/dist/_pkgs/affine-gfx-note/toolbar/note-menu.js +5 -8
- package/dist/_pkgs/affine-gfx-template/contribute.d.ts +14 -4
- package/dist/_pkgs/affine-gfx-template/contribute.js +47 -6
- package/dist/_pkgs/affine-gfx-template/toolbar/builtin-templates.d.ts +7 -2
- package/dist/_pkgs/affine-gfx-template/toolbar/builtin-templates.js +14 -40
- package/dist/_pkgs/affine-gfx-template/toolbar/resolve-name.d.ts +1 -1
- package/dist/_pkgs/affine-gfx-template/toolbar/resolve-name.js +1 -1
- package/dist/_pkgs/affine-gfx-template/toolbar/template-panel.d.ts +4 -4
- package/dist/_pkgs/affine-gfx-template/toolbar/template-panel.js +9 -9
- package/dist/_pkgs/affine-gfx-template/toolbar/template-type.d.ts +2 -4
- package/dist/_pkgs/affine-gfx-template/translations.d.ts +5 -0
- package/dist/_pkgs/affine-gfx-template/translations.js +9 -0
- package/dist/_pkgs/affine-inline-footnote/adapters/markdown/inline-delta.js +6 -0
- package/dist/_pkgs/affine-inline-footnote/adapters/markdown/markdown-inline.js +7 -0
- package/dist/_pkgs/affine-inline-link/adapters/html/html-inline.js +4 -1
- package/dist/_pkgs/affine-inline-link/adapters/html/inline-delta.js +3 -1
- package/dist/_pkgs/affine-inline-link/adapters/markdown/inline-delta.js +4 -1
- package/dist/_pkgs/affine-inline-link/adapters/notion-html/html-inline.js +2 -1
- package/dist/_pkgs/affine-inline-link/link-node/affine-link.d.ts +7 -0
- package/dist/_pkgs/affine-inline-link/link-node/affine-link.js +37 -0
- package/dist/_pkgs/affine-inline-link/link-node/index.d.ts +1 -0
- package/dist/_pkgs/affine-inline-link/link-node/index.js +1 -0
- package/dist/_pkgs/affine-inline-link/link-node/propose-views.d.ts +22 -0
- package/dist/_pkgs/affine-inline-link/link-node/propose-views.js +59 -0
- package/dist/_pkgs/affine-model/blocks/image/image-crop.d.ts +48 -0
- package/dist/_pkgs/affine-model/blocks/image/image-crop.js +78 -0
- package/dist/_pkgs/affine-model/blocks/image/image-model.d.ts +6 -0
- package/dist/_pkgs/affine-model/blocks/image/image-model.js +2 -0
- package/dist/_pkgs/affine-model/blocks/image/index.d.ts +1 -0
- package/dist/_pkgs/affine-model/blocks/image/index.js +1 -0
- package/dist/_pkgs/affine-model/consts/shape.d.ts +2 -0
- package/dist/_pkgs/affine-model/consts/shape.js +5 -0
- package/dist/_pkgs/affine-model/elements/bpmn/consts.d.ts +31 -0
- package/dist/_pkgs/affine-model/elements/bpmn/consts.js +31 -0
- package/dist/_pkgs/affine-model/elements/bpmn/index.d.ts +1 -0
- package/dist/_pkgs/affine-model/elements/bpmn/index.js +1 -0
- package/dist/_pkgs/affine-model/elements/bpmn/pool.d.ts +0 -25
- package/dist/_pkgs/affine-model/elements/bpmn/pool.js +1 -25
- package/dist/_pkgs/affine-model/elements/shape/shape.d.ts +0 -2
- package/dist/_pkgs/affine-model/elements/shape/shape.js +1 -2
- package/dist/_pkgs/affine-model/elements/uml/consts.d.ts +133 -0
- package/dist/_pkgs/affine-model/elements/uml/consts.js +107 -0
- package/dist/_pkgs/affine-model/elements/uml/diagram.d.ts +1 -79
- package/dist/_pkgs/affine-model/elements/uml/diagram.js +1 -53
- package/dist/_pkgs/affine-model/elements/uml/fragment.d.ts +0 -15
- package/dist/_pkgs/affine-model/elements/uml/fragment.js +1 -15
- package/dist/_pkgs/affine-model/elements/uml/index.d.ts +1 -0
- package/dist/_pkgs/affine-model/elements/uml/index.js +1 -0
- package/dist/_pkgs/affine-model/elements/uml/partition.d.ts +0 -20
- package/dist/_pkgs/affine-model/elements/uml/partition.js +1 -20
- package/dist/_pkgs/affine-model/elements/uml/region.d.ts +0 -11
- package/dist/_pkgs/affine-model/elements/uml/region.js +1 -11
- package/dist/_pkgs/affine-model/headless.d.ts +19 -0
- package/dist/_pkgs/affine-model/headless.js +19 -0
- package/dist/_pkgs/affine-shared/headless.d.ts +10 -0
- package/dist/_pkgs/affine-shared/headless.js +10 -0
- package/dist/_pkgs/affine-shared/services/asset-picker-service.d.ts +63 -0
- package/dist/_pkgs/affine-shared/services/asset-picker-service.js +20 -0
- package/dist/_pkgs/affine-shared/services/frame-template-service.d.ts +83 -0
- package/dist/_pkgs/affine-shared/services/frame-template-service.js +17 -0
- package/dist/_pkgs/affine-shared/services/index.d.ts +3 -0
- package/dist/_pkgs/affine-shared/services/index.js +3 -0
- package/dist/_pkgs/affine-shared/services/thread-marks-service.d.ts +69 -0
- package/dist/_pkgs/affine-shared/services/thread-marks-service.js +20 -0
- package/dist/_pkgs/affine-shared/services/translation-service/chrome.d.ts +6 -0
- package/dist/_pkgs/affine-shared/services/translation-service/chrome.js +10 -0
- package/dist/_pkgs/affine-widget-drag-handle/watchers/drag-event-watcher.js +8 -3
- package/dist/_pkgs/affine-widget-keyboard-toolbar/config.js +4 -16
- package/dist/_pkgs/affine-widget-linked-doc/transformers/html.d.ts +7 -0
- package/dist/_pkgs/affine-widget-linked-doc/transformers/html.js +25 -24
- package/dist/_pkgs/affine-widget-linked-doc/transformers/index.d.ts +1 -1
- package/dist/_pkgs/affine-widget-linked-doc/transformers/markdown.d.ts +7 -0
- package/dist/_pkgs/affine-widget-linked-doc/transformers/markdown.js +26 -25
- package/dist/_pkgs/affine-widget-linked-doc/transformers/utils.d.ts +23 -0
- package/dist/_pkgs/affine-widget-linked-doc/transformers/utils.js +14 -0
- package/dist/_pkgs/affine-widget-thread-marks/effects.d.ts +1 -0
- package/dist/_pkgs/affine-widget-thread-marks/effects.js +4 -0
- package/dist/_pkgs/affine-widget-thread-marks/excerpt.d.ts +19 -0
- package/dist/_pkgs/affine-widget-thread-marks/excerpt.js +68 -0
- package/dist/_pkgs/affine-widget-thread-marks/index.d.ts +5 -0
- package/dist/_pkgs/affine-widget-thread-marks/index.js +8 -0
- package/dist/_pkgs/affine-widget-thread-marks/toolbar.d.ts +49 -0
- package/dist/_pkgs/affine-widget-thread-marks/toolbar.js +108 -0
- package/dist/_pkgs/affine-widget-thread-marks/translations.d.ts +9 -0
- package/dist/_pkgs/affine-widget-thread-marks/translations.js +11 -0
- package/dist/_pkgs/affine-widget-thread-marks/view.d.ts +12 -0
- package/dist/_pkgs/affine-widget-thread-marks/view.js +25 -0
- package/dist/_pkgs/affine-widget-thread-marks/widget.d.ts +51 -0
- package/dist/_pkgs/affine-widget-thread-marks/widget.js +214 -0
- package/dist/commands.js +5 -2
- package/dist/extensions/view.js +2 -0
- package/dist/host-panels.d.ts +24 -1
- package/dist/host-panels.js +61 -10
- package/dist/interchange.d.ts +1 -0
- package/dist/interchange.js +1 -0
- package/dist/model/headless.d.ts +1 -0
- package/dist/model/headless.js +1 -0
- package/dist/shared/headless.d.ts +1 -0
- package/dist/shared/headless.js +1 -0
- package/dist/translations.js +10 -1
- package/package.json +13 -1
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { createIdentifier } from '../../global/di/index.js';
|
|
2
|
+
export const FrameTemplateProvider = createIdentifier('AffineFrameTemplate');
|
|
3
|
+
/**
|
|
4
|
+
* Host seam: keep frames saved as templates. Absent, the toolbar has no
|
|
5
|
+
* "Save as template", the Templates panel has no "Saved frames" category and
|
|
6
|
+
* nothing is reported when a frame is deleted.
|
|
7
|
+
*
|
|
8
|
+
* `di.override`, like `OutlinePanelExtension`, so a later registration always
|
|
9
|
+
* wins and registering twice never throws at boot.
|
|
10
|
+
*/
|
|
11
|
+
export function FrameTemplateExtension(service) {
|
|
12
|
+
return {
|
|
13
|
+
setup: di => {
|
|
14
|
+
di.override(FrameTemplateProvider, () => service);
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export * from './artefact-catalogue-service.js';
|
|
2
|
+
export * from './asset-picker-service.js';
|
|
2
3
|
export * from './audit-service.js';
|
|
3
4
|
export * from './auto-clear-selection-service.js';
|
|
4
5
|
export * from './block-meta-service.js';
|
|
@@ -18,6 +19,7 @@ export * from './embed-option-service.js';
|
|
|
18
19
|
export * from './feature-flag-service.js';
|
|
19
20
|
export * from './file-size-limit-service.js';
|
|
20
21
|
export * from './font-loader/index.js';
|
|
22
|
+
export * from './frame-template-service.js';
|
|
21
23
|
export * from './generate-url-service.js';
|
|
22
24
|
export * from './keymap-override-service.js';
|
|
23
25
|
export * from './link-preview-service/index.js';
|
|
@@ -36,6 +38,7 @@ export * from './quick-search-service.js';
|
|
|
36
38
|
export * from './selection-pane-service.js';
|
|
37
39
|
export * from './telemetry-service/index.js';
|
|
38
40
|
export * from './theme-service.js';
|
|
41
|
+
export * from './thread-marks-service.js';
|
|
39
42
|
export * from './title-band-service.js';
|
|
40
43
|
export * from './toolbar-service/index.js';
|
|
41
44
|
export * from './translation-service/index.js';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export * from './artefact-catalogue-service.js';
|
|
2
|
+
export * from './asset-picker-service.js';
|
|
2
3
|
export * from './audit-service.js';
|
|
3
4
|
export * from './auto-clear-selection-service.js';
|
|
4
5
|
export * from './block-meta-service.js';
|
|
@@ -18,6 +19,7 @@ export * from './embed-option-service.js';
|
|
|
18
19
|
export * from './feature-flag-service.js';
|
|
19
20
|
export * from './file-size-limit-service.js';
|
|
20
21
|
export * from './font-loader/index.js';
|
|
22
|
+
export * from './frame-template-service.js';
|
|
21
23
|
export * from './generate-url-service.js';
|
|
22
24
|
export * from './keymap-override-service.js';
|
|
23
25
|
export * from './link-preview-service/index.js';
|
|
@@ -36,6 +38,7 @@ export * from './quick-search-service.js';
|
|
|
36
38
|
export * from './selection-pane-service.js';
|
|
37
39
|
export * from './telemetry-service/index.js';
|
|
38
40
|
export * from './theme-service.js';
|
|
41
|
+
export * from './thread-marks-service.js';
|
|
39
42
|
export * from './title-band-service.js';
|
|
40
43
|
export * from './toolbar-service/index.js';
|
|
41
44
|
export * from './translation-service/index.js';
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { ExtensionType } from '../../store/index.js';
|
|
2
|
+
import type { ReadonlySignal } from '@preact/signals-core';
|
|
3
|
+
/**
|
|
4
|
+
* What a mark sits on (ADR 0038): a block, in either view, or a canvas element
|
|
5
|
+
* no block backs (a shape, a connector, a group, a framework board). The id is
|
|
6
|
+
* the one the library already gives it: a block id, an element id.
|
|
7
|
+
*/
|
|
8
|
+
export type ThreadMarkTargetType = 'block' | 'element';
|
|
9
|
+
/**
|
|
10
|
+
* One marked target of the mounted document, as the host computes it. Ids and
|
|
11
|
+
* counters only: the library never learns what the host attaches to a target,
|
|
12
|
+
* who wrote it or what it says.
|
|
13
|
+
*
|
|
14
|
+
* `count` is how many the host has on that target (a mark at `0` or below is
|
|
15
|
+
* not drawn); `unread` turns the mark to the accent colour.
|
|
16
|
+
*/
|
|
17
|
+
export interface ThreadMark {
|
|
18
|
+
targetType: ThreadMarkTargetType;
|
|
19
|
+
targetId: string;
|
|
20
|
+
count: number;
|
|
21
|
+
unread: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* What the library hands the host when someone clicks a mark or "Discuss"
|
|
25
|
+
* (`com.labre.thread.discuss`) in a block or element toolbar.
|
|
26
|
+
*
|
|
27
|
+
* `excerpt` is computed here because the library knows the content: the
|
|
28
|
+
* block's text (its descendants' for a container such as a note), a canvas
|
|
29
|
+
* element's label as the selection pane reads it, else the kind of target.
|
|
30
|
+
* Whitespace is collapsed and it is cut to at most 280 characters, an
|
|
31
|
+
* ellipsis included (`THREAD_EXCERPT_MAX`). It is a snapshot for the host to
|
|
32
|
+
* store beside its anchor; the library keeps no copy.
|
|
33
|
+
*/
|
|
34
|
+
export interface ThreadOpenRequest {
|
|
35
|
+
docId: string;
|
|
36
|
+
targetType: ThreadMarkTargetType;
|
|
37
|
+
targetId: string;
|
|
38
|
+
excerpt: string;
|
|
39
|
+
}
|
|
40
|
+
/** The longest excerpt `openThread` is ever handed, in code points. */
|
|
41
|
+
export declare const THREAD_EXCERPT_MAX = 280;
|
|
42
|
+
/**
|
|
43
|
+
* The "has a thread" seam (ADR 0038): the host owns the discussions, the
|
|
44
|
+
* library marks what the host says is marked and asks the host to open one.
|
|
45
|
+
*
|
|
46
|
+
* Nothing is written to the document, ever: no prop, no id in the content, no
|
|
47
|
+
* write on load. That is why it is not `CommentProvider`, which writes
|
|
48
|
+
* `block.props.comments` and ignores canvas elements.
|
|
49
|
+
*
|
|
50
|
+
* Absent or `null`: no mark is drawn and no toolbar offers "Discuss".
|
|
51
|
+
*/
|
|
52
|
+
export interface ThreadMarksService {
|
|
53
|
+
/**
|
|
54
|
+
* The marks of the mounted document. Read reactively: a new array
|
|
55
|
+
* repaints the marks. An id the editor cannot find (a deleted block, an
|
|
56
|
+
* element of the other view) is ignored, never an error.
|
|
57
|
+
*/
|
|
58
|
+
marks$: ReadonlySignal<readonly ThreadMark[]>;
|
|
59
|
+
/** Open (or start) the discussion on a target. Writes nothing here. */
|
|
60
|
+
openThread(request: ThreadOpenRequest): void;
|
|
61
|
+
}
|
|
62
|
+
export declare const ThreadMarksProvider: import("../../global/di/types.js").ServiceIdentifier<ThreadMarksService> & (<U extends ThreadMarksService = ThreadMarksService>(variant: import("../../global/di/types.js").ServiceVariant) => import("../../global/di/types.js").ServiceIdentifier<U>);
|
|
63
|
+
/**
|
|
64
|
+
* Host seam: the host's thread marks, or `null` to say there are none.
|
|
65
|
+
*
|
|
66
|
+
* `di.override`, like every panel seam, so a later registration wins and
|
|
67
|
+
* registering twice never throws at boot.
|
|
68
|
+
*/
|
|
69
|
+
export declare function ThreadMarksExtension(service: ThreadMarksService | null): ExtensionType;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createIdentifier } from '../../global/di/index.js';
|
|
2
|
+
/** The longest excerpt `openThread` is ever handed, in code points. */
|
|
3
|
+
export const THREAD_EXCERPT_MAX = 280;
|
|
4
|
+
export const ThreadMarksProvider = createIdentifier('LabreThreadMarks');
|
|
5
|
+
/**
|
|
6
|
+
* Host seam: the host's thread marks, or `null` to say there are none.
|
|
7
|
+
*
|
|
8
|
+
* `di.override`, like every panel seam, so a later registration wins and
|
|
9
|
+
* registering twice never throws at boot.
|
|
10
|
+
*/
|
|
11
|
+
export function ThreadMarksExtension(service) {
|
|
12
|
+
return {
|
|
13
|
+
setup: di => {
|
|
14
|
+
// `null` rides through the factory on purpose: `getOptional` then
|
|
15
|
+
// reports the seam as absent, which is the whole "no mark, no button"
|
|
16
|
+
// story.
|
|
17
|
+
di.override(ThreadMarksProvider, () => service);
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|
|
@@ -509,6 +509,12 @@ export declare const TOOLBAR_INSERT_INTO_PAGE: ChromeWording;
|
|
|
509
509
|
* frame's. Was `GROUP_TOOLBAR_UNGROUP` (`gfx/group`).
|
|
510
510
|
*/
|
|
511
511
|
export declare const TOOLBAR_UNGROUP: ChromeWording;
|
|
512
|
+
/**
|
|
513
|
+
* "Save as template" — a database view's own menu entry, said identically by
|
|
514
|
+
* a frame's toolbar (`FrameTemplateProvider`). Was `VIEW_MENU_SAVE_TEMPLATE`
|
|
515
|
+
* (`database-editor`), whose key it keeps.
|
|
516
|
+
*/
|
|
517
|
+
export declare const SAVE_AS_TEMPLATE: ChromeWording;
|
|
512
518
|
/**
|
|
513
519
|
* "Mind Map" as chrome — the mindmap tool's own name (template-panel tab,
|
|
514
520
|
* senior/quick tool tooltips), said identically by the surface-ref slash
|
|
@@ -1100,6 +1100,15 @@ export const TOOLBAR_UNGROUP = [
|
|
|
1100
1100
|
'com.labre.group.toolbar.ungroup',
|
|
1101
1101
|
'Ungroup',
|
|
1102
1102
|
];
|
|
1103
|
+
/**
|
|
1104
|
+
* "Save as template" — a database view's own menu entry, said identically by
|
|
1105
|
+
* a frame's toolbar (`FrameTemplateProvider`). Was `VIEW_MENU_SAVE_TEMPLATE`
|
|
1106
|
+
* (`database-editor`), whose key it keeps.
|
|
1107
|
+
*/
|
|
1108
|
+
export const SAVE_AS_TEMPLATE = [
|
|
1109
|
+
'com.labre.database.view-menu.save-template',
|
|
1110
|
+
'Save as template',
|
|
1111
|
+
];
|
|
1103
1112
|
/**
|
|
1104
1113
|
* "Mind Map" as chrome — the mindmap tool's own name (template-panel tab,
|
|
1105
1114
|
* senior/quick tool tooltips), said identically by the surface-ref slash
|
|
@@ -1308,6 +1317,7 @@ export const CHROME_WORDINGS = [
|
|
|
1308
1317
|
IMAGE_LABEL,
|
|
1309
1318
|
TOOLBAR_INSERT_INTO_PAGE,
|
|
1310
1319
|
TOOLBAR_UNGROUP,
|
|
1320
|
+
SAVE_AS_TEMPLATE,
|
|
1311
1321
|
MINDMAP_NAME,
|
|
1312
1322
|
NEW_DOC_LABEL,
|
|
1313
1323
|
CATALOGUE_OTHER,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { EMBED_IFRAME_DEFAULT_HEIGHT_IN_SURFACE, EMBED_IFRAME_DEFAULT_WIDTH_IN_SURFACE, } from '../../affine-block-embed/index.js';
|
|
2
2
|
import { ParagraphBlockComponent } from '../../affine-block-paragraph/index.js';
|
|
3
3
|
import { DropIndicator } from '../../affine-components/drop-indicator/index.js';
|
|
4
|
-
import { AttachmentBlockModel, BookmarkBlockModel, DatabaseBlockModel, DEFAULT_NOTE_HEIGHT, DEFAULT_NOTE_WIDTH, ListBlockModel, NoteBlockModel, RootBlockModel, } from '../../affine-model/index.js';
|
|
4
|
+
import { AttachmentBlockModel, BookmarkBlockModel, DatabaseBlockModel, DEFAULT_NOTE_HEIGHT, DEFAULT_NOTE_WIDTH, ListBlockModel, NoteBlockModel, readImageCrop, RootBlockModel, } from '../../affine-model/index.js';
|
|
5
5
|
import { surfaceRefToEmbed } from '../../affine-shared/adapters/index.js';
|
|
6
6
|
import { BLOCK_CHILDREN_CONTAINER_PADDING_LEFT, EMBED_CARD_HEIGHT, EMBED_CARD_WIDTH, } from '../../affine-shared/consts/index.js';
|
|
7
7
|
import { DndApiExtensionIdentifier, DocModeProvider, EmbedIframeService, TelemetryProvider, } from '../../affine-shared/services/index.js';
|
|
@@ -721,8 +721,13 @@ export class DragEventWatcher {
|
|
|
721
721
|
}
|
|
722
722
|
if (block.flavour === 'affine:image') {
|
|
723
723
|
assertType(block.props);
|
|
724
|
-
|
|
725
|
-
|
|
724
|
+
// A page image's `width`/`height` are the WHOLE picture; on the
|
|
725
|
+
// canvas the box is the cropped window (ADR 0037).
|
|
726
|
+
const crop = readImageCrop(block.props.crop);
|
|
727
|
+
blockBound.w =
|
|
728
|
+
blockBound.w || block.props.width * (crop?.w ?? 1) || 100;
|
|
729
|
+
blockBound.h =
|
|
730
|
+
blockBound.h || block.props.height * (crop?.h ?? 1) || 100;
|
|
726
731
|
}
|
|
727
732
|
if (ignoreOriginalPos) {
|
|
728
733
|
blockBound.x = modelX;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { pickAndAddSiblingAttachmentBlocks } from '../affine-block-attachment/index.js';
|
|
2
2
|
import { insertDatabaseBlockCommand } from '../affine-block-database/index.js';
|
|
3
3
|
import { insertEmptyEmbedIframeCommand } from '../affine-block-embed/index.js';
|
|
4
4
|
import { insertImagesCommand } from '../affine-block-image/index.js';
|
|
@@ -16,7 +16,7 @@ import { formatBlockCommand, formatNativeCommand, formatTextCommand, getTextAttr
|
|
|
16
16
|
import { insertContent } from '../affine-rich-text/index.js';
|
|
17
17
|
import { copySelectedModelsCommand, deleteSelectedModelsCommand, draftSelectedModelsCommand, duplicateSelectedModelsCommand, getBlockSelectionsCommand, getSelectedModelsCommand, getTextSelectionCommand, } from '../affine-shared/commands/index.js';
|
|
18
18
|
import { REFERENCE_NODE } from '../affine-shared/consts/index.js';
|
|
19
|
-
import { createDefaultDoc
|
|
19
|
+
import { createDefaultDoc } from '../affine-shared/utils/index.js';
|
|
20
20
|
import { viewPresets } from '../data-view/view-presets/index.js';
|
|
21
21
|
import { assertType } from '../global/utils/index.js';
|
|
22
22
|
import { AttachmentIcon, BoldIcon, BulletedListIcon, CheckBoxCheckLinearIcon, CloseIcon, CodeBlockIcon, CodeIcon, CollapseTabIcon, CopyIcon, DatabaseKanbanViewIcon, DatabaseTableViewIcon, DeleteIcon, DividerIcon, DuplicateIcon, EmbedIcon, FontIcon, FrameIcon, GithubIcon, GroupIcon, ImageIcon, ItalicIcon, LinkedPageIcon, LinkIcon, LoomLogoIcon, NewPageIcon, NowIcon, NumberedListIcon, PlusIcon, QuoteIcon, RedoIcon, RightTabIcon, StrikeThroughIcon, TeXIcon, TextIcon, TodayIcon, TomorrowIcon, UnderLineIcon, UndoIcon, YesterdayIcon, YoutubeDuotoneIcon, } from '@blocksuite/icons/lit';
|
|
@@ -233,13 +233,7 @@ const contentMediaToolGroup = {
|
|
|
233
233
|
const model = selectedModels?.[0];
|
|
234
234
|
if (!model)
|
|
235
235
|
return;
|
|
236
|
-
|
|
237
|
-
if (!file)
|
|
238
|
-
return;
|
|
239
|
-
await addSiblingAttachmentBlocks(std, [file], model);
|
|
240
|
-
if (model.text?.length === 0) {
|
|
241
|
-
std.store.deleteBlock(model);
|
|
242
|
-
}
|
|
236
|
+
await pickAndAddSiblingAttachmentBlocks(std, model);
|
|
243
237
|
},
|
|
244
238
|
},
|
|
245
239
|
{
|
|
@@ -778,13 +772,7 @@ export const defaultKeyboardToolbarConfig = {
|
|
|
778
772
|
const model = selectedModels?.[0];
|
|
779
773
|
if (!model)
|
|
780
774
|
return;
|
|
781
|
-
|
|
782
|
-
if (!file)
|
|
783
|
-
return;
|
|
784
|
-
await addSiblingAttachmentBlocks(std, [file], model);
|
|
785
|
-
if (model.text?.length === 0) {
|
|
786
|
-
std.store.deleteBlock(model);
|
|
787
|
-
}
|
|
775
|
+
await pickAndAddSiblingAttachmentBlocks(std, model);
|
|
788
776
|
},
|
|
789
777
|
},
|
|
790
778
|
{
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ExtensionType, Schema, Store, Workspace } from '../../store/index.js';
|
|
2
|
+
import { type DocExportFile } from './utils.js';
|
|
2
3
|
type ImportHTMLToDocOptions = {
|
|
3
4
|
collection: Workspace;
|
|
4
5
|
schema: Schema;
|
|
@@ -12,6 +13,11 @@ type ImportHTMLZipOptions = {
|
|
|
12
13
|
imported: Blob;
|
|
13
14
|
extensions: ExtensionType[];
|
|
14
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* A doc as an HTML file, or as a zip of the HTML and its assets when it holds
|
|
18
|
+
* any — without downloading it. `null` when the doc has no snapshot.
|
|
19
|
+
*/
|
|
20
|
+
declare function docFile(doc: Store): Promise<DocExportFile | null>;
|
|
15
21
|
/**
|
|
16
22
|
* Exports a doc to HTML format.
|
|
17
23
|
*
|
|
@@ -41,6 +47,7 @@ declare function importHTMLToDoc({ collection, schema, html, fileName, extension
|
|
|
41
47
|
*/
|
|
42
48
|
declare function importHTMLZip({ collection, schema, imported, extensions, }: ImportHTMLZipOptions): Promise<string[]>;
|
|
43
49
|
export declare const HtmlTransformer: {
|
|
50
|
+
docFile: typeof docFile;
|
|
44
51
|
exportDoc: typeof exportDoc;
|
|
45
52
|
importHTMLToDoc: typeof importHTMLToDoc;
|
|
46
53
|
importHTMLZip: typeof importHTMLZip;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { defaultImageProxyMiddleware, docLinkBaseURLMiddleware, fileNameMiddleware, filePathMiddleware, HtmlAdapter, resolveWording, titleMiddleware, } from '../../affine-shared/adapters/index.js';
|
|
2
2
|
import { CHROME_UNTITLED } from '../../affine-shared/services/index.js';
|
|
3
|
+
import { safeFilename } from '../../affine-shared/utils/index.js';
|
|
3
4
|
import { Container } from '../../global/di/index.js';
|
|
4
5
|
import { sha } from '../../global/utils/index.js';
|
|
5
6
|
import { extMimeMap, Transformer } from '../../store/index.js';
|
|
6
|
-
import {
|
|
7
|
+
import { download, packDocExport, Unzip } from './utils.js';
|
|
7
8
|
function getProvider(extensions) {
|
|
8
9
|
const container = new Container();
|
|
9
10
|
extensions.forEach(ext => {
|
|
@@ -12,41 +13,40 @@ function getProvider(extensions) {
|
|
|
12
13
|
return container.provider();
|
|
13
14
|
}
|
|
14
15
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* @param doc - The doc to be exported.
|
|
18
|
-
* @returns A Promise that resolves when the export is complete.
|
|
16
|
+
* A doc as an HTML file, or as a zip of the HTML and its assets when it holds
|
|
17
|
+
* any — without downloading it. `null` when the doc has no snapshot.
|
|
19
18
|
*/
|
|
20
|
-
async function
|
|
19
|
+
async function docFile(doc) {
|
|
21
20
|
const provider = doc.provider;
|
|
22
21
|
const job = doc.getTransformer([
|
|
23
22
|
docLinkBaseURLMiddleware(doc.workspace.id),
|
|
24
23
|
titleMiddleware(doc.workspace.meta.docMetas),
|
|
25
24
|
]);
|
|
26
25
|
const snapshot = job.docToSnapshot(doc);
|
|
26
|
+
if (!snapshot)
|
|
27
|
+
return null;
|
|
27
28
|
const adapter = new HtmlAdapter(job, provider);
|
|
28
|
-
if (!snapshot) {
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
29
|
const htmlResult = await adapter.fromDocSnapshot({
|
|
32
30
|
snapshot,
|
|
33
31
|
assets: job.assetsManager,
|
|
34
32
|
});
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
33
|
+
const untitled = resolveWording(provider, CHROME_UNTITLED);
|
|
34
|
+
return packDocExport(htmlResult, job.assets, {
|
|
35
|
+
name: safeFilename(doc.meta?.title, untitled),
|
|
36
|
+
extension: '.html',
|
|
37
|
+
mime: 'text/html;charset=utf-8',
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Exports a doc to HTML format.
|
|
42
|
+
*
|
|
43
|
+
* @param doc - The doc to be exported.
|
|
44
|
+
* @returns A Promise that resolves when the export is complete.
|
|
45
|
+
*/
|
|
46
|
+
async function exportDoc(doc) {
|
|
47
|
+
const file = await docFile(doc);
|
|
48
|
+
if (file)
|
|
49
|
+
download(file.blob, file.filename);
|
|
50
50
|
}
|
|
51
51
|
/**
|
|
52
52
|
* Imports HTML content into a new doc within a collection.
|
|
@@ -160,6 +160,7 @@ async function importHTMLZip({ collection, schema, imported, extensions, }) {
|
|
|
160
160
|
return docIds;
|
|
161
161
|
}
|
|
162
162
|
export const HtmlTransformer = {
|
|
163
|
+
docFile,
|
|
163
164
|
exportDoc,
|
|
164
165
|
importHTMLToDoc,
|
|
165
166
|
importHTMLZip,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { HtmlTransformer } from './html.js';
|
|
2
2
|
export { MarkdownTransformer } from './markdown.js';
|
|
3
3
|
export { NotionHtmlTransformer } from './notion-html.js';
|
|
4
|
-
export { createAssetsArchive, download } from './utils.js';
|
|
4
|
+
export { createAssetsArchive, type DocExportFile, download } from './utils.js';
|
|
5
5
|
export { ZipTransformer } from './zip.js';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { DocMeta, ExtensionType, Schema, Store, Workspace } from '../../store/index.js';
|
|
2
|
+
import { type DocExportFile } from './utils.js';
|
|
2
3
|
type ParsedFrontmatterMeta = Partial<Pick<DocMeta, 'title' | 'createDate' | 'updatedDate' | 'tags' | 'favorite'>>;
|
|
3
4
|
/**
|
|
4
5
|
* Read the frontmatter off a markdown file and hand back the content without
|
|
@@ -27,6 +28,11 @@ type ImportMarkdownZipOptions = {
|
|
|
27
28
|
imported: Blob;
|
|
28
29
|
extensions: ExtensionType[];
|
|
29
30
|
};
|
|
31
|
+
/**
|
|
32
|
+
* A doc as a Markdown file, or as a zip of the Markdown and its assets when it
|
|
33
|
+
* holds any — without downloading it. `null` when the doc has no snapshot.
|
|
34
|
+
*/
|
|
35
|
+
declare function docFile(doc: Store): Promise<DocExportFile | null>;
|
|
30
36
|
/**
|
|
31
37
|
* Exports a doc to a Markdown file or a zip archive containing Markdown and assets.
|
|
32
38
|
* @param doc The doc to export
|
|
@@ -62,6 +68,7 @@ declare function importMarkdownToDoc({ collection, schema, markdown, fileName, e
|
|
|
62
68
|
*/
|
|
63
69
|
declare function importMarkdownZip({ collection, schema, imported, extensions, }: ImportMarkdownZipOptions): Promise<string[]>;
|
|
64
70
|
export declare const MarkdownTransformer: {
|
|
71
|
+
docFile: typeof docFile;
|
|
65
72
|
exportDoc: typeof exportDoc;
|
|
66
73
|
importMarkdownToBlock: typeof importMarkdownToBlock;
|
|
67
74
|
importMarkdownToDoc: typeof importMarkdownToDoc;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { defaultImageProxyMiddleware, docLinkBaseURLMiddleware, fileNameMiddleware, filePathMiddleware, MarkdownAdapter, resolveWording, titleMiddleware, } from '../../affine-shared/adapters/index.js';
|
|
2
2
|
import { CHROME_UNTITLED } from '../../affine-shared/services/index.js';
|
|
3
|
+
import { safeFilename } from '../../affine-shared/utils/index.js';
|
|
3
4
|
import { Container } from '../../global/di/index.js';
|
|
4
5
|
import { BlockSuiteError, ErrorCode } from '../../global/exceptions/index.js';
|
|
5
6
|
import { sha } from '../../global/utils/index.js';
|
|
6
7
|
import { extMimeMap, Transformer } from '../../store/index.js';
|
|
7
|
-
import {
|
|
8
|
+
import { download, packDocExport, parseMatter, Unzip, } from './utils.js';
|
|
8
9
|
/**
|
|
9
10
|
* The spellings the tools people export markdown from actually use. Anything
|
|
10
11
|
* else in the frontmatter is metadata we have no field for, and is dropped.
|
|
@@ -137,43 +138,42 @@ function getProvider(extensions) {
|
|
|
137
138
|
return container.provider();
|
|
138
139
|
}
|
|
139
140
|
/**
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
* @returns A Promise that resolves when the export is complete
|
|
141
|
+
* A doc as a Markdown file, or as a zip of the Markdown and its assets when it
|
|
142
|
+
* holds any — without downloading it. `null` when the doc has no snapshot.
|
|
143
143
|
*/
|
|
144
|
-
async function
|
|
144
|
+
async function docFile(doc) {
|
|
145
145
|
const provider = doc.provider;
|
|
146
146
|
const job = doc.getTransformer([
|
|
147
147
|
docLinkBaseURLMiddleware(doc.workspace.id),
|
|
148
148
|
titleMiddleware(doc.workspace.meta.docMetas),
|
|
149
149
|
]);
|
|
150
150
|
const snapshot = job.docToSnapshot(doc);
|
|
151
|
+
if (!snapshot)
|
|
152
|
+
return null;
|
|
151
153
|
const adapter = new MarkdownAdapter(job, provider);
|
|
152
|
-
if (!snapshot) {
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
154
|
const markdownResult = await adapter.fromDocSnapshot({
|
|
156
155
|
snapshot,
|
|
157
156
|
assets: job.assetsManager,
|
|
158
157
|
});
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
let name;
|
|
162
|
-
const contentBlob = new Blob([markdownResult.file], { type: 'plain/text' });
|
|
163
|
-
if (markdownResult.assetsIds.length > 0) {
|
|
164
|
-
if (!job.assets) {
|
|
165
|
-
throw new BlockSuiteError(ErrorCode.ValueNotExists, 'No assets found');
|
|
166
|
-
}
|
|
167
|
-
const zip = await createAssetsArchive(job.assets, markdownResult.assetsIds);
|
|
168
|
-
await zip.file('index.md', contentBlob);
|
|
169
|
-
downloadBlob = await zip.generate();
|
|
170
|
-
name = `${docTitle}.zip`;
|
|
171
|
-
}
|
|
172
|
-
else {
|
|
173
|
-
downloadBlob = contentBlob;
|
|
174
|
-
name = `${docTitle}.md`;
|
|
158
|
+
if (markdownResult.assetsIds.length > 0 && !job.assets) {
|
|
159
|
+
throw new BlockSuiteError(ErrorCode.ValueNotExists, 'No assets found');
|
|
175
160
|
}
|
|
176
|
-
|
|
161
|
+
const untitled = resolveWording(provider, CHROME_UNTITLED);
|
|
162
|
+
return packDocExport(markdownResult, job.assets, {
|
|
163
|
+
name: safeFilename(doc.meta?.title, untitled),
|
|
164
|
+
extension: '.md',
|
|
165
|
+
mime: 'text/markdown;charset=utf-8',
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Exports a doc to a Markdown file or a zip archive containing Markdown and assets.
|
|
170
|
+
* @param doc The doc to export
|
|
171
|
+
* @returns A Promise that resolves when the export is complete
|
|
172
|
+
*/
|
|
173
|
+
async function exportDoc(doc) {
|
|
174
|
+
const file = await docFile(doc);
|
|
175
|
+
if (file)
|
|
176
|
+
download(file.blob, file.filename);
|
|
177
177
|
}
|
|
178
178
|
/**
|
|
179
179
|
* Imports Markdown content into a specific block within a doc.
|
|
@@ -328,6 +328,7 @@ async function importMarkdownZip({ collection, schema, imported, extensions, })
|
|
|
328
328
|
return docIds;
|
|
329
329
|
}
|
|
330
330
|
export const MarkdownTransformer = {
|
|
331
|
+
docFile,
|
|
331
332
|
exportDoc,
|
|
332
333
|
importMarkdownToBlock,
|
|
333
334
|
importMarkdownToDoc,
|
|
@@ -32,3 +32,26 @@ export declare const parseMatter: (contents: string) => {
|
|
|
32
32
|
metadata: Record<string, FrontmatterValue>;
|
|
33
33
|
} | null;
|
|
34
34
|
export declare function download(blob: Blob, name: string): void;
|
|
35
|
+
/**
|
|
36
|
+
* A page exported to a file, before anything is done with it: the bytes and
|
|
37
|
+
* the name a download would give them. What `exportDoc` downloads, and what
|
|
38
|
+
* the `page.export.*` view actions hand to the host instead.
|
|
39
|
+
*/
|
|
40
|
+
export interface DocExportFile {
|
|
41
|
+
blob: Blob;
|
|
42
|
+
/** Sanitised, extension included: `Order to cash.md` or `Order to cash.zip`. */
|
|
43
|
+
filename: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Pack an adapter's output: the document alone when it references no asset,
|
|
47
|
+
* else a zip holding it as `index.<ext>` beside an `assets/` folder — the
|
|
48
|
+
* relative paths the Markdown and HTML adapters write for images point there.
|
|
49
|
+
*/
|
|
50
|
+
export declare function packDocExport(result: {
|
|
51
|
+
file: string;
|
|
52
|
+
assetsIds: string[];
|
|
53
|
+
}, assets: Map<string, Blob>, { name, extension, mime }: {
|
|
54
|
+
name: string;
|
|
55
|
+
extension: string;
|
|
56
|
+
mime: string;
|
|
57
|
+
}): Promise<DocExportFile>;
|
|
@@ -214,3 +214,17 @@ export function download(blob, name) {
|
|
|
214
214
|
element.remove();
|
|
215
215
|
URL.revokeObjectURL(fileURL);
|
|
216
216
|
}
|
|
217
|
+
/**
|
|
218
|
+
* Pack an adapter's output: the document alone when it references no asset,
|
|
219
|
+
* else a zip holding it as `index.<ext>` beside an `assets/` folder — the
|
|
220
|
+
* relative paths the Markdown and HTML adapters write for images point there.
|
|
221
|
+
*/
|
|
222
|
+
export async function packDocExport(result, assets, { name, extension, mime }) {
|
|
223
|
+
const content = new Blob([result.file], { type: mime });
|
|
224
|
+
if (result.assetsIds.length === 0) {
|
|
225
|
+
return { blob: content, filename: `${name}${extension}` };
|
|
226
|
+
}
|
|
227
|
+
const zip = await createAssetsArchive(assets, result.assetsIds);
|
|
228
|
+
await zip.file(`index${extension}`, content);
|
|
229
|
+
return { blob: await zip.generate(), filename: `${name}.zip` };
|
|
230
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function effects(): void;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type ThreadMarkTargetType } from '../affine-shared/services/index.js';
|
|
2
|
+
import type { BlockStdScope } from '../std/index.js';
|
|
3
|
+
/** A block or a canvas element, by the id the library gave it. */
|
|
4
|
+
export interface ThreadTarget {
|
|
5
|
+
targetType: ThreadMarkTargetType;
|
|
6
|
+
targetId: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Collapse whitespace and cut to {@link THREAD_EXCERPT_MAX} code points, the
|
|
10
|
+
* ellipsis included. Code points, not UTF-16 units, so an emoji is never cut
|
|
11
|
+
* in half and a host counting characters (Postgres `char_length`) agrees.
|
|
12
|
+
*/
|
|
13
|
+
export declare function truncateThreadExcerpt(raw: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* The excerpt handed to `openThread` (ADR 0038): what the target says, as a
|
|
16
|
+
* reader would recognise it, at most {@link THREAD_EXCERPT_MAX} characters.
|
|
17
|
+
* Read only: nothing is written, nothing is cached.
|
|
18
|
+
*/
|
|
19
|
+
export declare function threadExcerpt(std: BlockStdScope, target: ThreadTarget): string;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { getSurfaceBlock } from '../affine-block-surface/index.js';
|
|
2
|
+
import { THREAD_EXCERPT_MAX, } from '../affine-shared/services/index.js';
|
|
3
|
+
import { selectionPaneRowLabel, selectionPaneTypeLabel, } from '../affine-widget-edgeless-toolbar/index.js';
|
|
4
|
+
import { GfxBlockElementModel } from '../std/gfx/index.js';
|
|
5
|
+
const ELLIPSIS = '…';
|
|
6
|
+
/**
|
|
7
|
+
* Collapse whitespace and cut to {@link THREAD_EXCERPT_MAX} code points, the
|
|
8
|
+
* ellipsis included. Code points, not UTF-16 units, so an emoji is never cut
|
|
9
|
+
* in half and a host counting characters (Postgres `char_length`) agrees.
|
|
10
|
+
*/
|
|
11
|
+
export function truncateThreadExcerpt(raw) {
|
|
12
|
+
const text = raw.replace(/\s+/g, ' ').trim();
|
|
13
|
+
const chars = Array.from(text);
|
|
14
|
+
if (chars.length <= THREAD_EXCERPT_MAX)
|
|
15
|
+
return text;
|
|
16
|
+
return (chars
|
|
17
|
+
.slice(0, THREAD_EXCERPT_MAX - 1)
|
|
18
|
+
.join('')
|
|
19
|
+
.trimEnd() + ELLIPSIS);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* A block's own text, then its descendants' in document order (a note, a
|
|
23
|
+
* callout, a list item with children), until there is more than an excerpt
|
|
24
|
+
* can hold.
|
|
25
|
+
*/
|
|
26
|
+
function blockText(model) {
|
|
27
|
+
const parts = [];
|
|
28
|
+
let length = 0;
|
|
29
|
+
const visit = (block) => {
|
|
30
|
+
if (length > THREAD_EXCERPT_MAX)
|
|
31
|
+
return;
|
|
32
|
+
const own = block.text?.toString() ?? '';
|
|
33
|
+
if (own.trim()) {
|
|
34
|
+
parts.push(own);
|
|
35
|
+
length += own.length + 1;
|
|
36
|
+
}
|
|
37
|
+
for (const child of block.children)
|
|
38
|
+
visit(child);
|
|
39
|
+
};
|
|
40
|
+
visit(model);
|
|
41
|
+
return parts.join(' ');
|
|
42
|
+
}
|
|
43
|
+
function rawExcerpt(std, target) {
|
|
44
|
+
if (target.targetType === 'block') {
|
|
45
|
+
const model = std.store.getModelById(target.targetId);
|
|
46
|
+
if (!model)
|
|
47
|
+
return '';
|
|
48
|
+
const text = blockText(model);
|
|
49
|
+
if (text.trim())
|
|
50
|
+
return text;
|
|
51
|
+
// A canvas block with no text reads as the selection pane names it: a
|
|
52
|
+
// frame by its title, an image or a note by its kind.
|
|
53
|
+
if (model instanceof GfxBlockElementModel) {
|
|
54
|
+
return selectionPaneRowLabel(std, model);
|
|
55
|
+
}
|
|
56
|
+
return selectionPaneTypeLabel(std, model.flavour);
|
|
57
|
+
}
|
|
58
|
+
const element = getSurfaceBlock(std.store)?.getElementById(target.targetId);
|
|
59
|
+
return element ? selectionPaneRowLabel(std, element) : '';
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The excerpt handed to `openThread` (ADR 0038): what the target says, as a
|
|
63
|
+
* reader would recognise it, at most {@link THREAD_EXCERPT_MAX} characters.
|
|
64
|
+
* Read only: nothing is written, nothing is cached.
|
|
65
|
+
*/
|
|
66
|
+
export function threadExcerpt(std, target) {
|
|
67
|
+
return truncateThreadExcerpt(rawExcerpt(std, target));
|
|
68
|
+
}
|