@formicoidea/labre-core 0.43.1 → 0.45.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/utils.js +4 -0
- package/dist/_pkgs/affine-block-bookmark/configs/toolbar.js +17 -4
- package/dist/_pkgs/affine-block-callout/commands/turn-into-callout.d.ts +29 -0
- package/dist/_pkgs/affine-block-callout/commands/turn-into-callout.js +81 -0
- package/dist/_pkgs/affine-block-callout/configs/slash-menu.js +6 -4
- package/dist/_pkgs/affine-block-callout/configs/turn-into.d.ts +8 -0
- package/dist/_pkgs/affine-block-callout/configs/turn-into.js +19 -0
- package/dist/_pkgs/affine-block-callout/translations.d.ts +4 -2
- package/dist/_pkgs/affine-block-callout/translations.js +4 -2
- package/dist/_pkgs/affine-block-callout/view.js +3 -0
- package/dist/_pkgs/affine-block-code/code-block-service.d.ts +13 -0
- package/dist/_pkgs/affine-block-code/code-block-service.js +26 -0
- package/dist/_pkgs/affine-block-code/code-block.d.ts +6 -0
- package/dist/_pkgs/affine-block-code/code-block.js +11 -2
- package/dist/_pkgs/affine-block-code/code-toolbar/components/lang-button.js +31 -8
- package/dist/_pkgs/affine-block-edgeless-text/edgeless-toolbar/config.d.ts +11 -0
- package/dist/_pkgs/affine-block-edgeless-text/svg-painter.d.ts +20 -0
- package/dist/_pkgs/affine-block-edgeless-text/svg-painter.js +76 -0
- package/dist/_pkgs/affine-block-edgeless-text/view.js +2 -0
- package/dist/_pkgs/affine-block-embed/configs/toolbar.js +11 -2
- package/dist/_pkgs/affine-block-embed/embed-iframe-block/configs/toolbar.js +11 -2
- package/dist/_pkgs/affine-block-embed-doc/embed-linked-doc-block/embed-edgeless-linked-doc-block.js +3 -1
- package/dist/_pkgs/affine-block-embed-doc/embed-synced-doc-block/configs/toolbar.js +7 -2
- package/dist/_pkgs/affine-block-embed-doc/embed-synced-doc-block/embed-edgeless-synced-doc-block.js +3 -1
- package/dist/_pkgs/affine-block-frame/frame-manager.d.ts +5 -0
- package/dist/_pkgs/affine-block-frame/frame-manager.js +48 -17
- package/dist/_pkgs/affine-block-frame/frame-tool.js +3 -1
- package/dist/_pkgs/affine-block-image/utils.js +4 -1
- package/dist/_pkgs/affine-block-latex/adapters/markdown/preprocessor.d.ts +8 -0
- package/dist/_pkgs/affine-block-latex/adapters/markdown/preprocessor.js +9 -5
- package/dist/_pkgs/affine-block-note/translations.d.ts +0 -1
- package/dist/_pkgs/affine-block-note/translations.js +0 -5
- package/dist/_pkgs/affine-block-root/configs/toolbar.js +17 -1
- package/dist/_pkgs/affine-block-root/edgeless/clipboard/clipboard.js +2 -1
- package/dist/_pkgs/affine-block-root/edgeless/clipboard/command.js +161 -83
- package/dist/_pkgs/affine-block-root/edgeless/clipboard/paste-order.d.ts +21 -0
- package/dist/_pkgs/affine-block-root/edgeless/clipboard/paste-order.js +85 -0
- package/dist/_pkgs/affine-block-root/edgeless/edgeless-root-block.d.ts +6 -0
- package/dist/_pkgs/affine-block-root/edgeless/edgeless-root-block.js +18 -1
- package/dist/_pkgs/affine-block-root/edgeless/utils/clone-utils.d.ts +9 -0
- package/dist/_pkgs/affine-block-root/edgeless/utils/clone-utils.js +28 -0
- package/dist/_pkgs/affine-block-root/keyboard/commands.js +9 -6
- package/dist/_pkgs/affine-block-root/preview/edgeless-root-preview-block.js +15 -2
- package/dist/_pkgs/affine-block-surface/adapters/markdown/element-adapter/type.d.ts +1 -1
- package/dist/_pkgs/affine-block-surface/element-model/index.d.ts +1 -1
- package/dist/_pkgs/affine-block-surface/element-model/index.js +1 -1
- package/dist/_pkgs/affine-block-surface/extensions/audit.js +13 -61
- package/dist/_pkgs/affine-block-surface/extensions/canvas-grid/commands.d.ts +2 -0
- package/dist/_pkgs/affine-block-surface/extensions/canvas-grid/commands.js +71 -0
- package/dist/_pkgs/affine-block-surface/extensions/canvas-grid/index.d.ts +1 -0
- package/dist/_pkgs/affine-block-surface/extensions/canvas-grid/index.js +1 -0
- package/dist/_pkgs/affine-block-surface/extensions/clipboard-config.js +4 -0
- package/dist/_pkgs/affine-block-surface/extensions/crud-extension.js +4 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-manager/export-manager.d.ts +12 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-manager/export-manager.js +27 -7
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/command.d.ts +2 -1
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/command.js +22 -3
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/index.d.ts +6 -3
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/index.js +4 -2
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/parts.d.ts +63 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/parts.js +67 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/render.d.ts +62 -5
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/render.js +98 -18
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/svg-context.d.ts +14 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/svg-context.js +82 -1
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/toolbar.d.ts +2 -2
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/toolbar.js +112 -10
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/translations.d.ts +13 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/translations.js +33 -0
- package/dist/_pkgs/affine-block-surface/extensions/index.d.ts +3 -0
- package/dist/_pkgs/affine-block-surface/extensions/index.js +3 -0
- package/dist/_pkgs/affine-block-surface/extensions/reading-widget.d.ts +13 -6
- package/dist/_pkgs/affine-block-surface/extensions/reading-widget.js +26 -10
- package/dist/_pkgs/affine-block-surface/extensions/reading.d.ts +82 -6
- package/dist/_pkgs/affine-block-surface/extensions/reading.js +99 -21
- package/dist/_pkgs/affine-block-surface/extensions/selection-pane/actions.d.ts +80 -0
- package/dist/_pkgs/affine-block-surface/extensions/selection-pane/actions.js +248 -0
- package/dist/_pkgs/affine-block-surface/extensions/selection-pane/commands.d.ts +82 -0
- package/dist/_pkgs/affine-block-surface/extensions/selection-pane/commands.js +342 -0
- package/dist/_pkgs/affine-block-surface/extensions/selection-pane/index.d.ts +3 -0
- package/dist/_pkgs/affine-block-surface/extensions/selection-pane/index.js +3 -0
- package/dist/_pkgs/affine-block-surface/extensions/selection-pane/tree.d.ts +137 -0
- package/dist/_pkgs/affine-block-surface/extensions/selection-pane/tree.js +323 -0
- package/dist/_pkgs/affine-block-surface/extensions/svg-sketch.d.ts +112 -4
- package/dist/_pkgs/affine-block-surface/extensions/svg-sketch.js +86 -15
- package/dist/_pkgs/affine-block-surface/extensions/user-layers/actions.d.ts +76 -0
- package/dist/_pkgs/affine-block-surface/extensions/user-layers/actions.js +299 -0
- package/dist/_pkgs/affine-block-surface/extensions/user-layers/active-layer.d.ts +20 -0
- package/dist/_pkgs/affine-block-surface/extensions/user-layers/active-layer.js +34 -0
- package/dist/_pkgs/affine-block-surface/extensions/user-layers/commands.d.ts +67 -0
- package/dist/_pkgs/affine-block-surface/extensions/user-layers/commands.js +172 -0
- package/dist/_pkgs/affine-block-surface/extensions/user-layers/creation.d.ts +40 -0
- package/dist/_pkgs/affine-block-surface/extensions/user-layers/creation.js +69 -0
- package/dist/_pkgs/affine-block-surface/extensions/user-layers/index.d.ts +5 -0
- package/dist/_pkgs/affine-block-surface/extensions/user-layers/index.js +5 -0
- package/dist/_pkgs/affine-block-surface/extensions/user-layers/translations.d.ts +10 -0
- package/dist/_pkgs/affine-block-surface/extensions/user-layers/translations.js +14 -0
- package/dist/_pkgs/affine-block-surface/framework-background/facts.d.ts +55 -2
- package/dist/_pkgs/affine-block-surface/framework-background/facts.js +63 -1
- package/dist/_pkgs/affine-block-surface/framework-background/stacking.d.ts +16 -8
- package/dist/_pkgs/affine-block-surface/framework-background/stacking.js +26 -14
- package/dist/_pkgs/affine-block-surface/renderer/canvas-renderer.js +17 -3
- package/dist/_pkgs/affine-block-surface/renderer/dom-renderer.d.ts +3 -1
- package/dist/_pkgs/affine-block-surface/renderer/dom-renderer.js +22 -2
- package/dist/_pkgs/affine-block-surface/renderer/paint-predicate.d.ts +30 -0
- package/dist/_pkgs/affine-block-surface/renderer/paint-predicate.js +29 -0
- package/dist/_pkgs/affine-block-surface/surface-block.js +6 -0
- package/dist/_pkgs/affine-block-surface/surface-model.js +5 -0
- package/dist/_pkgs/affine-block-surface/surface-transformer.js +5 -0
- package/dist/_pkgs/affine-block-surface/tool/default-tool.js +28 -5
- package/dist/_pkgs/affine-block-surface/view.js +23 -1
- package/dist/_pkgs/affine-block-surface-ref/surface-ref-block.js +12 -2
- package/dist/_pkgs/affine-components/context-menu/button.js +14 -0
- package/dist/_pkgs/affine-components/filterable-list/index.js +30 -9
- package/dist/_pkgs/affine-components/icons/index.d.ts +0 -1
- package/dist/_pkgs/affine-components/icons/index.js +0 -1
- package/dist/_pkgs/affine-components/icons/text.d.ts +1 -0
- package/dist/_pkgs/affine-components/icons/text.js +11 -0
- package/dist/_pkgs/affine-fragment-adapter-panel/adapter-panel.d.ts +2 -2
- package/dist/_pkgs/affine-fragment-frame-panel/card/frame-card.js +2 -2
- package/dist/_pkgs/affine-fragment-frame-panel/header/frame-panel-header.d.ts +1 -1
- package/dist/_pkgs/affine-fragment-frame-panel/header/frame-panel-header.js +8 -27
- package/dist/_pkgs/affine-fragment-frame-panel/index.d.ts +1 -0
- package/dist/_pkgs/affine-fragment-frame-panel/index.js +1 -0
- package/dist/_pkgs/affine-gfx-connector/element-renderer/connector-dom/index.js +3 -1
- package/dist/_pkgs/affine-gfx-connector/element-renderer/index.js +21 -4
- package/dist/_pkgs/affine-gfx-connector/text/edgeless-connector-label-editor.js +3 -2
- package/dist/_pkgs/affine-gfx-connector/toolbar/config.js +1 -1
- package/dist/_pkgs/affine-gfx-group/command/group-api.js +52 -1
- package/dist/_pkgs/affine-gfx-shape/element-renderer/shape/index.js +21 -3
- package/dist/_pkgs/affine-gfx-shape/text/edgeless-shape-text-editor.js +2 -0
- package/dist/_pkgs/affine-gfx-shape/toolbar/config.js +1 -1
- package/dist/_pkgs/affine-gfx-template/services/template-middlewares.d.ts +9 -0
- package/dist/_pkgs/affine-gfx-template/services/template-middlewares.js +23 -1
- package/dist/_pkgs/affine-gfx-template/services/template.js +2 -1
- package/dist/_pkgs/affine-gfx-text/edgeless-text-editor.js +2 -1
- package/dist/_pkgs/affine-gfx-text/element-renderer/index.js +20 -3
- package/dist/_pkgs/affine-gfx-text/element-renderer/utils.d.ts +67 -1
- package/dist/_pkgs/affine-gfx-text/element-renderer/utils.js +101 -0
- package/dist/_pkgs/affine-gfx-text/toolbar/actions.d.ts +11 -0
- package/dist/_pkgs/affine-gfx-text/toolbar/actions.js +53 -2
- package/dist/_pkgs/affine-gfx-text/toolbar/config.d.ts +11 -0
- package/dist/_pkgs/affine-gfx-text/toolbar/config.js +1 -1
- package/dist/_pkgs/affine-inline-preset/adapters/html/html-inline.d.ts +3 -0
- package/dist/_pkgs/affine-inline-preset/adapters/html/html-inline.js +31 -0
- package/dist/_pkgs/affine-inline-preset/adapters/html/inline-delta.d.ts +4 -0
- package/dist/_pkgs/affine-inline-preset/adapters/html/inline-delta.js +14 -0
- package/dist/_pkgs/affine-inline-preset/command/config.js +21 -3
- package/dist/_pkgs/affine-inline-preset/command/index.d.ts +1 -1
- package/dist/_pkgs/affine-inline-preset/command/index.js +1 -1
- package/dist/_pkgs/affine-inline-preset/command/text-style.d.ts +2 -1
- package/dist/_pkgs/affine-inline-preset/command/text-style.js +1 -0
- package/dist/_pkgs/affine-inline-preset/default-inline-manager.js +2 -1
- package/dist/_pkgs/affine-inline-preset/inline-spec.d.ts +4 -0
- package/dist/_pkgs/affine-inline-preset/inline-spec.js +14 -0
- package/dist/_pkgs/affine-inline-preset/translations.d.ts +2 -2
- package/dist/_pkgs/affine-inline-preset/translations.js +2 -2
- package/dist/_pkgs/affine-model/blocks/attachment/attachment-model.js +2 -0
- package/dist/_pkgs/affine-model/blocks/bookmark/bookmark-model.js +2 -0
- package/dist/_pkgs/affine-model/blocks/edgeless-text/edgeless-text-model.d.ts +1 -1
- package/dist/_pkgs/affine-model/blocks/edgeless-text/edgeless-text-model.js +2 -0
- package/dist/_pkgs/affine-model/blocks/embed/iframe/iframe-model.js +2 -0
- package/dist/_pkgs/affine-model/blocks/frame/frame-model.js +2 -0
- package/dist/_pkgs/affine-model/blocks/image/image-model.js +2 -0
- package/dist/_pkgs/affine-model/blocks/latex/latex-model.js +2 -0
- package/dist/_pkgs/affine-model/blocks/note/note-model.js +2 -0
- package/dist/_pkgs/affine-model/consts/text.d.ts +26 -0
- package/dist/_pkgs/affine-model/consts/text.js +25 -0
- package/dist/_pkgs/affine-model/elements/shape/shape.d.ts +6 -1
- package/dist/_pkgs/affine-model/elements/shape/shape.js +14 -1
- package/dist/_pkgs/affine-model/elements/text/text.d.ts +6 -1
- package/dist/_pkgs/affine-model/elements/text/text.js +13 -1
- package/dist/_pkgs/affine-model/utils/helper.js +2 -0
- package/dist/_pkgs/affine-rich-text/conversion.d.ts +25 -0
- package/dist/_pkgs/affine-rich-text/conversion.js +9 -0
- package/dist/_pkgs/affine-rich-text/index.d.ts +1 -1
- package/dist/_pkgs/affine-rich-text/index.js +1 -1
- package/dist/_pkgs/affine-shared/commands/model-crud/replace-selected-text-with-blocks.d.ts +1 -1
- package/dist/_pkgs/affine-shared/services/canvas-grid.d.ts +63 -0
- package/dist/_pkgs/affine-shared/services/canvas-grid.js +109 -0
- package/dist/_pkgs/affine-shared/services/canvas-local-visibility.d.ts +64 -0
- package/dist/_pkgs/affine-shared/services/canvas-local-visibility.js +192 -0
- package/dist/_pkgs/affine-shared/services/edit-props-store.d.ts +27 -0
- package/dist/_pkgs/affine-shared/services/edit-props-store.js +34 -0
- package/dist/_pkgs/affine-shared/services/editor-setting-service.d.ts +3 -0
- package/dist/_pkgs/affine-shared/services/editor-setting-service.js +7 -0
- package/dist/_pkgs/affine-shared/services/feature-flag-service.d.ts +4 -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/selection-pane-service.d.ts +44 -0
- package/dist/_pkgs/affine-shared/services/selection-pane-service.js +28 -0
- package/dist/_pkgs/affine-shared/services/telemetry-service/lifecycle.d.ts +69 -0
- package/dist/_pkgs/affine-shared/services/telemetry-service/telemetry-service.d.ts +2 -2
- package/dist/_pkgs/affine-shared/services/translation-service/chrome.d.ts +5 -0
- package/dist/_pkgs/affine-shared/services/translation-service/chrome.js +9 -0
- package/dist/_pkgs/affine-shared/styles/index.d.ts +1 -0
- package/dist/_pkgs/affine-shared/styles/index.js +1 -0
- package/dist/_pkgs/affine-shared/styles/panel-header.d.ts +31 -0
- package/dist/_pkgs/affine-shared/styles/panel-header.js +61 -0
- package/dist/_pkgs/affine-shared/styles/text.js +7 -7
- package/dist/_pkgs/affine-shared/types/index.d.ts +6 -0
- package/dist/_pkgs/affine-shared/utils/canvas-export-colors.d.ts +26 -0
- package/dist/_pkgs/affine-shared/utils/canvas-export-colors.js +127 -0
- package/dist/_pkgs/affine-shared/utils/file/filesys.d.ts +8 -11
- package/dist/_pkgs/affine-shared/utils/file/filesys.js +8 -11
- package/dist/_pkgs/affine-shared/utils/index.d.ts +2 -0
- package/dist/_pkgs/affine-shared/utils/index.js +2 -0
- package/dist/_pkgs/affine-shared/utils/label-mode.d.ts +47 -0
- package/dist/_pkgs/affine-shared/utils/label-mode.js +55 -0
- package/dist/_pkgs/affine-shared/utils/model/merge-to-code-model.js +7 -1
- package/dist/_pkgs/affine-shared/utils/model/transform-model.js +5 -0
- package/dist/_pkgs/affine-widget-edgeless-selected-rect/utils.js +10 -3
- package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/artefact-catalogue-widget.js +25 -49
- package/dist/_pkgs/affine-widget-edgeless-toolbar/effects.d.ts +4 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/effects.js +4 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/index.d.ts +4 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/index.js +4 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/selection-pane/drop.d.ts +61 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/selection-pane/drop.js +91 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/selection-pane/labels.d.ts +17 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/selection-pane/labels.js +95 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/selection-pane/selection-pane-default.d.ts +10 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/selection-pane/selection-pane-default.js +31 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/selection-pane/selection-pane-tool.d.ts +26 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/selection-pane/selection-pane-tool.js +82 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/selection-pane/selection-pane-widget.d.ts +170 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/selection-pane/selection-pane-widget.js +1381 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/translations.d.ts +52 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/translations.js +161 -1
- package/dist/_pkgs/affine-widget-edgeless-toolbar/view.js +10 -0
- package/dist/_pkgs/affine-widget-note-slicer/note-slicer.js +7 -3
- package/dist/_pkgs/std/gfx/controller.d.ts +13 -0
- package/dist/_pkgs/std/gfx/controller.js +22 -2
- package/dist/_pkgs/std/gfx/grid.d.ts +31 -2
- package/dist/_pkgs/std/gfx/index.d.ts +3 -1
- package/dist/_pkgs/std/gfx/index.js +3 -1
- package/dist/_pkgs/std/gfx/interactivity/manager.js +7 -0
- package/dist/_pkgs/std/gfx/layer.js +73 -5
- package/dist/_pkgs/std/gfx/local-visibility.d.ts +88 -0
- package/dist/_pkgs/std/gfx/local-visibility.js +217 -0
- package/dist/_pkgs/std/gfx/model/gfx-block-model.d.ts +13 -0
- package/dist/_pkgs/std/gfx/model/surface/element-model.d.ts +34 -0
- package/dist/_pkgs/std/gfx/model/surface/element-model.js +65 -1
- package/dist/_pkgs/std/gfx/model/surface/surface-model.d.ts +27 -0
- package/dist/_pkgs/std/gfx/model/surface/surface-model.js +43 -0
- package/dist/_pkgs/std/gfx/model/surface/user-layers.d.ts +68 -0
- package/dist/_pkgs/std/gfx/model/surface/user-layers.js +127 -0
- package/dist/_pkgs/std/utils/layer.d.ts +10 -0
- package/dist/_pkgs/std/utils/layer.js +64 -13
- package/dist/_pkgs/std/view/element/gfx-block-component.js +10 -2
- package/dist/commands.js +4 -1
- package/dist/translations.js +10 -6
- package/package.json +9 -2
- package/dist/_pkgs/affine-components/icons/file-icons-rc.d.ts +0 -1
- package/dist/_pkgs/affine-components/icons/file-icons-rc.js +0 -130
- package/dist/_pkgs/affine-shared/test-utils/affine-template.d.ts +0 -6
- package/dist/_pkgs/affine-shared/test-utils/affine-template.js +0 -258
- package/dist/_pkgs/affine-shared/test-utils/affine-test-utils.d.ts +0 -8
- package/dist/_pkgs/affine-shared/test-utils/affine-test-utils.js +0 -81
- package/dist/_pkgs/affine-shared/test-utils/create-test-host.d.ts +0 -23
- package/dist/_pkgs/affine-shared/test-utils/create-test-host.js +0 -187
- package/dist/_pkgs/affine-shared/test-utils/index.d.ts +0 -3
- package/dist/_pkgs/affine-shared/test-utils/index.js +0 -3
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { applyCreationLayer } from '../affine-block-surface/index.js';
|
|
1
2
|
import { toast } from '../affine-components/toast/index.js';
|
|
2
3
|
import { AttachmentBlockSchema, } from '../affine-model/index.js';
|
|
3
4
|
import { EMBED_CARD_HEIGHT, EMBED_CARD_WIDTH, } from '../affine-shared/consts/index.js';
|
|
@@ -142,6 +143,9 @@ export async function addAttachments(std, files, point, shouldTransformPoint //
|
|
|
142
143
|
const xywh = Bound.fromCenter(center, width, height).serialize();
|
|
143
144
|
return { flavour, blockProps: { ...props, style, xywh } };
|
|
144
145
|
});
|
|
146
|
+
// The viewer's active layer, as the CRUD `addBlock` path stamps it
|
|
147
|
+
// (ADR 0031 §6): several blocks at once go straight to `store.addBlocks`.
|
|
148
|
+
blocks.forEach(({ blockProps }) => applyCreationLayer(std, blockProps));
|
|
145
149
|
const blockIds = std.store.addBlocks(blocks, gfx.surface);
|
|
146
150
|
gfx.selection.set({
|
|
147
151
|
elements: blockIds,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { canEmbedAsEmbedBlock, canEmbedAsIframe, EMBED_IFRAME_DEFAULT_HEIGHT_IN_SURFACE, EMBED_IFRAME_DEFAULT_WIDTH_IN_SURFACE, } from '../../affine-block-embed/index.js';
|
|
2
|
-
import { reassociateConnectorsCommand } from '../../affine-block-surface/index.js';
|
|
2
|
+
import { applyCreationLayer, reassociateConnectorsCommand, sourceLayerOf, } from '../../affine-block-surface/index.js';
|
|
3
3
|
import { toast } from '../../affine-components/toast/index.js';
|
|
4
4
|
import { BookmarkBlockModel, BookmarkStyles, } from '../../affine-model/index.js';
|
|
5
5
|
import { EMBED_CARD_HEIGHT, EMBED_CARD_WIDTH, } from '../../affine-shared/consts/index.js';
|
|
@@ -291,6 +291,13 @@ const builtinSurfaceToolbarConfig = {
|
|
|
291
291
|
return;
|
|
292
292
|
const { id: oldId, xywh, parent } = model;
|
|
293
293
|
const { url, caption, title, description } = model.props;
|
|
294
|
+
// The replacement takes the bookmark's place, layer included
|
|
295
|
+
// (ADR 0031 §6).
|
|
296
|
+
const withLayer = (props) => {
|
|
297
|
+
props.layer = sourceLayerOf(model);
|
|
298
|
+
applyCreationLayer(ctx.std, props);
|
|
299
|
+
return props;
|
|
300
|
+
};
|
|
294
301
|
let newId;
|
|
295
302
|
// first try to embed as a custom embed block
|
|
296
303
|
if (canEmbedAsEmbedBlock(ctx.std, url)) {
|
|
@@ -307,14 +314,14 @@ const builtinSurfaceToolbarConfig = {
|
|
|
307
314
|
const bound = Bound.deserialize(xywh);
|
|
308
315
|
bound.w = EMBED_CARD_WIDTH[style];
|
|
309
316
|
bound.h = EMBED_CARD_HEIGHT[style];
|
|
310
|
-
newId = ctx.store.addBlock(flavour, {
|
|
317
|
+
newId = ctx.store.addBlock(flavour, withLayer({
|
|
311
318
|
url,
|
|
312
319
|
caption,
|
|
313
320
|
title,
|
|
314
321
|
description,
|
|
315
322
|
style,
|
|
316
323
|
xywh: bound.serialize(),
|
|
317
|
-
}, parent);
|
|
324
|
+
}), parent);
|
|
318
325
|
}
|
|
319
326
|
else if (canEmbedAsIframe(ctx.std, url)) {
|
|
320
327
|
const embedIframeService = ctx.std.get(EmbedIframeService);
|
|
@@ -328,7 +335,13 @@ const builtinSurfaceToolbarConfig = {
|
|
|
328
335
|
bound.w = widthInSurface ?? EMBED_IFRAME_DEFAULT_WIDTH_IN_SURFACE;
|
|
329
336
|
bound.h =
|
|
330
337
|
heightInSurface ?? EMBED_IFRAME_DEFAULT_HEIGHT_IN_SURFACE;
|
|
331
|
-
newId = ctx.store.addBlock('affine:embed-iframe', {
|
|
338
|
+
newId = ctx.store.addBlock('affine:embed-iframe', withLayer({
|
|
339
|
+
url,
|
|
340
|
+
caption,
|
|
341
|
+
title,
|
|
342
|
+
description,
|
|
343
|
+
xywh: bound.serialize(),
|
|
344
|
+
}), parent);
|
|
332
345
|
}
|
|
333
346
|
if (!newId)
|
|
334
347
|
return;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Command } from '../../std/index.js';
|
|
2
|
+
import type { BlockModel, Store } from '../../store/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* The selected blocks "Turn into → Callout" would actually wrap.
|
|
5
|
+
*
|
|
6
|
+
* Decided BEFORE anything is written, so that a refusal costs nothing: a
|
|
7
|
+
* block already inside a callout (a callout never nests) or inside an
|
|
8
|
+
* edgeless text (where the slash item is not offered either), a parent that
|
|
9
|
+
* does not accept a callout, or a child the inner paragraph could not adopt —
|
|
10
|
+
* `deleteBlock({ bringChildrenTo })` detaches the source before it validates
|
|
11
|
+
* the children, so a refused child there would orphan the whole block. A
|
|
12
|
+
* selected child of another selected block is dropped too: it moves with its
|
|
13
|
+
* parent.
|
|
14
|
+
*/
|
|
15
|
+
export declare function calloutConversionTargets(store: Store, models: BlockModel[]): BlockModel[];
|
|
16
|
+
/**
|
|
17
|
+
* Wraps each selected paragraph, list item or code block in a callout (#418).
|
|
18
|
+
*
|
|
19
|
+
* A callout is a hub with no text of its own, so this cannot be
|
|
20
|
+
* `transformModel`: the callout takes the block's place, a paragraph inside it
|
|
21
|
+
* takes the text, and the block's children move under that paragraph. Every
|
|
22
|
+
* callout is built before any source is removed; if one cannot be, the ones
|
|
23
|
+
* already built are deleted and every source stays as it was.
|
|
24
|
+
*/
|
|
25
|
+
export declare const turnIntoCalloutCommand: Command<{
|
|
26
|
+
models: BlockModel[];
|
|
27
|
+
}, {
|
|
28
|
+
updatedBlocks: BlockModel[];
|
|
29
|
+
}>;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { CodeBlockModel, ListBlockModel, ParagraphBlockModel, } from '../../affine-model/index.js';
|
|
2
|
+
import { focusTextModel } from '../../affine-rich-text/index.js';
|
|
3
|
+
import { isInsideBlockByFlavour, matchModels, } from '../../affine-shared/utils/index.js';
|
|
4
|
+
const isAncestor = (store, ancestor, block) => {
|
|
5
|
+
for (let at = store.getParent(block); at; at = store.getParent(at)) {
|
|
6
|
+
if (at === ancestor)
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
return false;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* The selected blocks "Turn into → Callout" would actually wrap.
|
|
13
|
+
*
|
|
14
|
+
* Decided BEFORE anything is written, so that a refusal costs nothing: a
|
|
15
|
+
* block already inside a callout (a callout never nests) or inside an
|
|
16
|
+
* edgeless text (where the slash item is not offered either), a parent that
|
|
17
|
+
* does not accept a callout, or a child the inner paragraph could not adopt —
|
|
18
|
+
* `deleteBlock({ bringChildrenTo })` detaches the source before it validates
|
|
19
|
+
* the children, so a refused child there would orphan the whole block. A
|
|
20
|
+
* selected child of another selected block is dropped too: it moves with its
|
|
21
|
+
* parent.
|
|
22
|
+
*/
|
|
23
|
+
export function calloutConversionTargets(store, models) {
|
|
24
|
+
const { schema } = store;
|
|
25
|
+
const convertible = models.filter(model => {
|
|
26
|
+
if (!matchModels(model, [ParagraphBlockModel, ListBlockModel, CodeBlockModel]))
|
|
27
|
+
return false;
|
|
28
|
+
if (isInsideBlockByFlavour(store, model, 'affine:callout'))
|
|
29
|
+
return false;
|
|
30
|
+
if (isInsideBlockByFlavour(store, model, 'affine:edgeless-text'))
|
|
31
|
+
return false;
|
|
32
|
+
const parent = store.getParent(model);
|
|
33
|
+
if (!parent || !schema.isValid('affine:callout', parent.flavour))
|
|
34
|
+
return false;
|
|
35
|
+
return model.children.every(child => schema.isValid(child.flavour, 'affine:paragraph'));
|
|
36
|
+
});
|
|
37
|
+
return convertible.filter(model => !convertible.some(other => isAncestor(store, other, model)));
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Wraps each selected paragraph, list item or code block in a callout (#418).
|
|
41
|
+
*
|
|
42
|
+
* A callout is a hub with no text of its own, so this cannot be
|
|
43
|
+
* `transformModel`: the callout takes the block's place, a paragraph inside it
|
|
44
|
+
* takes the text, and the block's children move under that paragraph. Every
|
|
45
|
+
* callout is built before any source is removed; if one cannot be, the ones
|
|
46
|
+
* already built are deleted and every source stays as it was.
|
|
47
|
+
*/
|
|
48
|
+
export const turnIntoCalloutCommand = (ctx, next) => {
|
|
49
|
+
const { std, models } = ctx;
|
|
50
|
+
const store = std.store;
|
|
51
|
+
if (store.readonly)
|
|
52
|
+
return;
|
|
53
|
+
const targets = calloutConversionTargets(store, models);
|
|
54
|
+
if (targets.length === 0)
|
|
55
|
+
return;
|
|
56
|
+
store.captureSync();
|
|
57
|
+
const callouts = [];
|
|
58
|
+
const paragraphs = [];
|
|
59
|
+
for (const model of targets) {
|
|
60
|
+
const parent = store.getParent(model);
|
|
61
|
+
const callout = parent
|
|
62
|
+
? store.getModelById(store.addBlock('affine:callout', {}, parent, parent.children.indexOf(model)))
|
|
63
|
+
: null;
|
|
64
|
+
if (callout)
|
|
65
|
+
callouts.push(callout);
|
|
66
|
+
// `addBlock` returns an id even for a block the store refused, so only
|
|
67
|
+
// `getModelById` proves the block exists.
|
|
68
|
+
const paragraph = callout
|
|
69
|
+
? store.getModelById(store.addBlock('affine:paragraph', { text: model.text?.clone() }, callout))
|
|
70
|
+
: null;
|
|
71
|
+
if (!paragraph) {
|
|
72
|
+
callouts.forEach(created => store.deleteBlock(created));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
paragraphs.push(paragraph);
|
|
76
|
+
}
|
|
77
|
+
targets.forEach((model, i) => store.deleteBlock(model, { bringChildrenTo: paragraphs[i] }));
|
|
78
|
+
const first = paragraphs[0];
|
|
79
|
+
focusTextModel(std, first.id, first.text?.length ?? 0);
|
|
80
|
+
return next({ updatedBlocks: paragraphs });
|
|
81
|
+
};
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { focusBlockEnd } from '../../affine-shared/commands/index.js';
|
|
2
|
-
import { FeatureFlagService } from '../../affine-shared/services/index.js';
|
|
3
2
|
import { isInsideBlockByFlavour } from '../../affine-shared/utils/index.js';
|
|
4
3
|
import {} from '../../affine-widget-slash-menu/index.js';
|
|
5
4
|
import { FontIcon } from '@blocksuite/icons/lit';
|
|
6
5
|
import { CALLOUT_SLASH_CAPTION, CALLOUT_SLASH_DESCRIPTION, CALLOUT_SLASH_NAME, } from '../translations.js';
|
|
7
6
|
import { calloutTooltip } from './tooltips.js';
|
|
7
|
+
// Gated by the `callout` block flag alone: `CalloutViewExtension` registers
|
|
8
|
+
// this config and is itself flag-gated (ADR 0009). The deprecated
|
|
9
|
+
// `enable_callout` feature flag is not read.
|
|
10
|
+
//
|
|
8
11
|
// No `disableWhen` here on purpose. The widget ORs every config's `disableWhen`
|
|
9
12
|
// together and then refuses to open at all, so the callout's own guard used to
|
|
10
13
|
// silence the WHOLE slash menu inside a callout — every block, every framework,
|
|
@@ -24,9 +27,8 @@ export const calloutSlashMenuConfig = {
|
|
|
24
27
|
},
|
|
25
28
|
searchAlias: ['callout'],
|
|
26
29
|
group: '0_Basic@9',
|
|
27
|
-
when: ({
|
|
28
|
-
return (
|
|
29
|
-
!isInsideBlockByFlavour(model.store, model, 'affine:edgeless-text') &&
|
|
30
|
+
when: ({ model }) => {
|
|
31
|
+
return (!isInsideBlockByFlavour(model.store, model, 'affine:edgeless-text') &&
|
|
30
32
|
// The schema forbids a callout inside a callout, so offering the item
|
|
31
33
|
// there would only produce a thrown insertion.
|
|
32
34
|
!isInsideBlockByFlavour(model.store, model, 'affine:callout'));
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { TextConversionEntry } from '../../affine-rich-text/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* "Callout" in the "Turn into" menu, registered by `CalloutViewExtension` so
|
|
4
|
+
* the `callout` flag removes it with the slash item (ADR 0009). That flag is
|
|
5
|
+
* the only switch: the deprecated `enable_callout` feature flag is not read,
|
|
6
|
+
* so the two entries always appear and disappear together.
|
|
7
|
+
*/
|
|
8
|
+
export declare const calloutTurnIntoEntry: TextConversionEntry;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { FontIcon } from '@blocksuite/icons/lit';
|
|
2
|
+
import { calloutConversionTargets, turnIntoCalloutCommand, } from '../commands/turn-into-callout.js';
|
|
3
|
+
import { CALLOUT_TURN_INTO_NAME } from '../translations.js';
|
|
4
|
+
/**
|
|
5
|
+
* "Callout" in the "Turn into" menu, registered by `CalloutViewExtension` so
|
|
6
|
+
* the `callout` flag removes it with the slash item (ADR 0009). That flag is
|
|
7
|
+
* the only switch: the deprecated `enable_callout` feature flag is not read,
|
|
8
|
+
* so the two entries always appear and disappear together.
|
|
9
|
+
*/
|
|
10
|
+
export const calloutTurnIntoEntry = {
|
|
11
|
+
flavour: 'affine:callout',
|
|
12
|
+
name: 'Callout',
|
|
13
|
+
nameWording: CALLOUT_TURN_INTO_NAME,
|
|
14
|
+
icon: FontIcon(),
|
|
15
|
+
when: (std, models) => calloutConversionTargets(std.store, models).length > 0,
|
|
16
|
+
run: (std, models) => {
|
|
17
|
+
std.command.exec(turnIntoCalloutCommand, { models });
|
|
18
|
+
},
|
|
19
|
+
};
|
|
@@ -7,10 +7,12 @@ export declare const CALLOUT_SLASH_NAME: ChromeWording;
|
|
|
7
7
|
export declare const CALLOUT_SLASH_DESCRIPTION: ChromeWording;
|
|
8
8
|
/** The item's tooltip caption says the exact same word as its name. */
|
|
9
9
|
export declare const CALLOUT_SLASH_CAPTION: ChromeWording;
|
|
10
|
+
/** "Turn into → Callout" names the block with the slash item's own word. */
|
|
11
|
+
export declare const CALLOUT_TURN_INTO_NAME: ChromeWording;
|
|
10
12
|
/**
|
|
11
13
|
* Every wording declared above, in declaration order — walked by
|
|
12
14
|
* `PACKAGE_WORDINGS` in `packages/affine/all/src/translations.ts`. The
|
|
13
|
-
* caption
|
|
14
|
-
* aliases already follow.
|
|
15
|
+
* caption and turn-into aliases are not listed again, same rule other
|
|
16
|
+
* packages' chrome aliases already follow.
|
|
15
17
|
*/
|
|
16
18
|
export declare const CALLOUT_WORDINGS: readonly ChromeWording[];
|
|
@@ -12,11 +12,13 @@ export const CALLOUT_SLASH_DESCRIPTION = [
|
|
|
12
12
|
];
|
|
13
13
|
/** The item's tooltip caption says the exact same word as its name. */
|
|
14
14
|
export const CALLOUT_SLASH_CAPTION = CALLOUT_SLASH_NAME;
|
|
15
|
+
/** "Turn into → Callout" names the block with the slash item's own word. */
|
|
16
|
+
export const CALLOUT_TURN_INTO_NAME = CALLOUT_SLASH_NAME;
|
|
15
17
|
/**
|
|
16
18
|
* Every wording declared above, in declaration order — walked by
|
|
17
19
|
* `PACKAGE_WORDINGS` in `packages/affine/all/src/translations.ts`. The
|
|
18
|
-
* caption
|
|
19
|
-
* aliases already follow.
|
|
20
|
+
* caption and turn-into aliases are not listed again, same rule other
|
|
21
|
+
* packages' chrome aliases already follow.
|
|
20
22
|
*/
|
|
21
23
|
export const CALLOUT_WORDINGS = [
|
|
22
24
|
CALLOUT_SLASH_NAME,
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { ViewExtensionProvider, } from '../affine-ext-loader/index.js';
|
|
2
|
+
import { TextConversionEntryExtension } from '../affine-rich-text/index.js';
|
|
2
3
|
import { SlashMenuConfigExtension } from '../affine-widget-slash-menu/index.js';
|
|
3
4
|
import { BlockViewExtension, FlavourExtension } from '../std/index.js';
|
|
4
5
|
import { literal } from 'lit/static-html.js';
|
|
5
6
|
import { CalloutKeymapExtension } from './callout-keymap.js';
|
|
6
7
|
import { calloutSlashMenuConfig } from './configs/slash-menu.js';
|
|
8
|
+
import { calloutTurnIntoEntry } from './configs/turn-into.js';
|
|
7
9
|
import { effects } from './effects.js';
|
|
8
10
|
export class CalloutViewExtension extends ViewExtensionProvider {
|
|
9
11
|
constructor() {
|
|
@@ -21,6 +23,7 @@ export class CalloutViewExtension extends ViewExtensionProvider {
|
|
|
21
23
|
BlockViewExtension('affine:callout', literal `affine-callout`),
|
|
22
24
|
CalloutKeymapExtension,
|
|
23
25
|
SlashMenuConfigExtension('affine:callout', calloutSlashMenuConfig),
|
|
26
|
+
TextConversionEntryExtension(calloutTurnIntoEntry),
|
|
24
27
|
]);
|
|
25
28
|
}
|
|
26
29
|
}
|
|
@@ -6,8 +6,21 @@ export declare class CodeBlockHighlighter extends LifeCycleWatcher {
|
|
|
6
6
|
private _darkThemeKey;
|
|
7
7
|
private _lightThemeKey;
|
|
8
8
|
highlighter$: Signal<HighlighterCore | null>;
|
|
9
|
+
/**
|
|
10
|
+
* In-flight grammar loads, one per language. Per instance rather than
|
|
11
|
+
* static: each editor owns its own shiki core, and a grammar loaded into
|
|
12
|
+
* another editor's core is not loaded into this one.
|
|
13
|
+
*/
|
|
14
|
+
private readonly _languageLoads;
|
|
9
15
|
get themeKey(): string | undefined;
|
|
10
16
|
private readonly _loadTheme;
|
|
17
|
+
/**
|
|
18
|
+
* Loads a grammar into the shiki core, sharing the pending promise between
|
|
19
|
+
* concurrent callers (every code block of that language asks at once on
|
|
20
|
+
* first paint). A settled load leaves the map, so a failed one is retried
|
|
21
|
+
* on the next request.
|
|
22
|
+
*/
|
|
23
|
+
loadLanguage(lang: string, input: Parameters<HighlighterCore['loadLanguage']>[0]): Promise<void>;
|
|
11
24
|
mounted(): void;
|
|
12
25
|
unmounted(): void;
|
|
13
26
|
}
|
|
@@ -10,6 +10,12 @@ export class CodeBlockHighlighter extends LifeCycleWatcher {
|
|
|
10
10
|
constructor() {
|
|
11
11
|
super(...arguments);
|
|
12
12
|
this.highlighter$ = signal(null);
|
|
13
|
+
/**
|
|
14
|
+
* In-flight grammar loads, one per language. Per instance rather than
|
|
15
|
+
* static: each editor owns its own shiki core, and a grammar loaded into
|
|
16
|
+
* another editor's core is not loaded into this one.
|
|
17
|
+
*/
|
|
18
|
+
this._languageLoads = new Map();
|
|
13
19
|
this._loadTheme = async (highlighter) => {
|
|
14
20
|
const config = this.std.getOptional(CodeBlockConfigExtension.identifier);
|
|
15
21
|
const darkTheme = config?.theme?.dark ?? CODE_BLOCK_DEFAULT_DARK_THEME;
|
|
@@ -27,6 +33,26 @@ export class CodeBlockHighlighter extends LifeCycleWatcher {
|
|
|
27
33
|
? this._darkThemeKey
|
|
28
34
|
: this._lightThemeKey;
|
|
29
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Loads a grammar into the shiki core, sharing the pending promise between
|
|
38
|
+
* concurrent callers (every code block of that language asks at once on
|
|
39
|
+
* first paint). A settled load leaves the map, so a failed one is retried
|
|
40
|
+
* on the next request.
|
|
41
|
+
*/
|
|
42
|
+
loadLanguage(lang, input) {
|
|
43
|
+
const pending = this._languageLoads.get(lang);
|
|
44
|
+
if (pending)
|
|
45
|
+
return pending;
|
|
46
|
+
const highlighter = this.highlighter$.peek();
|
|
47
|
+
if (!highlighter) {
|
|
48
|
+
return Promise.reject(new Error('Code block highlighter is not ready'));
|
|
49
|
+
}
|
|
50
|
+
const load = highlighter.loadLanguage(input).finally(() => {
|
|
51
|
+
this._languageLoads.delete(lang);
|
|
52
|
+
});
|
|
53
|
+
this._languageLoads.set(lang, load);
|
|
54
|
+
return load;
|
|
55
|
+
}
|
|
30
56
|
mounted() {
|
|
31
57
|
super.mounted();
|
|
32
58
|
createHighlighterCore({
|
|
@@ -32,6 +32,12 @@ export declare class CodeBlockComponent extends CaptionedBlockComponent<CodeBloc
|
|
|
32
32
|
*/
|
|
33
33
|
get showLineNumbers(): boolean;
|
|
34
34
|
get topContenteditableElement(): BlockComponent<import("../store/index.js").BlockModel<object>, import("../std/index.js").BlockService, string> | null;
|
|
35
|
+
/**
|
|
36
|
+
* Bumped on every highlight request: a grammar load that resolves after a
|
|
37
|
+
* newer request (another language, or plain text) must not repaint the
|
|
38
|
+
* block with its stale tokens (#416).
|
|
39
|
+
*/
|
|
40
|
+
private _highlightRequestId;
|
|
35
41
|
private _updateHighlightTokens;
|
|
36
42
|
/**
|
|
37
43
|
* Stable signal: true when the global editor setting enables line numbers.
|
|
@@ -84,6 +84,12 @@ let CodeBlockComponent = (() => {
|
|
|
84
84
|
? matchedInfo.name
|
|
85
85
|
: translateKey(this.std, ...CODE_PLAIN_TEXT_LANGUAGE);
|
|
86
86
|
});
|
|
87
|
+
/**
|
|
88
|
+
* Bumped on every highlight request: a grammar load that resolves after a
|
|
89
|
+
* newer request (another language, or plain text) must not repaint the
|
|
90
|
+
* block with its stale tokens (#416).
|
|
91
|
+
*/
|
|
92
|
+
this._highlightRequestId = 0;
|
|
87
93
|
/**
|
|
88
94
|
* Stable signal: true when the global editor setting enables line numbers.
|
|
89
95
|
* Defaults to true. Updated reactively by an effect in connectedCallback.
|
|
@@ -146,6 +152,7 @@ let CodeBlockComponent = (() => {
|
|
|
146
152
|
return this.rootComponent;
|
|
147
153
|
}
|
|
148
154
|
_updateHighlightTokens() {
|
|
155
|
+
const requestId = ++this._highlightRequestId;
|
|
149
156
|
const modelLang = this.model.props.language$.value;
|
|
150
157
|
if (modelLang === null) {
|
|
151
158
|
this.highlightTokens$.value = [];
|
|
@@ -168,9 +175,11 @@ let CodeBlockComponent = (() => {
|
|
|
168
175
|
const code = this.model.props.text.toString();
|
|
169
176
|
const loadedLanguages = highlighter.getLoadedLanguages();
|
|
170
177
|
if (!loadedLanguages.includes(lang)) {
|
|
171
|
-
highlighter
|
|
172
|
-
.loadLanguage(langImport)
|
|
178
|
+
this.highlighter
|
|
179
|
+
.loadLanguage(lang, langImport)
|
|
173
180
|
.then(() => {
|
|
181
|
+
if (requestId !== this._highlightRequestId)
|
|
182
|
+
return;
|
|
174
183
|
this.highlightTokens$.value = highlighter.codeToTokensBase(code, {
|
|
175
184
|
lang,
|
|
176
185
|
theme,
|
|
@@ -42,7 +42,17 @@ import { css, LitElement, nothing } from 'lit';
|
|
|
42
42
|
import { property, query } from 'lit/decorators.js';
|
|
43
43
|
import { styleMap } from 'lit/directives/style-map.js';
|
|
44
44
|
import { html } from 'lit/static-html.js';
|
|
45
|
-
import { CODE_SEARCH_FOR_LANGUAGE } from '../../translations.js';
|
|
45
|
+
import { CODE_PLAIN_TEXT_LANGUAGE, CODE_SEARCH_FOR_LANGUAGE, } from '../../translations.js';
|
|
46
|
+
/**
|
|
47
|
+
* The list name of the Plain Text entry, which stands for `language: null`
|
|
48
|
+
* (#417). A colon never appears in a shiki language id, so it cannot collide
|
|
49
|
+
* with one, and no query starting with a letter matches it by name. It lives
|
|
50
|
+
* in the list and its persisted order only, never in the model.
|
|
51
|
+
*/
|
|
52
|
+
const PLAIN_TEXT_ITEM_NAME = ':plain-text';
|
|
53
|
+
function languageOf(item) {
|
|
54
|
+
return item.name === PLAIN_TEXT_ITEM_NAME ? null : item.name;
|
|
55
|
+
}
|
|
46
56
|
let LanguageListButton = (() => {
|
|
47
57
|
let _classSuper = WithDisposable(SignalWatcher(LitElement));
|
|
48
58
|
let __langButton_decorators;
|
|
@@ -95,16 +105,29 @@ let LanguageListButton = (() => {
|
|
|
95
105
|
connectedCallback() {
|
|
96
106
|
super.connectedCallback();
|
|
97
107
|
const langList = localStorage.getItem('blocksuite:code-block:lang-list');
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
else {
|
|
102
|
-
this._sortedBundledLanguages = this.blockComponent.langs.map(lang => ({
|
|
108
|
+
const languages = langList
|
|
109
|
+
? JSON.parse(langList)
|
|
110
|
+
: this.blockComponent.langs.map(lang => ({
|
|
103
111
|
label: lang.name,
|
|
104
112
|
name: lang.id,
|
|
105
113
|
aliases: lang.aliases,
|
|
106
114
|
}));
|
|
115
|
+
// A list persisted before the entry existed lacks it, and a persisted
|
|
116
|
+
// label is in the locale of the session that wrote it: keep the entry's
|
|
117
|
+
// recently-used position, refresh its words.
|
|
118
|
+
const plainText = {
|
|
119
|
+
label: translateKey(this.blockComponent.std, ...CODE_PLAIN_TEXT_LANGUAGE),
|
|
120
|
+
name: PLAIN_TEXT_ITEM_NAME,
|
|
121
|
+
aliases: ['plain', 'text', 'none'],
|
|
122
|
+
};
|
|
123
|
+
const index = languages.findIndex(item => item.name === PLAIN_TEXT_ITEM_NAME);
|
|
124
|
+
if (index === -1) {
|
|
125
|
+
languages.unshift(plainText);
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
languages[index] = plainText;
|
|
107
129
|
}
|
|
130
|
+
this._sortedBundledLanguages = languages;
|
|
108
131
|
this.disposables.add(() => {
|
|
109
132
|
localStorage.setItem('blocksuite:code-block:lang-list', JSON.stringify(this._sortedBundledLanguages));
|
|
110
133
|
});
|
|
@@ -169,7 +192,7 @@ let LanguageListButton = (() => {
|
|
|
169
192
|
sortedBundledLanguages.unshift(item);
|
|
170
193
|
}
|
|
171
194
|
this.blockComponent.store.transact(() => {
|
|
172
|
-
this.blockComponent.model.props.language$.value = item
|
|
195
|
+
this.blockComponent.model.props.language$.value = languageOf(item);
|
|
173
196
|
});
|
|
174
197
|
const std = this.blockComponent.std;
|
|
175
198
|
const mode = std.getOptional(DocModeProvider)?.getEditorMode() ?? 'page';
|
|
@@ -183,7 +206,7 @@ let LanguageListButton = (() => {
|
|
|
183
206
|
control: item.name,
|
|
184
207
|
});
|
|
185
208
|
},
|
|
186
|
-
active: item => item
|
|
209
|
+
active: item => languageOf(item) === this.blockComponent.model.props.language,
|
|
187
210
|
items: this._sortedBundledLanguages,
|
|
188
211
|
};
|
|
189
212
|
showPopFilterableList({
|
|
@@ -8,6 +8,17 @@ export declare const edgelessTextToolbarConfig: {
|
|
|
8
8
|
}, {
|
|
9
9
|
readonly id: "c.font-style";
|
|
10
10
|
readonly content: (ctx: import("../../affine-shared/services/index.js").ToolbarContext) => import("lit-html").TemplateResult<1> | null;
|
|
11
|
+
}, {
|
|
12
|
+
readonly id: "c.text-decoration";
|
|
13
|
+
readonly when: boolean;
|
|
14
|
+
readonly actions: {
|
|
15
|
+
id: "a.underline" | "b.overline";
|
|
16
|
+
icon: import("lit-html").TemplateResult<1>;
|
|
17
|
+
tooltipWording: import("../../affine-shared/services/index.js").ChromeWording;
|
|
18
|
+
when: (ctx: import("../../affine-shared/services/index.js").ToolbarContext) => boolean;
|
|
19
|
+
active: (ctx: import("../../affine-shared/services/index.js").ToolbarContext) => boolean;
|
|
20
|
+
run: (ctx: import("../../affine-shared/services/index.js").ToolbarContext) => void;
|
|
21
|
+
}[];
|
|
11
22
|
}, {
|
|
12
23
|
readonly id: "d.font-size";
|
|
13
24
|
readonly when: boolean;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type BlockSvgPainter } from '../affine-block-surface/index.js';
|
|
2
|
+
import { type EdgelessTextBlockModel } from '../affine-model/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* An edgeless text, redrawn as VECTOR text for "Export SVG" (ADR 0025,
|
|
5
|
+
* amendment of 2026-10-04).
|
|
6
|
+
*
|
|
7
|
+
* The block is DOM, so no canvas renderer paints it; this lays it out the way
|
|
8
|
+
* its CSS does, with the canvas text renderer's own font string and wrapping
|
|
9
|
+
* (`@labre/affine-gfx-text`): one line run per paragraph, its size and weight
|
|
10
|
+
* from `HEADING_SCALE` for a heading and from the 15px body otherwise, wrapped
|
|
11
|
+
* to the block's width only when the block has one (`hasMaxWidth`), then
|
|
12
|
+
* rotated about the block's centre and scaled by `scale`, as on screen.
|
|
13
|
+
*
|
|
14
|
+
* ponytail: each paragraph is drawn in the BLOCK's style — inline bold, italic,
|
|
15
|
+
* colour and links are flattened, list bullets and numbers are not drawn, and
|
|
16
|
+
* heading margins are ignored. Upgrade by walking the paragraph's deltas the
|
|
17
|
+
* way `wrapTextDeltas` does for a canvas text, when a board needs it.
|
|
18
|
+
*/
|
|
19
|
+
export declare const edgelessTextSvgPainter: BlockSvgPainter<EdgelessTextBlockModel>;
|
|
20
|
+
export declare const EdgelessTextSvgPainterExtension: import("../store/index.js").ExtensionType;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { BlockSvgPainterExtension, } from '../affine-block-surface/index.js';
|
|
2
|
+
import { getFontString, wrapText } from '../affine-gfx-text/index.js';
|
|
3
|
+
import { DefaultTheme } from '../affine-model/index.js';
|
|
4
|
+
import { HEADING_SCALE } from '../affine-shared/consts/index.js';
|
|
5
|
+
import { EDGELESS_TEXT_BASE_FONT_SIZE } from './edgeless-toolbar/font-size.js';
|
|
6
|
+
/** `--affine-line-height` is `calc(1em + 8px)`: what a body line adds to its size. */
|
|
7
|
+
const BODY_LINE_EXTRA = 8;
|
|
8
|
+
/** The container's 1px border, which the text sits inside. */
|
|
9
|
+
const BORDER = 1;
|
|
10
|
+
/** Every paragraph and list item of the block, depth first, as plain text. */
|
|
11
|
+
function runsOf(model, runs = []) {
|
|
12
|
+
for (const child of model.children) {
|
|
13
|
+
if (child.text) {
|
|
14
|
+
const type = child.props.type;
|
|
15
|
+
runs.push({
|
|
16
|
+
level: type !== undefined && type in HEADING_SCALE
|
|
17
|
+
? type
|
|
18
|
+
: undefined,
|
|
19
|
+
text: child.text.toString(),
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
runsOf(child, runs);
|
|
23
|
+
}
|
|
24
|
+
return runs;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* An edgeless text, redrawn as VECTOR text for "Export SVG" (ADR 0025,
|
|
28
|
+
* amendment of 2026-10-04).
|
|
29
|
+
*
|
|
30
|
+
* The block is DOM, so no canvas renderer paints it; this lays it out the way
|
|
31
|
+
* its CSS does, with the canvas text renderer's own font string and wrapping
|
|
32
|
+
* (`@labre/affine-gfx-text`): one line run per paragraph, its size and weight
|
|
33
|
+
* from `HEADING_SCALE` for a heading and from the 15px body otherwise, wrapped
|
|
34
|
+
* to the block's width only when the block has one (`hasMaxWidth`), then
|
|
35
|
+
* rotated about the block's centre and scaled by `scale`, as on screen.
|
|
36
|
+
*
|
|
37
|
+
* ponytail: each paragraph is drawn in the BLOCK's style — inline bold, italic,
|
|
38
|
+
* colour and links are flattened, list bullets and numbers are not drawn, and
|
|
39
|
+
* heading margins are ignored. Upgrade by walking the paragraph's deltas the
|
|
40
|
+
* way `wrapTextDeltas` does for a canvas text, when a board needs it.
|
|
41
|
+
*/
|
|
42
|
+
export const edgelessTextSvgPainter = (model, ctx, matrix, renderer) => {
|
|
43
|
+
const { scale, rotate, color, fontFamily, fontStyle, fontWeight, textAlign, hasMaxWidth, } = model.props;
|
|
44
|
+
const [, , w, h] = model.deserializedXYWH;
|
|
45
|
+
ctx.setTransform(matrix
|
|
46
|
+
.translate(w / 2, h / 2)
|
|
47
|
+
.rotate(rotate)
|
|
48
|
+
.translate(-w / 2, -h / 2)
|
|
49
|
+
.scale(scale));
|
|
50
|
+
const width = w / scale - 2 * BORDER;
|
|
51
|
+
const x = BORDER +
|
|
52
|
+
(textAlign === 'center' ? width / 2 : textAlign === 'right' ? width : 0);
|
|
53
|
+
ctx.fillStyle = renderer.getColorValue(color, DefaultTheme.textColor, true);
|
|
54
|
+
ctx.textAlign = textAlign;
|
|
55
|
+
ctx.textBaseline = 'middle';
|
|
56
|
+
let y = BORDER;
|
|
57
|
+
for (const { level, text } of runsOf(model)) {
|
|
58
|
+
const heading = level ? HEADING_SCALE[level] : undefined;
|
|
59
|
+
const fontSize = heading?.fontSize ?? EDGELESS_TEXT_BASE_FONT_SIZE;
|
|
60
|
+
const lineHeight = fontSize + (heading?.lineHeightExtra ?? BODY_LINE_EXTRA);
|
|
61
|
+
const font = getFontString({
|
|
62
|
+
fontStyle,
|
|
63
|
+
fontWeight: heading ? String(heading.fontWeight) : fontWeight,
|
|
64
|
+
fontSize,
|
|
65
|
+
fontFamily,
|
|
66
|
+
});
|
|
67
|
+
ctx.font = font;
|
|
68
|
+
const lines = (hasMaxWidth ? wrapText(text, font, width) : text).split('\n');
|
|
69
|
+
for (const line of lines) {
|
|
70
|
+
if (line)
|
|
71
|
+
ctx.fillText(line, x, y + lineHeight / 2);
|
|
72
|
+
y += lineHeight;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
export const EdgelessTextSvgPainterExtension = BlockSvgPainterExtension('affine:edgeless-text', edgelessTextSvgPainter);
|
|
@@ -5,6 +5,7 @@ import { EdgelessClipboardEdgelessTextConfig } from './edgeless-clipboard-config
|
|
|
5
5
|
import { EdgelessTextInteraction } from './edgeless-text-block.js';
|
|
6
6
|
import { edgelessTextToolbarExtension } from './edgeless-toolbar/index.js';
|
|
7
7
|
import { effects } from './effects.js';
|
|
8
|
+
import { EdgelessTextSvgPainterExtension } from './svg-painter.js';
|
|
8
9
|
export class EdgelessTextViewExtension extends ViewExtensionProvider {
|
|
9
10
|
constructor() {
|
|
10
11
|
super(...arguments);
|
|
@@ -24,6 +25,7 @@ export class EdgelessTextViewExtension extends ViewExtensionProvider {
|
|
|
24
25
|
context.register(edgelessTextToolbarExtension);
|
|
25
26
|
context.register(EdgelessClipboardEdgelessTextConfig);
|
|
26
27
|
context.register(EdgelessTextInteraction);
|
|
28
|
+
context.register(EdgelessTextSvgPainterExtension);
|
|
27
29
|
}
|
|
28
30
|
}
|
|
29
31
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { reassociateConnectorsCommand } from '../../affine-block-surface/index.js';
|
|
1
|
+
import { applyCreationLayer, reassociateConnectorsCommand, sourceLayerOf, } from '../../affine-block-surface/index.js';
|
|
2
2
|
import { toast } from '../../affine-components/toast/index.js';
|
|
3
3
|
import { BookmarkStyles, EmbedGithubModel, EmbedGithubStyles, isExternalEmbedModel, } from '../../affine-model/index.js';
|
|
4
4
|
import { EMBED_CARD_HEIGHT, EMBED_CARD_WIDTH, } from '../../affine-shared/consts/index.js';
|
|
@@ -342,7 +342,16 @@ const createBuiltinSurfaceToolbarConfigForExternal = (klass) => {
|
|
|
342
342
|
const bounds = Bound.deserialize(xywh);
|
|
343
343
|
bounds.w = EMBED_CARD_WIDTH[style];
|
|
344
344
|
bounds.h = EMBED_CARD_HEIGHT[style];
|
|
345
|
-
|
|
345
|
+
// The card takes the embed's place, layer included (ADR 0031 §6).
|
|
346
|
+
const props = {
|
|
347
|
+
url,
|
|
348
|
+
caption,
|
|
349
|
+
style,
|
|
350
|
+
xywh: bounds.serialize(),
|
|
351
|
+
layer: sourceLayerOf(model),
|
|
352
|
+
};
|
|
353
|
+
applyCreationLayer(ctx.std, props);
|
|
354
|
+
const newId = ctx.store.addBlock(flavour, props, parent);
|
|
346
355
|
ctx.command.exec(reassociateConnectorsCommand, { oldId, newId });
|
|
347
356
|
ctx.store.deleteBlock(model);
|
|
348
357
|
// Selects new block
|