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

View File

@@ -9,7 +9,6 @@ import {
import { FlavourExtension } from '@blocksuite/block-std';
import type { ExtensionType } from '@blocksuite/store';
import { ExportManagerExtension } from '../../_common/export-manager/export-manager';
import { RootBlockAdapterExtensions } from '../adapters/extension';
import {
docRemoteSelectionWidget,
@@ -29,7 +28,6 @@ export const CommonSpecs: ExtensionType[] = [
DocModeService,
ThemeService,
EmbedOptionService,
ExportManagerExtension,
PageViewportServiceExtension,
DNDAPIExtension,
FileDropExtension,

View File

@@ -3,6 +3,7 @@ import { addImages } from '@blocksuite/affine-block-image';
import {
CanvasElementType,
EdgelessCRUDIdentifier,
ExportManager,
SurfaceGroupLikeModel,
TextUtils,
} from '@blocksuite/affine-block-surface';
@@ -68,7 +69,6 @@ import {
import DOMPurify from 'dompurify';
import * as Y from 'yjs';
import { ExportManager } from '../../../_common/export-manager/export-manager.js';
import { getRootByEditorHost } from '../../../_common/utils/query.js';
import { ClipboardAdapter } from '../../clipboard/adapter.js';
import { PageClipboard } from '../../clipboard/index.js';

View File

@@ -4,6 +4,7 @@ import type {
} from '@blocksuite/affine-block-surface';
import {
EdgelessLegacySlotIdentifier,
getBgGridGap,
normalizeWheelDeltaY,
} from '@blocksuite/affine-block-surface';
import {
@@ -51,7 +52,7 @@ import { EdgelessClipboardController } from './clipboard/clipboard.js';
import type { EdgelessSelectedRectWidget } from './components/rects/edgeless-selected-rect.js';
import { EdgelessPageKeyboardManager } from './edgeless-keyboard.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';
export class EdgelessRootBlockComponent extends BlockComponent<
@@ -106,7 +107,7 @@ export class EdgelessRootBlockComponent extends BlockComponent<
private readonly _refreshLayerViewport = requestThrottledConnectedFrame(
() => {
const { zoom, translateX, translateY } = this.gfx.viewport;
const { gap } = getBackgroundGrid(zoom, true);
const gap = getBgGridGap(zoom);
if (this.backgroundElm) {
this.backgroundElm.style.setProperty(

View File

@@ -1,6 +1,7 @@
import type {
SurfaceBlockComponent,
SurfaceBlockModel,
import {
getBgGridGap,
type SurfaceBlockComponent,
type SurfaceBlockModel,
} from '@blocksuite/affine-block-surface';
import type { EdgelessPreviewer } from '@blocksuite/affine-block-surface-ref';
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 { EdgelessRootService } from './edgeless-root-service.js';
import { getBackgroundGrid, isCanvasElement } from './utils/query.js';
import { isCanvasElement } from './utils/query.js';
export class EdgelessRootPreviewBlockComponent
extends BlockComponent<
@@ -73,7 +74,7 @@ export class EdgelessRootPreviewBlockComponent
private readonly _refreshLayerViewport = requestThrottledConnectedFrame(
() => {
const { zoom, translateX, translateY } = this.service.viewport;
const { gap } = getBackgroundGrid(zoom, true);
const gap = getBgGridGap(zoom);
this.background.style.setProperty(
'background-position',

View File

@@ -1,6 +1,6 @@
import type { SurfaceBlockModel } 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 {
generateKeyBetweenV2,
@@ -21,7 +21,6 @@ import {
type IVec,
type SerializedXYWH,
} from '@blocksuite/global/utils';
import type { Store } from '@blocksuite/store';
import { Text } from '@blocksuite/store';
import * as Y from 'yjs';
@@ -462,47 +461,3 @@ export class EdgelessFrameManager extends GfxExtension {
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[]
);
}

View File

@@ -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 };
}

View File

@@ -1,8 +1,4 @@
import {
type CanvasElementWithText,
GRID_GAP_MAX,
GRID_GAP_MIN,
} from '@blocksuite/affine-block-surface';
import type { CanvasElementWithText } from '@blocksuite/affine-block-surface';
import {
type AttachmentBlockModel,
type BookmarkBlockModel,
@@ -34,7 +30,7 @@ import type {
Viewport,
} from '@blocksuite/block-std/gfx';
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 { 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 = {
bound: Bound;
rotate: number;

View File

@@ -1,12 +1,14 @@
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 { isTopLevelBlock } from '@blocksuite/affine-shared/utils';
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 { ExportManager } from '../../../_common/export-manager/export-manager.js';
export const edgelessToBlob = async (
host: EditorHost,
options: {
@@ -19,12 +21,13 @@ export const edgelessToBlob = async (
const exportManager = host.std.get(ExportManager);
const bound = Bound.deserialize(edgelessElement.xywh);
const isBlock = isTopLevelBlock(edgelessElement);
const gfx = host.std.get(GfxControllerIdentifier);
return exportManager
.edgelessToCanvas(
options.surfaceRenderer,
bound,
undefined,
gfx,
isBlock ? [edgelessElement] : undefined,
isBlock ? undefined : [edgelessElement],
{ zoom: options.surfaceRenderer.viewport.zoom }