refactor(editor): move export manager to surface block extensions (#10231)

This commit is contained in:
Saul-Mirone
2025-02-18 04:39:05 +00:00
parent 31f8e92a4b
commit c3e924d4cb
20 changed files with 128 additions and 119 deletions
@@ -24,9 +24,11 @@
"@preact/signals-core": "^1.8.0", "@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.7", "@toeverything/theme": "^1.1.7",
"fractional-indexing": "^3.2.0", "fractional-indexing": "^3.2.0",
"html2canvas": "^1.4.1",
"lit": "^3.2.0", "lit": "^3.2.0",
"lodash.chunk": "^4.2.0", "lodash.chunk": "^4.2.0",
"nanoid": "^5.0.7", "nanoid": "^5.0.7",
"pdf-lib": "^1.17.1",
"yjs": "^13.6.21", "yjs": "^13.6.21",
"zod": "^3.23.8" "zod": "^3.23.8"
}, },
@@ -1,11 +1,8 @@
import {
type CanvasRenderer,
SurfaceElementModel,
} from '@blocksuite/affine-block-surface';
import { import {
FrameBlockModel, FrameBlockModel,
GroupElementModel, GroupElementModel,
ImageBlockModel, ImageBlockModel,
type NoteBlockModel,
type RootBlockModel, type RootBlockModel,
} from '@blocksuite/affine-model'; } from '@blocksuite/affine-model';
import { FetchUtils } from '@blocksuite/affine-shared/adapters'; import { FetchUtils } from '@blocksuite/affine-shared/adapters';
@@ -13,32 +10,32 @@ import {
CANVAS_EXPORT_IGNORE_TAGS, CANVAS_EXPORT_IGNORE_TAGS,
DEFAULT_IMAGE_PROXY_ENDPOINT, DEFAULT_IMAGE_PROXY_ENDPOINT,
} from '@blocksuite/affine-shared/consts'; } from '@blocksuite/affine-shared/consts';
import type { Viewport } from '@blocksuite/affine-shared/types';
import { import {
isInsidePageEditor, isInsidePageEditor,
matchModels, matchModels,
} from '@blocksuite/affine-shared/utils'; } from '@blocksuite/affine-shared/utils';
import { import {
type BlockComponent,
type BlockStdScope, type BlockStdScope,
type EditorHost, type EditorHost,
StdIdentifier, StdIdentifier,
} from '@blocksuite/block-std'; } from '@blocksuite/block-std';
import type { import {
GfxBlockElementModel, GfxBlockElementModel,
GfxPrimitiveElementModel, type GfxController,
GfxControllerIdentifier,
type GfxPrimitiveElementModel,
} from '@blocksuite/block-std/gfx'; } from '@blocksuite/block-std/gfx';
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions'; import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
import type { IBound } from '@blocksuite/global/utils'; import type { IBound } from '@blocksuite/global/utils';
import { Bound } from '@blocksuite/global/utils'; import { Bound, deserializeXYWH } from '@blocksuite/global/utils';
import type { ExtensionType, Store } from '@blocksuite/store'; import type { ExtensionType, Store } from '@blocksuite/store';
import { import { SurfaceElementModel } from '../../element-model/base.js';
getBlockComponentByModel, import type { CanvasRenderer } from '../../renderer/canvas-renderer.js';
getRootByEditorHost, import type { SurfaceBlockComponent } from '../../surface-block.js';
} from '../../_common/utils/index.js'; import { getBgGridGap } from '../../utils/get-bg-grip-gap.js';
import type { EdgelessRootBlockComponent } from '../../root-block/edgeless/edgeless-root-block.js';
import { getBlocksInFrameBound } from '../../root-block/edgeless/frame-manager.js';
import { xywhArrayToObject } from '../../root-block/edgeless/utils/convert.js';
import { getBackgroundGrid } from '../../root-block/edgeless/utils/query.js';
import { FileExporter } from './file-exporter.js'; import { FileExporter } from './file-exporter.js';
// oxlint-disable-next-line typescript/consistent-type-imports // oxlint-disable-next-line typescript/consistent-type-imports
@@ -47,6 +44,7 @@ type Html2CanvasFunction = typeof import('html2canvas').default;
export type ExportOptions = { export type ExportOptions = {
imageProxyEndpoint: string; imageProxyEndpoint: string;
}; };
export class ExportManager { export class ExportManager {
private readonly _exportOptions: ExportOptions = { private readonly _exportOptions: ExportOptions = {
imageProxyEndpoint: DEFAULT_IMAGE_PROXY_ENDPOINT, imageProxyEndpoint: DEFAULT_IMAGE_PROXY_ENDPOINT,
@@ -151,7 +149,9 @@ export class ExportManager {
} }
const rootModel = this.doc.root; const rootModel = this.doc.root;
const rootComponent = this.doc.root const rootComponent = this.doc.root
? getBlockComponentByModel(this.editorHost, rootModel) ? rootModel
? this.editorHost.view.getBlock(rootModel.id)
: null
: null; : null;
const imageCard = rootComponent?.querySelector( const imageCard = rootComponent?.querySelector(
'affine-image-fallback-card' 'affine-image-fallback-card'
@@ -398,12 +398,11 @@ export class ExportManager {
const rootModel = this.doc.root; const rootModel = this.doc.root;
if (!rootModel) return; if (!rootModel) return;
const edgeless = getBlockComponentByModel( const gfx = this.editorHost.std.get(GfxControllerIdentifier);
this.editorHost, const surfaceBlock = gfx.surfaceComponent as SurfaceBlockComponent | null;
rootModel if (!surfaceBlock) return;
) as EdgelessRootBlockComponent; const bound = gfx.elementsBound;
const bound = edgeless.gfx.elementsBound; return this.edgelessToCanvas(surfaceBlock.renderer, bound, gfx);
return this.edgelessToCanvas(edgeless.surface.renderer, bound, edgeless);
} }
} }
@@ -411,7 +410,7 @@ export class ExportManager {
async edgelessToCanvas( async edgelessToCanvas(
surfaceRenderer: CanvasRenderer, surfaceRenderer: CanvasRenderer,
bound: IBound, bound: IBound,
edgeless?: EdgelessRootBlockComponent, gfx: GfxController,
nodes?: GfxBlockElementModel[], nodes?: GfxBlockElementModel[],
surfaces?: GfxPrimitiveElementModel[], surfaces?: GfxPrimitiveElementModel[],
edgelessBackground?: { edgelessBackground?: {
@@ -449,7 +448,7 @@ export class ExportManager {
backgroundColor: containerComputedStyle.getPropertyValue( backgroundColor: containerComputedStyle.getPropertyValue(
'--affine-background-primary-color' '--affine-background-primary-color'
), ),
size: getBackgroundGrid(edgelessBackground.zoom, true).gap, size: getBgGridGap(edgelessBackground.zoom),
gridColor: containerComputedStyle.getPropertyValue( gridColor: containerComputedStyle.getPropertyValue(
'--affine-edgeless-grid-color' '--affine-edgeless-grid-color'
), ),
@@ -457,9 +456,7 @@ export class ExportManager {
} }
const blocks = const blocks =
nodes ?? nodes ?? gfx.getElementsByBound(bound, { type: 'block' }) ?? [];
edgeless?.service.gfx.getElementsByBound(bound, { type: 'block' }) ??
[];
for (const block of blocks) { for (const block of blocks) {
if (matchModels(block, [ImageBlockModel])) { if (matchModels(block, [ImageBlockModel])) {
if (!block.sourceId) return; if (!block.sourceId) return;
@@ -592,3 +589,66 @@ export const ExportManagerExtension: ExtensionType = {
di.add(ExportManager, [StdIdentifier]); di.add(ExportManager, [StdIdentifier]);
}, },
}; };
function xywhArrayToObject(element: GfxBlockElementModel) {
const [x, y, w, h] = deserializeXYWH(element.xywh);
return { x, y, w, h };
}
function getNotesInFrameBound(
doc: Store,
frame: FrameBlockModel,
fullyContained: boolean = true
): NoteBlockModel[] {
const bound = Bound.deserialize(frame.xywh);
return (doc.getBlockByFlavour('affine:note') as NoteBlockModel[]).filter(
ele => {
const xywh = Bound.deserialize(ele.xywh);
return fullyContained
? bound.contains(xywh)
: bound.isPointInBound([xywh.x, xywh.y]);
}
);
}
function getBlocksInFrameBound(
doc: Store,
model: FrameBlockModel,
fullyContained: boolean = true
) {
const bound = Bound.deserialize(model.xywh);
const surface = model.surface;
if (!surface) return [];
return (
getNotesInFrameBound(doc, model, fullyContained) as GfxBlockElementModel[]
).concat(
surface.children.filter((ele): ele is GfxBlockElementModel => {
if (ele.id === model.id) return false;
if (ele instanceof GfxBlockElementModel) {
const blockBound = Bound.deserialize(ele.xywh);
return fullyContained
? bound.contains(blockBound)
: bound.containsPoint([blockBound.x, blockBound.y]);
}
return false;
})
);
}
type RootBlockComponent = BlockComponent & {
viewportElement: HTMLElement;
viewport: Viewport;
};
function getRootByEditorHost(
editorHost: EditorHost
): RootBlockComponent | null {
const model = editorHost.doc.root;
if (!model) return null;
const root = editorHost.view.getBlock(model.id);
return root as RootBlockComponent | null;
}
@@ -1,4 +1,4 @@
/* eslint-disable no-control-regex */ /* oxlint-disable no-control-regex */
// Context: Lean towards breaking out any localizable content into constants so it's // Context: Lean towards breaking out any localizable content into constants so it's
// easier to track content we may need to localize in the future. (i18n) // easier to track content we may need to localize in the future. (i18n)
const UNTITLED_PAGE_NAME = 'Untitled'; const UNTITLED_PAGE_NAME = 'Untitled';
@@ -0,0 +1 @@
export { ExportManager, ExportManagerExtension } from './export-manager.js';
@@ -1,3 +1,4 @@
export * from './crud-extension'; export * from './crud-extension';
export * from './export-manager';
export * from './legacy-slot-extension'; export * from './legacy-slot-extension';
export * from './query'; export * from './query';
@@ -80,6 +80,7 @@ export {
addNote, addNote,
addNoteAtPoint, addNoteAtPoint,
generateElementId, generateElementId,
getBgGridGap,
getLastPropsKey, getLastPropsKey,
getSurfaceBlock, getSurfaceBlock,
normalizeWheelDeltaY, normalizeWheelDeltaY,
@@ -10,6 +10,7 @@ import {
EdgelessCRUDExtension, EdgelessCRUDExtension,
EdgelessLegacySlotExtension, EdgelessLegacySlotExtension,
} from './extensions'; } from './extensions';
import { ExportManagerExtension } from './extensions/export-manager/export-manager';
import { SurfaceBlockService } from './surface-service'; import { SurfaceBlockService } from './surface-service';
import { MindMapView } from './view/mindmap'; import { MindMapView } from './view/mindmap';
@@ -19,6 +20,7 @@ const CommonSurfaceBlockSpec: ExtensionType[] = [
MindMapView, MindMapView,
EdgelessCRUDExtension, EdgelessCRUDExtension,
EdgelessLegacySlotExtension, EdgelessLegacySlotExtension,
ExportManagerExtension,
]; ];
export const PageSurfaceBlockSpec: ExtensionType[] = [ export const PageSurfaceBlockSpec: ExtensionType[] = [
@@ -0,0 +1,10 @@
import { clamp } from '@blocksuite/global/utils';
import { GRID_GAP_MAX, GRID_GAP_MIN } from '../consts';
export function getBgGridGap(zoom: number) {
const step = zoom < 0.5 ? 2 : 1 / (Math.floor(zoom) || 1);
const gap = clamp(20 * step * zoom, GRID_GAP_MIN, GRID_GAP_MAX);
return gap;
}
@@ -34,6 +34,7 @@ export function normalizeWheelDeltaY(delta: number, zoom = 1) {
} }
export { addNote, addNoteAtPoint } from './add-note'; export { addNote, addNoteAtPoint } from './add-note';
export { getBgGridGap } from './get-bg-grip-gap';
export { getLastPropsKey } from './get-last-props-key'; export { getLastPropsKey } from './get-last-props-key';
export { getSurfaceBlock } from './get-surface-block'; export { getSurfaceBlock } from './get-surface-block';
export * from './mindmap/style-svg.js'; export * from './mindmap/style-svg.js';
-1
View File
@@ -62,7 +62,6 @@
"lz-string": "^1.5.0", "lz-string": "^1.5.0",
"minimatch": "^10.0.1", "minimatch": "^10.0.1",
"nanoid": "^5.0.7", "nanoid": "^5.0.7",
"pdf-lib": "^1.17.1",
"shiki": "^2.0.0", "shiki": "^2.0.0",
"simple-xml-to-json": "^1.2.2", "simple-xml-to-json": "^1.2.2",
"yjs": "^13.6.21", "yjs": "^13.6.21",
-4
View File
@@ -8,10 +8,6 @@ import { isCanvasElement } from './root-block/edgeless/utils/query.js';
export * from './_common/adapters/index.js'; export * from './_common/adapters/index.js';
export { type NavigatorMode } from './_common/edgeless/frame/consts.js'; export { type NavigatorMode } from './_common/edgeless/frame/consts.js';
export {
ExportManager,
ExportManagerExtension,
} from './_common/export-manager/export-manager.js';
export * from './_common/test-utils/test-utils.js'; export * from './_common/test-utils/test-utils.js';
export * from './_common/transformers/index.js'; export * from './_common/transformers/index.js';
export { type AbstractEditor } from './_common/types.js'; export { type AbstractEditor } from './_common/types.js';
@@ -9,7 +9,6 @@ import {
import { FlavourExtension } from '@blocksuite/block-std'; import { FlavourExtension } from '@blocksuite/block-std';
import type { ExtensionType } from '@blocksuite/store'; import type { ExtensionType } from '@blocksuite/store';
import { ExportManagerExtension } from '../../_common/export-manager/export-manager';
import { RootBlockAdapterExtensions } from '../adapters/extension'; import { RootBlockAdapterExtensions } from '../adapters/extension';
import { import {
docRemoteSelectionWidget, docRemoteSelectionWidget,
@@ -29,7 +28,6 @@ export const CommonSpecs: ExtensionType[] = [
DocModeService, DocModeService,
ThemeService, ThemeService,
EmbedOptionService, EmbedOptionService,
ExportManagerExtension,
PageViewportServiceExtension, PageViewportServiceExtension,
DNDAPIExtension, DNDAPIExtension,
FileDropExtension, FileDropExtension,
@@ -3,6 +3,7 @@ import { addImages } from '@blocksuite/affine-block-image';
import { import {
CanvasElementType, CanvasElementType,
EdgelessCRUDIdentifier, EdgelessCRUDIdentifier,
ExportManager,
SurfaceGroupLikeModel, SurfaceGroupLikeModel,
TextUtils, TextUtils,
} from '@blocksuite/affine-block-surface'; } from '@blocksuite/affine-block-surface';
@@ -68,7 +69,6 @@ import {
import DOMPurify from 'dompurify'; import DOMPurify from 'dompurify';
import * as Y from 'yjs'; import * as Y from 'yjs';
import { ExportManager } from '../../../_common/export-manager/export-manager.js';
import { getRootByEditorHost } from '../../../_common/utils/query.js'; import { getRootByEditorHost } from '../../../_common/utils/query.js';
import { ClipboardAdapter } from '../../clipboard/adapter.js'; import { ClipboardAdapter } from '../../clipboard/adapter.js';
import { PageClipboard } from '../../clipboard/index.js'; import { PageClipboard } from '../../clipboard/index.js';
@@ -4,6 +4,7 @@ import type {
} from '@blocksuite/affine-block-surface'; } from '@blocksuite/affine-block-surface';
import { import {
EdgelessLegacySlotIdentifier, EdgelessLegacySlotIdentifier,
getBgGridGap,
normalizeWheelDeltaY, normalizeWheelDeltaY,
} from '@blocksuite/affine-block-surface'; } from '@blocksuite/affine-block-surface';
import { import {
@@ -51,7 +52,7 @@ import { EdgelessClipboardController } from './clipboard/clipboard.js';
import type { EdgelessSelectedRectWidget } from './components/rects/edgeless-selected-rect.js'; import type { EdgelessSelectedRectWidget } from './components/rects/edgeless-selected-rect.js';
import { EdgelessPageKeyboardManager } from './edgeless-keyboard.js'; import { EdgelessPageKeyboardManager } from './edgeless-keyboard.js';
import type { EdgelessRootService } from './edgeless-root-service.js'; import type { EdgelessRootService } from './edgeless-root-service.js';
import { getBackgroundGrid, isCanvasElement } from './utils/query.js'; import { isCanvasElement } from './utils/query.js';
import { mountShapeTextEditor } from './utils/text.js'; import { mountShapeTextEditor } from './utils/text.js';
export class EdgelessRootBlockComponent extends BlockComponent< export class EdgelessRootBlockComponent extends BlockComponent<
@@ -106,7 +107,7 @@ export class EdgelessRootBlockComponent extends BlockComponent<
private readonly _refreshLayerViewport = requestThrottledConnectedFrame( private readonly _refreshLayerViewport = requestThrottledConnectedFrame(
() => { () => {
const { zoom, translateX, translateY } = this.gfx.viewport; const { zoom, translateX, translateY } = this.gfx.viewport;
const { gap } = getBackgroundGrid(zoom, true); const gap = getBgGridGap(zoom);
if (this.backgroundElm) { if (this.backgroundElm) {
this.backgroundElm.style.setProperty( this.backgroundElm.style.setProperty(
@@ -1,6 +1,7 @@
import type { import {
SurfaceBlockComponent, getBgGridGap,
SurfaceBlockModel, type SurfaceBlockComponent,
type SurfaceBlockModel,
} from '@blocksuite/affine-block-surface'; } from '@blocksuite/affine-block-surface';
import type { EdgelessPreviewer } from '@blocksuite/affine-block-surface-ref'; import type { EdgelessPreviewer } from '@blocksuite/affine-block-surface-ref';
import type { RootBlockModel } from '@blocksuite/affine-model'; import type { RootBlockModel } from '@blocksuite/affine-model';
@@ -23,7 +24,7 @@ import { styleMap } from 'lit/directives/style-map.js';
import type { EdgelessRootBlockWidgetName } from '../types.js'; import type { EdgelessRootBlockWidgetName } from '../types.js';
import type { EdgelessRootService } from './edgeless-root-service.js'; import type { EdgelessRootService } from './edgeless-root-service.js';
import { getBackgroundGrid, isCanvasElement } from './utils/query.js'; import { isCanvasElement } from './utils/query.js';
export class EdgelessRootPreviewBlockComponent export class EdgelessRootPreviewBlockComponent
extends BlockComponent< extends BlockComponent<
@@ -73,7 +74,7 @@ export class EdgelessRootPreviewBlockComponent
private readonly _refreshLayerViewport = requestThrottledConnectedFrame( private readonly _refreshLayerViewport = requestThrottledConnectedFrame(
() => { () => {
const { zoom, translateX, translateY } = this.service.viewport; const { zoom, translateX, translateY } = this.service.viewport;
const { gap } = getBackgroundGrid(zoom, true); const gap = getBgGridGap(zoom);
this.background.style.setProperty( this.background.style.setProperty(
'background-position', 'background-position',
@@ -1,6 +1,6 @@
import type { SurfaceBlockModel } from '@blocksuite/affine-block-surface'; import type { SurfaceBlockModel } from '@blocksuite/affine-block-surface';
import { Overlay } from '@blocksuite/affine-block-surface'; import { Overlay } from '@blocksuite/affine-block-surface';
import type { FrameBlockModel, NoteBlockModel } from '@blocksuite/affine-model'; import type { FrameBlockModel } from '@blocksuite/affine-model';
import { EditPropsStore } from '@blocksuite/affine-shared/services'; import { EditPropsStore } from '@blocksuite/affine-shared/services';
import { import {
generateKeyBetweenV2, generateKeyBetweenV2,
@@ -21,7 +21,6 @@ import {
type IVec, type IVec,
type SerializedXYWH, type SerializedXYWH,
} from '@blocksuite/global/utils'; } from '@blocksuite/global/utils';
import type { Store } from '@blocksuite/store';
import { Text } from '@blocksuite/store'; import { Text } from '@blocksuite/store';
import * as Y from 'yjs'; import * as Y from 'yjs';
@@ -462,47 +461,3 @@ export class EdgelessFrameManager extends GfxExtension {
this._disposable.dispose(); this._disposable.dispose();
} }
} }
export function getNotesInFrameBound(
doc: Store,
frame: FrameBlockModel,
fullyContained: boolean = true
) {
const bound = Bound.deserialize(frame.xywh);
return (doc.getBlockByFlavour('affine:note') as NoteBlockModel[]).filter(
ele => {
const xywh = Bound.deserialize(ele.xywh);
return fullyContained
? bound.contains(xywh)
: bound.isPointInBound([xywh.x, xywh.y]);
}
) as NoteBlockModel[];
}
export function getBlocksInFrameBound(
doc: Store,
model: FrameBlockModel,
fullyContained: boolean = true
) {
const bound = Bound.deserialize(model.xywh);
const surface = model.surface;
if (!surface) return [];
return (
getNotesInFrameBound(doc, model, fullyContained) as GfxBlockElementModel[]
).concat(
surface.children.filter(ele => {
if (ele.id === model.id) return false;
if (ele instanceof GfxBlockElementModel) {
const blockBound = Bound.deserialize(ele.xywh);
return fullyContained
? bound.contains(blockBound)
: bound.containsPoint([blockBound.x, blockBound.y]);
}
return false;
}) as GfxBlockElementModel[]
);
}
@@ -1,7 +0,0 @@
import type { GfxBlockElementModel } from '@blocksuite/block-std/gfx';
import { deserializeXYWH } from '@blocksuite/global/utils';
export function xywhArrayToObject(element: GfxBlockElementModel) {
const [x, y, w, h] = deserializeXYWH(element.xywh);
return { x, y, w, h };
}
@@ -1,8 +1,4 @@
import { import type { CanvasElementWithText } from '@blocksuite/affine-block-surface';
type CanvasElementWithText,
GRID_GAP_MAX,
GRID_GAP_MIN,
} from '@blocksuite/affine-block-surface';
import { import {
type AttachmentBlockModel, type AttachmentBlockModel,
type BookmarkBlockModel, type BookmarkBlockModel,
@@ -34,7 +30,7 @@ import type {
Viewport, Viewport,
} from '@blocksuite/block-std/gfx'; } from '@blocksuite/block-std/gfx';
import type { PointLocation } from '@blocksuite/global/utils'; import type { PointLocation } from '@blocksuite/global/utils';
import { Bound, clamp } from '@blocksuite/global/utils'; import { Bound } from '@blocksuite/global/utils';
import type { BlockModel } from '@blocksuite/store'; import type { BlockModel } from '@blocksuite/store';
import type { Connectable } from '../../../_common/utils/index.js'; import type { Connectable } from '../../../_common/utils/index.js';
@@ -228,18 +224,6 @@ export function getCursorMode(edgelessTool: GfxToolsFullOptionValue | null) {
} }
} }
export function getBackgroundGrid(zoom: number, showGrid: boolean) {
const step = zoom < 0.5 ? 2 : 1 / (Math.floor(zoom) || 1);
const gap = clamp(20 * step * zoom, GRID_GAP_MIN, GRID_GAP_MAX);
return {
gap,
grid: showGrid
? 'radial-gradient(var(--affine-edgeless-grid-color) 1px, var(--affine-background-primary-color) 1px)'
: 'unset',
};
}
export type SelectableProps = { export type SelectableProps = {
bound: Bound; bound: Bound;
rotate: number; rotate: number;
@@ -1,12 +1,14 @@
import type { CanvasRenderer } from '@blocksuite/affine-block-surface'; import type { CanvasRenderer } from '@blocksuite/affine-block-surface';
import { ExportManager } from '@blocksuite/affine-block-surface';
import type { SurfaceRefBlockComponent } from '@blocksuite/affine-block-surface-ref'; import type { SurfaceRefBlockComponent } from '@blocksuite/affine-block-surface-ref';
import { isTopLevelBlock } from '@blocksuite/affine-shared/utils'; import { isTopLevelBlock } from '@blocksuite/affine-shared/utils';
import type { EditorHost } from '@blocksuite/block-std'; import type { EditorHost } from '@blocksuite/block-std';
import type { GfxModel } from '@blocksuite/block-std/gfx'; import {
GfxControllerIdentifier,
type GfxModel,
} from '@blocksuite/block-std/gfx';
import { assertExists, Bound } from '@blocksuite/global/utils'; import { assertExists, Bound } from '@blocksuite/global/utils';
import { ExportManager } from '../../../_common/export-manager/export-manager.js';
export const edgelessToBlob = async ( export const edgelessToBlob = async (
host: EditorHost, host: EditorHost,
options: { options: {
@@ -19,12 +21,13 @@ export const edgelessToBlob = async (
const exportManager = host.std.get(ExportManager); const exportManager = host.std.get(ExportManager);
const bound = Bound.deserialize(edgelessElement.xywh); const bound = Bound.deserialize(edgelessElement.xywh);
const isBlock = isTopLevelBlock(edgelessElement); const isBlock = isTopLevelBlock(edgelessElement);
const gfx = host.std.get(GfxControllerIdentifier);
return exportManager return exportManager
.edgelessToCanvas( .edgelessToCanvas(
options.surfaceRenderer, options.surfaceRenderer,
bound, bound,
undefined, gfx,
isBlock ? [edgelessElement] : undefined, isBlock ? [edgelessElement] : undefined,
isBlock ? undefined : [edgelessElement], isBlock ? undefined : [edgelessElement],
{ zoom: options.surfaceRenderer.viewport.zoom } { zoom: options.surfaceRenderer.viewport.zoom }
+2 -1
View File
@@ -3645,9 +3645,11 @@ __metadata:
"@toeverything/theme": "npm:^1.1.7" "@toeverything/theme": "npm:^1.1.7"
"@types/lodash.chunk": "npm:^4.2.9" "@types/lodash.chunk": "npm:^4.2.9"
fractional-indexing: "npm:^3.2.0" fractional-indexing: "npm:^3.2.0"
html2canvas: "npm:^1.4.1"
lit: "npm:^3.2.0" lit: "npm:^3.2.0"
lodash.chunk: "npm:^4.2.0" lodash.chunk: "npm:^4.2.0"
nanoid: "npm:^5.0.7" nanoid: "npm:^5.0.7"
pdf-lib: "npm:^1.17.1"
vitest: "npm:3.0.5" vitest: "npm:3.0.5"
yjs: "npm:^13.6.21" yjs: "npm:^13.6.21"
zod: "npm:^3.23.8" zod: "npm:^3.23.8"
@@ -3958,7 +3960,6 @@ __metadata:
lz-string: "npm:^1.5.0" lz-string: "npm:^1.5.0"
minimatch: "npm:^10.0.1" minimatch: "npm:^10.0.1"
nanoid: "npm:^5.0.7" nanoid: "npm:^5.0.7"
pdf-lib: "npm:^1.17.1"
shiki: "npm:^2.0.0" shiki: "npm:^2.0.0"
simple-xml-to-json: "npm:^1.2.2" simple-xml-to-json: "npm:^1.2.2"
vitest: "npm:3.0.5" vitest: "npm:3.0.5"