@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
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { ExportToPdfIcon, ExportToPngIcon, GridIcon, } from '@blocksuite/icons/lit';
|
|
1
|
+
import { ExportIcon, ExportToPdfIcon, ExportToPngIcon, ExportToSvgIcon, GridIcon, } from '@blocksuite/icons/lit';
|
|
2
2
|
import { ViewExtensionProvider, } from '../affine-ext-loader/index.js';
|
|
3
3
|
import { CanvasGrid, CanvasLocalVisibility, } from '../affine-shared/services/index.js';
|
|
4
4
|
import { BlockViewExtension, CommandExtension, FlavourExtension, } from '../std/index.js';
|
|
5
5
|
import { literal } from 'lit/static-html.js';
|
|
6
6
|
import { effects } from './effects.js';
|
|
7
|
-
import { auditCommands, CanvasActiveLayer, canvasExportCommands, canvasGridCommands, EdgelessCRUDExtension, EdgelessLegacySlotExtension, EditPropsMiddlewareBuilder, exportSvgCommands, exportSvgToolbarExtension, mapQualityCommands, mapQualityWidget, ReadingManager, readingProposalWidget, readingToolbarExtension, selectionPaneCommands, SelectionPaneModel, SpotlightManager, UserLayerMiddlewareBuilder, userLayerCommands, ValidationManager, validationExceptionToolbarExtension, ValidationOverlay, violationDetailWidget, } from './extensions/index.js';
|
|
7
|
+
import { auditCommands, CanvasActiveLayer, canvasDrawioExportCommands, canvasExportCommands, CANVAS_INTERCHANGE, canvasGridCommands, canvasSvgExportCommands, EdgelessCRUDExtension, EdgelessLegacySlotExtension, EditPropsMiddlewareBuilder, exportSvgCommands, INTERCHANGE_EXPORT_ICON_KEY, InterchangeExtension, exportSvgToolbarExtension, mapQualityCommands, mapQualityWidget, ReadingManager, readingProposalWidget, readingToolbarExtension, selectionPaneCommands, SelectionPaneModel, SpotlightManager, UserLayerMiddlewareBuilder, userLayerCommands, ValidationManager, validationExceptionToolbarExtension, ValidationOverlay, violationDetailWidget, } from './extensions/index.js';
|
|
8
8
|
import { ExportManagerExtension } from './extensions/export-manager/export-manager.js';
|
|
9
9
|
import { BackgroundStackingExtension } from './framework-background/stacking.js';
|
|
10
10
|
import { ElementHighlightOverlay } from './renderer/element-highlight-overlay.js';
|
|
@@ -97,6 +97,26 @@ export class SurfaceViewExtension extends ViewExtensionProvider {
|
|
|
97
97
|
'canvas.export.png': ExportToPngIcon(),
|
|
98
98
|
'canvas.export.pdf': ExportToPdfIcon(),
|
|
99
99
|
}));
|
|
100
|
+
// The canvas as a draw.io drawing (ADR 0019, amendment of 2026-10-14):
|
|
101
|
+
// the third "This view" export, and the registry's one capability no
|
|
102
|
+
// framework owns. Never gated, for the PNG's reason — it writes what the
|
|
103
|
+
// canvas paints, whatever drew it — so with every framework off the
|
|
104
|
+
// registry still answers `canvas:drawio:export`.
|
|
105
|
+
context.register(InterchangeExtension(CANVAS_INTERCHANGE));
|
|
106
|
+
context.register(CommandExtension(canvasDrawioExportCommands, {
|
|
107
|
+
'canvas.export.drawio': ExportIcon(),
|
|
108
|
+
// The icon of the view actions derived from the frameworks'
|
|
109
|
+
// `*:export` capabilities (`interchange-export.ts`): they are
|
|
110
|
+
// listed by the host façade, never registered as commands, so their
|
|
111
|
+
// one icon rides on this table.
|
|
112
|
+
[INTERCHANGE_EXPORT_ICON_KEY]: ExportIcon(),
|
|
113
|
+
}));
|
|
114
|
+
// The whole canvas as SVG (ADR 0034, amendment of 2026-10-14): the
|
|
115
|
+
// renderer replay of `export.svg`, over everything this viewer sees.
|
|
116
|
+
// Never gated, for the PNG's reason.
|
|
117
|
+
context.register(CommandExtension(canvasSvgExportCommands, {
|
|
118
|
+
'canvas.export.svg': ExportToSvgIcon(),
|
|
119
|
+
}));
|
|
100
120
|
// User layers (ADR 0031 §2-§6): the viewer's active layer (session
|
|
101
121
|
// only), the `beforeAdd` middleware that stamps it on what is created,
|
|
102
122
|
// and the commands the pane's layer rows run. Content, never gated.
|
|
@@ -130,12 +130,35 @@ export const parseTableFromHtml = (element, astToDelta) => {
|
|
|
130
130
|
});
|
|
131
131
|
return createTableProps(rowTextLists);
|
|
132
132
|
};
|
|
133
|
+
/**
|
|
134
|
+
* A cell holds rich text, and no inline matcher turns an `image` into a delta:
|
|
135
|
+
* `` in a pasted Markdown table used to vanish from its cell. It is
|
|
136
|
+
* kept as a link named by its alt text (its URL when it has none), so nothing
|
|
137
|
+
* of the source is lost; the link matcher still refuses an unsafe scheme and
|
|
138
|
+
* keeps the words (labre REQ-IM-2, "no data loss").
|
|
139
|
+
*/
|
|
140
|
+
function imagesAsLinks(node) {
|
|
141
|
+
if (node.type === 'image') {
|
|
142
|
+
return {
|
|
143
|
+
type: 'link',
|
|
144
|
+
url: node.url,
|
|
145
|
+
title: node.title,
|
|
146
|
+
children: [{ type: 'text', value: node.alt || node.url }],
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
if (!('children' in node))
|
|
150
|
+
return node;
|
|
151
|
+
return {
|
|
152
|
+
...node,
|
|
153
|
+
children: node.children.map(child => imagesAsLinks(child)),
|
|
154
|
+
};
|
|
155
|
+
}
|
|
133
156
|
export const parseTableFromMarkdown = (node, astToDelta) => {
|
|
134
157
|
const rowTextLists = [];
|
|
135
158
|
node.children.forEach(row => {
|
|
136
159
|
const rowText = [];
|
|
137
160
|
row.children.forEach(cell => {
|
|
138
|
-
rowText.push(astToDelta(cell));
|
|
161
|
+
rowText.push(astToDelta(imagesAsLinks(cell)));
|
|
139
162
|
});
|
|
140
163
|
rowTextLists.push(rowText);
|
|
141
164
|
});
|
|
@@ -32,13 +32,12 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
|
|
|
32
32
|
}
|
|
33
33
|
return useValue ? value : void 0;
|
|
34
34
|
};
|
|
35
|
-
import {
|
|
35
|
+
import { pickAndAddAttachments } from '../../affine-block-attachment/index.js';
|
|
36
36
|
import { insertLinkByQuickSearchCommand } from '../../affine-block-bookmark/index.js';
|
|
37
|
-
import {
|
|
37
|
+
import { pickAndAddImages } from '../../affine-block-image/index.js';
|
|
38
38
|
import { DefaultTool } from '../../affine-block-surface/index.js';
|
|
39
39
|
import { MAX_IMAGE_WIDTH } from '../../affine-model/index.js';
|
|
40
40
|
import { TelemetryProvider, translateKey } from '../../affine-shared/services/index.js';
|
|
41
|
-
import { getImageFilesFromLocal, openSingleFileWith, } from '../../affine-shared/utils/index.js';
|
|
42
41
|
import { EdgelessToolbarToolMixin } from '../../affine-widget-edgeless-toolbar/index.js';
|
|
43
42
|
import { AttachmentIcon, ImageIcon, LinkIcon } from '@blocksuite/icons/lit';
|
|
44
43
|
import { effect } from '@preact/signals-core';
|
|
@@ -112,8 +111,7 @@ let EdgelessNoteMenu = (() => {
|
|
|
112
111
|
`; }
|
|
113
112
|
async _addImages() {
|
|
114
113
|
this._imageLoading = true;
|
|
115
|
-
const
|
|
116
|
-
const ids = await addImages(this.edgeless.std, imageFiles, {
|
|
114
|
+
const ids = await pickAndAddImages(this.edgeless.std, {
|
|
117
115
|
maxWidth: MAX_IMAGE_WIDTH,
|
|
118
116
|
});
|
|
119
117
|
this._imageLoading = false;
|
|
@@ -185,10 +183,9 @@ let EdgelessNoteMenu = (() => {
|
|
|
185
183
|
.activeMode=${'background'}
|
|
186
184
|
.tooltip=${translateKey(this.edgeless.std, ...GFX_NOTE_MENU_FILE)}
|
|
187
185
|
@click=${async () => {
|
|
188
|
-
const
|
|
189
|
-
if (!
|
|
186
|
+
const ids = await pickAndAddAttachments(this.edgeless.std);
|
|
187
|
+
if (!ids.length)
|
|
190
188
|
return;
|
|
191
|
-
await addAttachments(this.edgeless.std, [file]);
|
|
192
189
|
this.gfx.tool.setTool(DefaultTool);
|
|
193
190
|
this.edgeless.std
|
|
194
191
|
.getOptional(TelemetryProvider)
|
|
@@ -26,9 +26,19 @@ export declare const TemplateCategoryIdentifier: import("../global/di/types.js")
|
|
|
26
26
|
*/
|
|
27
27
|
export declare function TemplateCategoryExtension(...categories: TemplateCategory[]): ExtensionType;
|
|
28
28
|
/**
|
|
29
|
-
* The
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
|
|
29
|
+
* The identity of the host's category of saved frames (the
|
|
30
|
+
* `FrameTemplateProvider` seam): the stable name the panel remembers and
|
|
31
|
+
* lists by. Its tab reads {@link TEMPLATE_PANEL_CATEGORY_SAVED_FRAMES}.
|
|
32
|
+
*/
|
|
33
|
+
export declare const SAVED_FRAMES_CATEGORY = "Saved frames";
|
|
34
|
+
/**
|
|
35
|
+
* The catalogue ONE editor sees: the built-in `Other`, then the categories
|
|
36
|
+
* the view extensions mounted on this `std` registered — i.e. exactly the
|
|
37
|
+
* frameworks whose tooling is on — then the host's saved frames, when a
|
|
38
|
+
* host keeps them (`FrameTemplateProvider`).
|
|
39
|
+
*
|
|
40
|
+
* Per editor, from its DI container: the module-level `extend(...)` of
|
|
41
|
+
* 0.49 and earlier, which appended for every editor and was never emptied,
|
|
42
|
+
* is gone (a host category is a `TemplateCategoryExtension`).
|
|
33
43
|
*/
|
|
34
44
|
export declare function templateManagerFor(std: BlockStdScope): TemplateManager;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { FrameTemplateProvider, } from '../affine-shared/services/index.js';
|
|
1
2
|
import { createIdentifier } from '../global/di/index.js';
|
|
2
3
|
import { builtInTemplates } from './toolbar/builtin-templates.js';
|
|
3
4
|
import { resolveTemplateName } from './toolbar/resolve-name.js';
|
|
5
|
+
import { TEMPLATE_PANEL_CATEGORY_SAVED_FRAMES } from './translations.js';
|
|
4
6
|
/**
|
|
5
7
|
* A framework registers its Templates-panel categories here; the panel reads
|
|
6
8
|
* them back from the std of the edgeless it opens on. One identifier per
|
|
@@ -33,20 +35,61 @@ export function TemplateCategoryExtension(...categories) {
|
|
|
33
35
|
},
|
|
34
36
|
};
|
|
35
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* The identity of the host's category of saved frames (the
|
|
40
|
+
* `FrameTemplateProvider` seam): the stable name the panel remembers and
|
|
41
|
+
* lists by. Its tab reads {@link TEMPLATE_PANEL_CATEGORY_SAVED_FRAMES}.
|
|
42
|
+
*/
|
|
43
|
+
export const SAVED_FRAMES_CATEGORY = 'Saved frames';
|
|
44
|
+
function savedFrameTemplate(service, saved) {
|
|
45
|
+
return {
|
|
46
|
+
name: saved.title,
|
|
47
|
+
type: 'template',
|
|
48
|
+
content: saved.snapshot,
|
|
49
|
+
preview: saved.preview,
|
|
50
|
+
// The panel runs `afterInsert` only once the template job has resolved.
|
|
51
|
+
afterInsert: service.frameInserted
|
|
52
|
+
? std => service.frameInserted?.({
|
|
53
|
+
docId: std.store.id,
|
|
54
|
+
templateId: saved.id,
|
|
55
|
+
})
|
|
56
|
+
: undefined,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The host's saved frames as a category, or none without a host. Lazy: the
|
|
61
|
+
* host is asked only when the panel shows the tab or searches across tabs.
|
|
62
|
+
*/
|
|
63
|
+
function savedFramesCategory(std) {
|
|
64
|
+
const service = std.provider.getOptional(FrameTemplateProvider);
|
|
65
|
+
if (!service)
|
|
66
|
+
return null;
|
|
67
|
+
return {
|
|
68
|
+
name: SAVED_FRAMES_CATEGORY,
|
|
69
|
+
nameKey: TEMPLATE_PANEL_CATEGORY_SAVED_FRAMES[0],
|
|
70
|
+
templates: async () => (await service.list()).map(saved => savedFrameTemplate(service, saved)),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
36
73
|
function loadCategory(category) {
|
|
37
74
|
return Array.isArray(category.templates)
|
|
38
75
|
? Promise.resolve(category.templates)
|
|
39
76
|
: category.templates();
|
|
40
77
|
}
|
|
41
78
|
/**
|
|
42
|
-
* The catalogue ONE editor sees: the built-in
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
79
|
+
* The catalogue ONE editor sees: the built-in `Other`, then the categories
|
|
80
|
+
* the view extensions mounted on this `std` registered — i.e. exactly the
|
|
81
|
+
* frameworks whose tooling is on — then the host's saved frames, when a
|
|
82
|
+
* host keeps them (`FrameTemplateProvider`).
|
|
83
|
+
*
|
|
84
|
+
* Per editor, from its DI container: the module-level `extend(...)` of
|
|
85
|
+
* 0.49 and earlier, which appended for every editor and was never emptied,
|
|
86
|
+
* is gone (a host category is a `TemplateCategoryExtension`).
|
|
46
87
|
*/
|
|
47
88
|
export function templateManagerFor(std) {
|
|
89
|
+
const saved = savedFramesCategory(std);
|
|
48
90
|
const contributed = [
|
|
49
91
|
...std.provider.getAll(TemplateCategoryIdentifier).values(),
|
|
92
|
+
...(saved ? [saved] : []),
|
|
50
93
|
];
|
|
51
94
|
const byName = (name) => contributed.find(c => c.name === name);
|
|
52
95
|
return {
|
|
@@ -57,8 +100,6 @@ export function templateManagerFor(std) {
|
|
|
57
100
|
]),
|
|
58
101
|
],
|
|
59
102
|
categoryLabel: name => byName(name)?.nameKey ?? builtInTemplates.categoryLabel(name),
|
|
60
|
-
// Both halves, so a host's `extend(...)` can still append to a framework's
|
|
61
|
-
// own category (the global half answers `[]` for a name it does not know).
|
|
62
103
|
list: async (name) => {
|
|
63
104
|
const category = byName(name);
|
|
64
105
|
return [
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import type { Template, TemplateCategory
|
|
1
|
+
import type { Template, TemplateCategory } from './template-type.js';
|
|
2
2
|
export declare const templates: TemplateCategory[];
|
|
3
|
+
/**
|
|
4
|
+
* The catalogue every editor has, whatever is mounted: `Other`. A host or a
|
|
5
|
+
* framework adds a category per editor with `TemplateCategoryExtension`; the
|
|
6
|
+
* module-level `extend(...)` this object carried until 0.49 appended for every
|
|
7
|
+
* editor of the page and was never emptied.
|
|
8
|
+
*/
|
|
3
9
|
export declare const builtInTemplates: {
|
|
4
10
|
list: (category: string) => Promise<Template[]>;
|
|
5
11
|
categories: () => Promise<string[]>;
|
|
6
12
|
categoryLabel: (name: string) => string | undefined;
|
|
7
13
|
search: (keyword: string, cateName?: string) => Promise<Template[]>;
|
|
8
|
-
extend(manager: TemplateManager): void;
|
|
9
14
|
};
|
|
@@ -16,48 +16,27 @@ function lcs(text1, text2) {
|
|
|
16
16
|
}
|
|
17
17
|
return dp[text1.length][text2.length];
|
|
18
18
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}, []);
|
|
19
|
+
/**
|
|
20
|
+
* The catalogue every editor has, whatever is mounted: `Other`. A host or a
|
|
21
|
+
* framework adds a category per editor with `TemplateCategoryExtension`; the
|
|
22
|
+
* module-level `extend(...)` this object carried until 0.49 appended for every
|
|
23
|
+
* editor of the page and was never emptied.
|
|
24
|
+
*/
|
|
26
25
|
export const builtInTemplates = {
|
|
27
26
|
list: async (category) => {
|
|
28
|
-
const extendTemplates = flat(await Promise.all(extendTemplate.map(manager => manager.list(category))));
|
|
29
|
-
// eslint-disable-next-line sonarjs/no-empty-collection
|
|
30
27
|
const cate = templates.find(cate => cate.name === category);
|
|
31
28
|
if (!cate)
|
|
32
|
-
return
|
|
33
|
-
|
|
34
|
-
?
|
|
35
|
-
:
|
|
36
|
-
return result.concat(extendTemplates);
|
|
37
|
-
},
|
|
38
|
-
categories: async () => {
|
|
39
|
-
const extendCates = flat(await Promise.all(extendTemplate.map(manager => manager.categories())));
|
|
40
|
-
// eslint-disable-next-line sonarjs/no-empty-collection
|
|
41
|
-
return templates.map(cate => cate.name).concat(extendCates);
|
|
42
|
-
},
|
|
43
|
-
categoryLabel: (name) => {
|
|
44
|
-
// eslint-disable-next-line sonarjs/no-empty-collection
|
|
45
|
-
const own = templates.find(cate => cate.name === name)?.nameKey;
|
|
46
|
-
if (own)
|
|
47
|
-
return own;
|
|
48
|
-
for (const manager of extendTemplate) {
|
|
49
|
-
const key = manager.categoryLabel?.(name);
|
|
50
|
-
if (key)
|
|
51
|
-
return key;
|
|
52
|
-
}
|
|
53
|
-
return undefined;
|
|
29
|
+
return [];
|
|
30
|
+
return cate.templates instanceof Function
|
|
31
|
+
? cate.templates()
|
|
32
|
+
: cate.templates;
|
|
54
33
|
},
|
|
34
|
+
categories: async () => templates.map(cate => cate.name),
|
|
35
|
+
categoryLabel: (name) => templates.find(cate => cate.name === name)?.nameKey,
|
|
55
36
|
search: async (keyword, cateName) => {
|
|
56
|
-
const candidates =
|
|
37
|
+
const candidates = [];
|
|
57
38
|
keyword = keyword.trim().toLocaleLowerCase();
|
|
58
|
-
await Promise.all(
|
|
59
|
-
// eslint-disable-next-line sonarjs/no-empty-collection
|
|
60
|
-
templates.map(async (categroy) => {
|
|
39
|
+
await Promise.all(templates.map(async (categroy) => {
|
|
61
40
|
if (cateName && cateName !== categroy.name) {
|
|
62
41
|
return;
|
|
63
42
|
}
|
|
@@ -73,9 +52,4 @@ export const builtInTemplates = {
|
|
|
73
52
|
}));
|
|
74
53
|
return candidates;
|
|
75
54
|
},
|
|
76
|
-
extend(manager) {
|
|
77
|
-
if (extendTemplate.includes(manager))
|
|
78
|
-
return;
|
|
79
|
-
extendTemplate.push(manager);
|
|
80
|
-
},
|
|
81
55
|
};
|
|
@@ -10,7 +10,7 @@ import type { Template } from './template-type.js';
|
|
|
10
10
|
* through this generic seam.
|
|
11
11
|
*
|
|
12
12
|
* `Template.name` itself stays the STABLE identity `templateFromCommand`
|
|
13
|
-
* bakes in (the drag payload, the
|
|
13
|
+
* bakes in (the drag payload, the search, the `templateCache` storage
|
|
14
14
|
* key) — and it is ALSO what gets passed as `translateKey`'s fallback, never
|
|
15
15
|
* `command.labelFallback`: most derived templates leave `name` at its default
|
|
16
16
|
* (the command's own fallback, so the two agree anyway), but a few tiles
|
|
@@ -10,7 +10,7 @@ import { getRegisteredCommands } from '../../std/index.js';
|
|
|
10
10
|
* through this generic seam.
|
|
11
11
|
*
|
|
12
12
|
* `Template.name` itself stays the STABLE identity `templateFromCommand`
|
|
13
|
-
* bakes in (the drag payload, the
|
|
13
|
+
* bakes in (the drag payload, the search, the `templateCache` storage
|
|
14
14
|
* key) — and it is ALSO what gets passed as `translateKey`'s fallback, never
|
|
15
15
|
* `command.labelFallback`: most derived templates leave `name` at its default
|
|
16
16
|
* (the command's own fallback, so the two agree anyway), but a few tiles
|
|
@@ -6,16 +6,16 @@ declare const EdgelessTemplatePanel_base: typeof LitElement & import("../../glob
|
|
|
6
6
|
export declare class EdgelessTemplatePanel extends EdgelessTemplatePanel_base {
|
|
7
7
|
static styles: import("lit").CSSResult;
|
|
8
8
|
/**
|
|
9
|
-
* The GLOBAL half of the catalogue — `Other
|
|
10
|
-
*
|
|
11
|
-
* (`TemplateCategoryExtension`) and are read
|
|
9
|
+
* The GLOBAL half of the catalogue — `Other`. Framework and host
|
|
10
|
+
* categories are not here: they live in the editor's DI container
|
|
11
|
+
* (`TemplateCategoryExtension`, `FrameTemplateProvider`) and are read
|
|
12
|
+
* through {@link catalogue}.
|
|
12
13
|
*/
|
|
13
14
|
static templates: {
|
|
14
15
|
list: (category: string) => Promise<Template[]>;
|
|
15
16
|
categories: () => Promise<string[]>;
|
|
16
17
|
categoryLabel: (name: string) => string | undefined;
|
|
17
18
|
search: (keyword: string, cateName?: string) => Promise<Template[]>;
|
|
18
|
-
extend(manager: import("./template-type.js").TemplateManager): void;
|
|
19
19
|
};
|
|
20
20
|
/** What THIS edgeless offers: the global half plus its std's categories. */
|
|
21
21
|
get catalogue(): import("./template-type.js").TemplateManager;
|
|
@@ -265,9 +265,10 @@ let EdgelessTemplatePanel = (() => {
|
|
|
265
265
|
}
|
|
266
266
|
`; }
|
|
267
267
|
/**
|
|
268
|
-
* The GLOBAL half of the catalogue — `Other
|
|
269
|
-
*
|
|
270
|
-
* (`TemplateCategoryExtension`) and are read
|
|
268
|
+
* The GLOBAL half of the catalogue — `Other`. Framework and host
|
|
269
|
+
* categories are not here: they live in the editor's DI container
|
|
270
|
+
* (`TemplateCategoryExtension`, `FrameTemplateProvider`) and are read
|
|
271
|
+
* through {@link catalogue}.
|
|
271
272
|
*/
|
|
272
273
|
static { this.templates = builtInTemplates; }
|
|
273
274
|
/** What THIS edgeless offers: the global half plus its std's categories. */
|
|
@@ -485,10 +486,10 @@ let EdgelessTemplatePanel = (() => {
|
|
|
485
486
|
})}
|
|
486
487
|
></affine-template-loading>`
|
|
487
488
|
: repeat(_templates,
|
|
488
|
-
// The
|
|
489
|
-
//
|
|
490
|
-
//
|
|
491
|
-
template => template
|
|
489
|
+
// The template object itself: two saved frames may share
|
|
490
|
+
// a title (`FrameTemplateProvider`), and a name key
|
|
491
|
+
// would draw one tile for both.
|
|
492
|
+
template => template, template => {
|
|
492
493
|
const preview = template.preview
|
|
493
494
|
? template.preview.startsWith('<svg')
|
|
494
495
|
? html `${unsafeSVG(template.preview)}`
|
|
@@ -498,8 +499,7 @@ let EdgelessTemplatePanel = (() => {
|
|
|
498
499
|
loading="lazy"
|
|
499
500
|
/>`
|
|
500
501
|
: defaultPreview;
|
|
501
|
-
const isBeingDragged = draggingElement &&
|
|
502
|
-
draggingElement.data.name === template.name;
|
|
502
|
+
const isBeingDragged = draggingElement && draggingElement.data === template;
|
|
503
503
|
// The one place that asks the host's catalogue for the
|
|
504
504
|
// WORDING above the identity — see `resolveTemplateName`.
|
|
505
505
|
const displayName = resolveTemplateName(this.edgeless.std, template);
|
|
@@ -70,9 +70,8 @@ export type TemplateCategory = {
|
|
|
70
70
|
* key (`com.labre.framework.<id>`, the senior button's); a generic one
|
|
71
71
|
* (`Other`) gets a key of its own. Absent for a category whose display name
|
|
72
72
|
* cannot be attributed to one owner (Cynefin and Estuarine share a single
|
|
73
|
-
* `cynefin-estuarine` framework key that names neither individually)
|
|
74
|
-
*
|
|
75
|
-
* `name` is shown as is.
|
|
73
|
+
* `cynefin-estuarine` framework key that names neither individually), in
|
|
74
|
+
* which case `name` is shown as is.
|
|
76
75
|
*/
|
|
77
76
|
nameKey?: string;
|
|
78
77
|
templates: Template[] | (() => Promise<Template[]>);
|
|
@@ -83,5 +82,4 @@ export interface TemplateManager {
|
|
|
83
82
|
search(keyword: string, category?: string): Promise<Template[]> | Template[];
|
|
84
83
|
/** {@link TemplateCategory.nameKey} of the category named `name`, if any. */
|
|
85
84
|
categoryLabel?(name: string): string | undefined;
|
|
86
|
-
extend?(manager: TemplateManager): void;
|
|
87
85
|
}
|
|
@@ -18,6 +18,11 @@ export declare const TEMPLATE_PANEL_SEARCH_PLACEHOLDER: ChromeWording;
|
|
|
18
18
|
* same word as {@link CATALOGUE_OTHER}, one key.
|
|
19
19
|
*/
|
|
20
20
|
export declare const TEMPLATE_PANEL_CATEGORY_OTHER: ChromeWording;
|
|
21
|
+
/**
|
|
22
|
+
* The tab of the frames a host keeps as templates (`FrameTemplateProvider`,
|
|
23
|
+
* `SAVED_FRAMES_CATEGORY`); there is no such tab without that host.
|
|
24
|
+
*/
|
|
25
|
+
export declare const TEMPLATE_PANEL_CATEGORY_SAVED_FRAMES: ChromeWording;
|
|
21
26
|
/** The "Template" senior tool's own button name (`SeniorTool.labelKey`). */
|
|
22
27
|
export declare const TEMPLATE_SENIOR_TOOL_NAME: ChromeWording;
|
|
23
28
|
export declare const TEMPLATE_NAME_SWOT: ChromeWording;
|
|
@@ -24,6 +24,14 @@ export const TEMPLATE_PANEL_SEARCH_PLACEHOLDER = [
|
|
|
24
24
|
* same word as {@link CATALOGUE_OTHER}, one key.
|
|
25
25
|
*/
|
|
26
26
|
export const TEMPLATE_PANEL_CATEGORY_OTHER = CATALOGUE_OTHER;
|
|
27
|
+
/**
|
|
28
|
+
* The tab of the frames a host keeps as templates (`FrameTemplateProvider`,
|
|
29
|
+
* `SAVED_FRAMES_CATEGORY`); there is no such tab without that host.
|
|
30
|
+
*/
|
|
31
|
+
export const TEMPLATE_PANEL_CATEGORY_SAVED_FRAMES = [
|
|
32
|
+
'com.labre.template.panel.category.saved-frames',
|
|
33
|
+
'Saved frames',
|
|
34
|
+
];
|
|
27
35
|
/** The "Template" senior tool's own button name (`SeniorTool.labelKey`). */
|
|
28
36
|
export const TEMPLATE_SENIOR_TOOL_NAME = [
|
|
29
37
|
'com.labre.template.senior-tool.name',
|
|
@@ -65,6 +73,7 @@ export const TEMPLATE_NAME_GANTT_CHART = [
|
|
|
65
73
|
export const TEMPLATE_PACKAGE_WORDINGS = [
|
|
66
74
|
TEMPLATE_PANEL_ADD,
|
|
67
75
|
TEMPLATE_PANEL_SEARCH_PLACEHOLDER,
|
|
76
|
+
TEMPLATE_PANEL_CATEGORY_SAVED_FRAMES,
|
|
68
77
|
TEMPLATE_SENIOR_TOOL_NAME,
|
|
69
78
|
TEMPLATE_NAME_SWOT,
|
|
70
79
|
TEMPLATE_NAME_KANBAN_BOARD,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { FOOTNOTE_DEFINITION_PREFIX, InlineDeltaToMarkdownAdapterExtension, } from '../../../affine-shared/adapters/index.js';
|
|
2
|
+
import { isSafeLinkUrl } from '../../../affine-shared/utils/index.js';
|
|
2
3
|
export const footnoteReferenceDeltaToMarkdownAdapterMatcher = InlineDeltaToMarkdownAdapterExtension({
|
|
3
4
|
name: 'footnote-reference',
|
|
4
5
|
match: delta => !!delta.attributes?.footnote,
|
|
@@ -19,6 +20,11 @@ export const footnoteReferenceDeltaToMarkdownAdapterMatcher = InlineDeltaToMarkd
|
|
|
19
20
|
if (!configs.has(footnoteDefinitionKey)) {
|
|
20
21
|
// clone the footnote reference
|
|
21
22
|
const clonedFootnoteReference = { ...footnote.reference };
|
|
23
|
+
// A stored url with a refused scheme is not written back out.
|
|
24
|
+
if (clonedFootnoteReference.url &&
|
|
25
|
+
!isSafeLinkUrl(clonedFootnoteReference.url)) {
|
|
26
|
+
delete clonedFootnoteReference.url;
|
|
27
|
+
}
|
|
22
28
|
// If the footnote reference contains url, encode it
|
|
23
29
|
if (clonedFootnoteReference.url) {
|
|
24
30
|
clonedFootnoteReference.url = encodeURIComponent(clonedFootnoteReference.url);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { FootNoteReferenceParamsSchema } from '../../../affine-model/index.js';
|
|
2
2
|
import { FOOTNOTE_DEFINITION_PREFIX, MarkdownASTToDeltaExtension, } from '../../../affine-shared/adapters/index.js';
|
|
3
|
+
import { isSafeLinkUrl } from '../../../affine-shared/utils/index.js';
|
|
3
4
|
export const markdownFootnoteReferenceToDeltaMatcher = MarkdownASTToDeltaExtension({
|
|
4
5
|
name: 'footnote-reference',
|
|
5
6
|
match: ast => ast.type === 'footnoteReference',
|
|
@@ -23,6 +24,12 @@ export const markdownFootnoteReferenceToDeltaMatcher = MarkdownASTToDeltaExtensi
|
|
|
23
24
|
footnoteDefinitionJson.favicon = decodeURIComponent(footnoteDefinitionJson.favicon);
|
|
24
25
|
}
|
|
25
26
|
const footnoteReference = FootNoteReferenceParamsSchema.parse(footnoteDefinitionJson);
|
|
27
|
+
// A refused scheme is not stored: the footnote keeps its label and
|
|
28
|
+
// loses the url, which the render side would refuse anyway.
|
|
29
|
+
if (footnoteReference.url !== undefined &&
|
|
30
|
+
!isSafeLinkUrl(footnoteReference.url)) {
|
|
31
|
+
delete footnoteReference.url;
|
|
32
|
+
}
|
|
26
33
|
// If the footnote reference is an attachment, and the file type is not set,
|
|
27
34
|
// Try to infer the file type from the file name.
|
|
28
35
|
const { type: referenceType, fileName, fileType } = footnoteReference;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { HtmlASTToDeltaExtension, } from '../../../affine-shared/adapters/index.js';
|
|
2
|
+
import { isSafeLinkUrl } from '../../../affine-shared/utils/index.js';
|
|
2
3
|
const isElement = (ast) => {
|
|
3
4
|
return ast.type === 'element';
|
|
4
5
|
};
|
|
@@ -47,7 +48,9 @@ export const htmlLinkElementToDeltaMatcher = HtmlASTToDeltaExtension({
|
|
|
47
48
|
}
|
|
48
49
|
}
|
|
49
50
|
return ast.children.flatMap(child => context.toDelta(child, { trim: false }).map(delta => {
|
|
50
|
-
|
|
51
|
+
// http(s) only, and by the parsed scheme: a prefix test let
|
|
52
|
+
// `httpx:` or `http-javascript:` through.
|
|
53
|
+
if (/^https?:/i.test(href.trim()) && isSafeLinkUrl(href)) {
|
|
51
54
|
delta.attributes = {
|
|
52
55
|
...delta.attributes,
|
|
53
56
|
link: href,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { InlineDeltaToHtmlAdapterExtension } from '../../../affine-shared/adapters/index.js';
|
|
2
|
+
import { isSafeLinkUrl } from '../../../affine-shared/utils/index.js';
|
|
2
3
|
export const linkDeltaToHtmlAdapterMatcher = InlineDeltaToHtmlAdapterExtension({
|
|
3
4
|
name: 'link',
|
|
4
5
|
match: delta => !!delta.attributes?.link,
|
|
@@ -8,7 +9,8 @@ export const linkDeltaToHtmlAdapterMatcher = InlineDeltaToHtmlAdapterExtension({
|
|
|
8
9
|
value: delta.insert,
|
|
9
10
|
};
|
|
10
11
|
const link = delta.attributes?.link;
|
|
11
|
-
|
|
12
|
+
// A stored link with a refused scheme is written as its text alone.
|
|
13
|
+
if (!link || !isSafeLinkUrl(link)) {
|
|
12
14
|
return hast;
|
|
13
15
|
}
|
|
14
16
|
return {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { InlineDeltaToMarkdownAdapterExtension } from '../../../affine-shared/adapters/index.js';
|
|
2
|
+
import { isSafeLinkUrl } from '../../../affine-shared/utils/index.js';
|
|
2
3
|
export const linkDeltaToMarkdownAdapterMatcher = InlineDeltaToMarkdownAdapterExtension({
|
|
3
4
|
name: 'link',
|
|
4
5
|
match: delta => !!delta.attributes?.link,
|
|
@@ -8,7 +9,9 @@ export const linkDeltaToMarkdownAdapterMatcher = InlineDeltaToMarkdownAdapterExt
|
|
|
8
9
|
value: delta.insert,
|
|
9
10
|
};
|
|
10
11
|
const link = delta.attributes?.link;
|
|
11
|
-
|
|
12
|
+
// A stored link with a refused scheme (an older document, a paste) is
|
|
13
|
+
// written as its text alone, never re-emitted as a link.
|
|
14
|
+
if (!link || !isSafeLinkUrl(link)) {
|
|
12
15
|
return mdast;
|
|
13
16
|
}
|
|
14
17
|
const { current: currentMdast } = context;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { NotionHtmlASTToDeltaExtension, } from '../../../affine-shared/adapters/index.js';
|
|
2
|
+
import { isSafeLinkUrl } from '../../../affine-shared/utils/index.js';
|
|
2
3
|
const isElement = (ast) => {
|
|
3
4
|
return ast.type === 'element';
|
|
4
5
|
};
|
|
@@ -29,7 +30,7 @@ export const notionHtmlLinkElementToDeltaMatcher = NotionHtmlASTToDeltaExtension
|
|
|
29
30
|
return delta;
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
|
-
if (href.
|
|
33
|
+
if (/^https?:/i.test(href.trim()) && isSafeLinkUrl(href)) {
|
|
33
34
|
delta.attributes = {
|
|
34
35
|
...delta.attributes,
|
|
35
36
|
link: href,
|
|
@@ -14,6 +14,13 @@ export declare class AffineLink extends AffineLink_base {
|
|
|
14
14
|
setFloating: (element?: Element) => void;
|
|
15
15
|
dispose: () => void;
|
|
16
16
|
};
|
|
17
|
+
/**
|
|
18
|
+
* Opens this link's toolbar without a hover, as a proposal (see
|
|
19
|
+
* `proposeLinkViews`). The toolbar keeps the hover contract once the pointer
|
|
20
|
+
* enters it; until then any key or press outside it closes it, so the
|
|
21
|
+
* proposal never outlives the next gesture.
|
|
22
|
+
*/
|
|
23
|
+
proposeViews(): void;
|
|
17
24
|
connectedCallback(): void;
|
|
18
25
|
get block(): BlockComponent<import("../../store/index.js").BlockModel<object>, import("../../std/index.js").BlockService, string> | null;
|
|
19
26
|
get inlineEditor(): import("../../std/inline/inline-editor.js").InlineEditor<AffineTextAttributes> | undefined;
|
|
@@ -65,6 +65,43 @@ let AffineLink = (() => {
|
|
|
65
65
|
text-decoration: underline;
|
|
66
66
|
}
|
|
67
67
|
`; }
|
|
68
|
+
/**
|
|
69
|
+
* Opens this link's toolbar without a hover, as a proposal (see
|
|
70
|
+
* `proposeLinkViews`). The toolbar keeps the hover contract once the pointer
|
|
71
|
+
* enters it; until then any key or press outside it closes it, so the
|
|
72
|
+
* proposal never outlives the next gesture.
|
|
73
|
+
*/
|
|
74
|
+
proposeViews() {
|
|
75
|
+
const message$ = this.std.get(ToolbarRegistryIdentifier).message$;
|
|
76
|
+
let floating;
|
|
77
|
+
const controller = new AbortController();
|
|
78
|
+
const close = (event) => {
|
|
79
|
+
if (floating && event.composedPath().includes(floating))
|
|
80
|
+
return;
|
|
81
|
+
controller.abort();
|
|
82
|
+
if (message$.peek()?.element === this)
|
|
83
|
+
message$.value = null;
|
|
84
|
+
};
|
|
85
|
+
const options = { capture: true, signal: controller.signal };
|
|
86
|
+
document.addEventListener('keydown', close, options);
|
|
87
|
+
document.addEventListener('pointerdown', close, options);
|
|
88
|
+
this._disposables.add(() => controller.abort());
|
|
89
|
+
message$.value = {
|
|
90
|
+
flavour: 'affine:link',
|
|
91
|
+
element: this,
|
|
92
|
+
setFloating: element => {
|
|
93
|
+
floating = element;
|
|
94
|
+
this._whenHover.setFloating(element);
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
// Subscribed after the write: `subscribe` calls back at once with the
|
|
98
|
+
// current value, which must already be this proposal.
|
|
99
|
+
const unsubscribe = message$.subscribe(message => {
|
|
100
|
+
if (message?.element !== this)
|
|
101
|
+
controller.abort();
|
|
102
|
+
});
|
|
103
|
+
controller.signal.addEventListener('abort', unsubscribe);
|
|
104
|
+
}
|
|
68
105
|
connectedCallback() {
|
|
69
106
|
super.connectedCallback();
|
|
70
107
|
this._whenHover.setReference(this);
|