From 48b4b82edae398935443095a16cdb0deca8f30e1 Mon Sep 17 00:00:00 2001 From: Beka Westberg Date: Mon, 31 Jul 2023 17:48:50 +0000 Subject: [PATCH 1/4] chore: rename CopyData to ICopyData --- core/block_svg.ts | 4 ++-- core/clipboard.ts | 4 ++-- core/clipboard/block_paster.ts | 4 ++-- core/clipboard/registry.ts | 4 ++-- core/clipboard/workspace_comment_paster.ts | 4 ++-- core/interfaces/i_copyable.ts | 6 +++--- core/interfaces/i_paster.ts | 6 +++--- core/registry.ts | 4 ++-- core/workspace_comment_svg.ts | 4 ++-- 9 files changed, 20 insertions(+), 20 deletions(-) diff --git a/core/block_svg.ts b/core/block_svg.ts index e4053de0a9c..c190000eaed 100644 --- a/core/block_svg.ts +++ b/core/block_svg.ts @@ -37,7 +37,7 @@ import {FieldLabel} from './field_label.js'; import type {Input} from './inputs/input.js'; import type {IASTNodeLocationSvg} from './interfaces/i_ast_node_location_svg.js'; import type {IBoundedElement} from './interfaces/i_bounded_element.js'; -import type {CopyData, ICopyable} from './interfaces/i_copyable.js'; +import type {ICopyData, ICopyable} from './interfaces/i_copyable.js'; import type {IDraggable} from './interfaces/i_draggable.js'; import {IIcon} from './interfaces/i_icon.js'; import * as internalConstants from './internal_constants.js'; @@ -825,7 +825,7 @@ export class BlockSvg * @returns Copy metadata, or null if the block is an insertion marker. * @internal */ - toCopyData(): CopyData | null { + toCopyData(): ICopyData | null { if (this.isInsertionMarker_) { return null; } diff --git a/core/clipboard.ts b/core/clipboard.ts index 9cad96751c0..036c4a20ac2 100644 --- a/core/clipboard.ts +++ b/core/clipboard.ts @@ -7,12 +7,12 @@ import * as goog from '../closure/goog/goog.js'; goog.declareModuleId('Blockly.clipboard'); -import type {CopyData, ICopyable} from './interfaces/i_copyable.js'; +import type {ICopyData, ICopyable} from './interfaces/i_copyable.js'; import {BlockPaster} from './clipboard/block_paster.js'; import * as registry from './clipboard/registry.js'; /** Metadata about the object that is currently on the clipboard. */ -let copyData: CopyData | null = null; +let copyData: ICopyData | null = null; /** * Copy a block or workspace comment onto the local clipboard. diff --git a/core/clipboard/block_paster.ts b/core/clipboard/block_paster.ts index 60ca336a5db..b4d4ae1c5cf 100644 --- a/core/clipboard/block_paster.ts +++ b/core/clipboard/block_paster.ts @@ -6,7 +6,7 @@ import {BlockSvg} from '../block_svg.js'; import {registry} from '../clipboard.js'; -import {CopyData} from '../interfaces/i_copyable.js'; +import {ICopyData} from '../interfaces/i_copyable.js'; import {IPaster} from '../interfaces/i_paster.js'; import {State, append} from '../serialization/blocks.js'; import {Coordinate} from '../utils/coordinate.js'; @@ -31,6 +31,6 @@ export class BlockPaster implements IPaster { } } -export interface BlockCopyData extends CopyData {} +export interface BlockCopyData extends ICopyData {} registry.register(BlockPaster.TYPE, new BlockPaster()); diff --git a/core/clipboard/registry.ts b/core/clipboard/registry.ts index 5a8c8342ee2..39634234183 100644 --- a/core/clipboard/registry.ts +++ b/core/clipboard/registry.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {ICopyable, CopyData} from '../interfaces/i_copyable.js'; +import {ICopyable, ICopyData} from '../interfaces/i_copyable.js'; import type {IPaster} from '../interfaces/i_paster.js'; import * as registry from '../registry.js'; @@ -14,7 +14,7 @@ import * as registry from '../registry.js'; * @param type The type of the paster to register, e.g. 'block', 'comment', etc. * @param paster The paster to register. */ -export function register( +export function register( type: string, paster: IPaster, ) { diff --git a/core/clipboard/workspace_comment_paster.ts b/core/clipboard/workspace_comment_paster.ts index 7959802d6bc..32f2ac96cfc 100644 --- a/core/clipboard/workspace_comment_paster.ts +++ b/core/clipboard/workspace_comment_paster.ts @@ -5,7 +5,7 @@ */ import {IPaster} from '../interfaces/i_paster.js'; -import {CopyData} from '../interfaces/i_copyable.js'; +import {ICopyData} from '../interfaces/i_copyable.js'; import {Coordinate} from '../utils/coordinate.js'; import {WorkspaceSvg} from '../workspace_svg.js'; import {WorkspaceCommentSvg} from '../workspace_comment_svg.js'; @@ -30,6 +30,6 @@ export class WorkspaceCommentPaster } } -export interface WorkspaceCommentCopyData extends CopyData {} +export interface WorkspaceCommentCopyData extends ICopyData {} registry.register(WorkspaceCommentPaster.TYPE, new WorkspaceCommentPaster()); diff --git a/core/interfaces/i_copyable.ts b/core/interfaces/i_copyable.ts index d62d9ef83e2..e7f8b21bfa1 100644 --- a/core/interfaces/i_copyable.ts +++ b/core/interfaces/i_copyable.ts @@ -17,15 +17,15 @@ export interface ICopyable extends ISelectable { * @returns Copy metadata. * @internal */ - toCopyData(): CopyData | null; + toCopyData(): ICopyData | null; } export namespace ICopyable { - export interface CopyData { + export interface ICopyData { saveInfo: Object | Element; source: WorkspaceSvg; typeCounts: {[key: string]: number} | null; } } -export type CopyData = ICopyable.CopyData; +export type ICopyData = ICopyable.ICopyData; diff --git a/core/interfaces/i_paster.ts b/core/interfaces/i_paster.ts index 9653d25df50..cb2d079c230 100644 --- a/core/interfaces/i_paster.ts +++ b/core/interfaces/i_paster.ts @@ -6,10 +6,10 @@ import {Coordinate} from '../utils/coordinate.js'; import {WorkspaceSvg} from '../workspace_svg.js'; -import {ICopyable, CopyData} from './i_copyable.js'; +import {ICopyable, ICopyData} from './i_copyable.js'; /** An object that can paste data into a workspace. */ -export interface IPaster { +export interface IPaster { paste( copyData: U, workspace: WorkspaceSvg, @@ -18,6 +18,6 @@ export interface IPaster { } /** @returns True if the given object is a paster. */ -export function isPaster(obj: any): obj is IPaster { +export function isPaster(obj: any): obj is IPaster { return obj.paste !== undefined; } diff --git a/core/registry.ts b/core/registry.ts index 2893f3d0f96..6e974718c27 100644 --- a/core/registry.ts +++ b/core/registry.ts @@ -23,7 +23,7 @@ import type {Renderer} from './renderers/common/renderer.js'; import type {Theme} from './theme.js'; import type {ToolboxItem} from './toolbox/toolbox_item.js'; import {IPaster} from './interfaces/i_paster.js'; -import {CopyData, ICopyable} from './interfaces/i_copyable.js'; +import {ICopyData, ICopyable} from './interfaces/i_copyable.js'; /** * A map of maps. With the keys being the type and name of the class we are @@ -100,7 +100,7 @@ export class Type<_T> { static ICON = new Type('icon'); /** @internal */ - static PASTER = new Type>('paster'); + static PASTER = new Type>('paster'); } /** diff --git a/core/workspace_comment_svg.ts b/core/workspace_comment_svg.ts index ab57fd5eff7..24f6efd9688 100644 --- a/core/workspace_comment_svg.ts +++ b/core/workspace_comment_svg.ts @@ -23,7 +23,7 @@ import type {CommentMove} from './events/events_comment_move.js'; import * as eventUtils from './events/utils.js'; import type {IBoundedElement} from './interfaces/i_bounded_element.js'; import type {IBubble} from './interfaces/i_bubble.js'; -import type {CopyData, ICopyable} from './interfaces/i_copyable.js'; +import type {ICopyData, ICopyable} from './interfaces/i_copyable.js'; import * as Touch from './touch.js'; import {Coordinate} from './utils/coordinate.js'; import * as dom from './utils/dom.js'; @@ -568,7 +568,7 @@ export class WorkspaceCommentSvg * @returns Copy metadata. * @internal */ - toCopyData(): CopyData { + toCopyData(): ICopyData { return { saveInfo: this.toXmlWithXY(), source: this.workspace, From 9c08aab53b2413cd15bc7b8ba0ce80b503f8da01 Mon Sep 17 00:00:00 2001 From: Beka Westberg Date: Mon, 31 Jul 2023 18:01:03 +0000 Subject: [PATCH 2/4] fix: ICopyable data structures --- core/clipboard/block_paster.ts | 12 +++++++----- core/clipboard/workspace_comment_paster.ts | 11 ++++++----- core/interfaces/i_copyable.ts | 6 +----- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/core/clipboard/block_paster.ts b/core/clipboard/block_paster.ts index b4d4ae1c5cf..1181f2eb844 100644 --- a/core/clipboard/block_paster.ts +++ b/core/clipboard/block_paster.ts @@ -22,15 +22,17 @@ export class BlockPaster implements IPaster { ): BlockSvg | null { if (!workspace.isCapacityAvailable(copyData.typeCounts!)) return null; - const state = copyData.saveInfo as State; if (coordinate) { - state['x'] = coordinate.x; - state['y'] = coordinate.y; + copyData.saveInfo['x'] = coordinate.x; + copyData.saveInfo['y'] = coordinate.y; } - return append(state, workspace, {recordUndo: true}) as BlockSvg; + return append(copyData.saveInfo, workspace, {recordUndo: true}) as BlockSvg; } } -export interface BlockCopyData extends ICopyData {} +export interface BlockCopyData extends ICopyData { + saveInfo: State; + typeCounts: {[key: string]: number}; +} registry.register(BlockPaster.TYPE, new BlockPaster()); diff --git a/core/clipboard/workspace_comment_paster.ts b/core/clipboard/workspace_comment_paster.ts index 32f2ac96cfc..766e045cbc0 100644 --- a/core/clipboard/workspace_comment_paster.ts +++ b/core/clipboard/workspace_comment_paster.ts @@ -21,15 +21,16 @@ export class WorkspaceCommentPaster workspace: WorkspaceSvg, coordinate?: Coordinate, ): WorkspaceCommentSvg { - const state = copyData.saveInfo as Element; if (coordinate) { - state.setAttribute('x', `${coordinate.x}`); - state.setAttribute('y', `${coordinate.y}`); + copyData.saveInfo.setAttribute('x', `${coordinate.x}`); + copyData.saveInfo.setAttribute('y', `${coordinate.y}`); } - return WorkspaceCommentSvg.fromXmlRendered(state, workspace); + return WorkspaceCommentSvg.fromXmlRendered(copyData.saveInfo, workspace); } } -export interface WorkspaceCommentCopyData extends ICopyData {} +export interface WorkspaceCommentCopyData extends ICopyData { + saveInfo: Element; +} registry.register(WorkspaceCommentPaster.TYPE, new WorkspaceCommentPaster()); diff --git a/core/interfaces/i_copyable.ts b/core/interfaces/i_copyable.ts index e7f8b21bfa1..6035c97ce0b 100644 --- a/core/interfaces/i_copyable.ts +++ b/core/interfaces/i_copyable.ts @@ -7,7 +7,6 @@ import * as goog from '../../closure/goog/goog.js'; goog.declareModuleId('Blockly.ICopyable'); -import type {WorkspaceSvg} from '../workspace_svg.js'; import type {ISelectable} from './i_selectable.js'; export interface ICopyable extends ISelectable { @@ -15,16 +14,13 @@ export interface ICopyable extends ISelectable { * Encode for copying. * * @returns Copy metadata. - * @internal */ toCopyData(): ICopyData | null; } export namespace ICopyable { export interface ICopyData { - saveInfo: Object | Element; - source: WorkspaceSvg; - typeCounts: {[key: string]: number} | null; + paster: string; } } From bbc0d798a61cc4348567a36b1ec581da5c088f23 Mon Sep 17 00:00:00 2001 From: Beka Westberg Date: Mon, 31 Jul 2023 18:25:43 +0000 Subject: [PATCH 3/4] fix: switch clipboard over to use new copy data interfaces --- core/block_svg.ts | 8 +++---- core/clipboard.ts | 27 ++++++++++++++-------- core/clipboard/block_paster.ts | 2 +- core/clipboard/workspace_comment_paster.ts | 2 +- core/workspace_comment_svg.ts | 12 ++++++---- 5 files changed, 30 insertions(+), 21 deletions(-) diff --git a/core/block_svg.ts b/core/block_svg.ts index c190000eaed..2d78d0569f6 100644 --- a/core/block_svg.ts +++ b/core/block_svg.ts @@ -37,7 +37,7 @@ import {FieldLabel} from './field_label.js'; import type {Input} from './inputs/input.js'; import type {IASTNodeLocationSvg} from './interfaces/i_ast_node_location_svg.js'; import type {IBoundedElement} from './interfaces/i_bounded_element.js'; -import type {ICopyData, ICopyable} from './interfaces/i_copyable.js'; +import type {ICopyable} from './interfaces/i_copyable.js'; import type {IDraggable} from './interfaces/i_draggable.js'; import {IIcon} from './interfaces/i_icon.js'; import * as internalConstants from './internal_constants.js'; @@ -62,6 +62,7 @@ import type {WorkspaceSvg} from './workspace_svg.js'; import * as renderManagement from './render_management.js'; import * as deprecation from './utils/deprecation.js'; import {IconType} from './icons/icon_types.js'; +import {BlockCopyData, BlockPaster} from './clipboard/block_paster.js'; /** * Class for a block's SVG representation. @@ -823,18 +824,17 @@ export class BlockSvg * Encode a block for copying. * * @returns Copy metadata, or null if the block is an insertion marker. - * @internal */ - toCopyData(): ICopyData | null { + toCopyData(): BlockCopyData | null { if (this.isInsertionMarker_) { return null; } return { + paster: BlockPaster.TYPE, saveInfo: blocks.save(this, { addCoordinates: true, addNextBlocks: false, }) as blocks.State, - source: this.workspace, typeCounts: common.getBlockTypeCounts(this, true), }; } diff --git a/core/clipboard.ts b/core/clipboard.ts index 036c4a20ac2..627d356bcbe 100644 --- a/core/clipboard.ts +++ b/core/clipboard.ts @@ -9,11 +9,15 @@ goog.declareModuleId('Blockly.clipboard'); import type {ICopyData, ICopyable} from './interfaces/i_copyable.js'; import {BlockPaster} from './clipboard/block_paster.js'; +import * as globalRegistry from './registry.js'; +import {WorkspaceSvg} from './workspace_svg.js'; import * as registry from './clipboard/registry.js'; /** Metadata about the object that is currently on the clipboard. */ let copyData: ICopyData | null = null; +let source: WorkspaceSvg | null = null; + /** * Copy a block or workspace comment onto the local clipboard. * @@ -29,6 +33,7 @@ export function copy(toCopy: ICopyable) { */ function copyInternal(toCopy: ICopyable) { copyData = toCopy.toCopyData(); + source = (toCopy as any).workspace ?? null; } /** @@ -43,17 +48,16 @@ export function paste(): ICopyable | null { } // Pasting always pastes to the main workspace, even if the copy // started in a flyout workspace. - let workspace = copyData.source; - if (workspace.isFlyout) { + let workspace = source; + if (workspace?.isFlyout) { workspace = workspace.targetWorkspace!; } - if ( - copyData.typeCounts && - workspace.isCapacityAvailable(copyData.typeCounts) - ) { - return workspace.paste(copyData.saveInfo); - } - return null; + if (!workspace) return null; + return ( + globalRegistry + .getObject(globalRegistry.Type.PASTER, copyData.paster, false) + ?.paste(copyData, workspace) ?? null + ); } /** @@ -74,8 +78,11 @@ export function duplicate(toDuplicate: ICopyable): ICopyable | null { function duplicateInternal(toDuplicate: ICopyable): ICopyable | null { const oldCopyData = copyData; copy(toDuplicate); + if (!copyData || !source) return null; const pastedThing = - toDuplicate.toCopyData()?.source?.paste(copyData!.saveInfo) ?? null; + globalRegistry + .getObject(globalRegistry.Type.PASTER, copyData.paster, false) + ?.paste(copyData, source) ?? null; copyData = oldCopyData; return pastedThing; } diff --git a/core/clipboard/block_paster.ts b/core/clipboard/block_paster.ts index 1181f2eb844..4838f6272b1 100644 --- a/core/clipboard/block_paster.ts +++ b/core/clipboard/block_paster.ts @@ -5,7 +5,7 @@ */ import {BlockSvg} from '../block_svg.js'; -import {registry} from '../clipboard.js'; +import * as registry from './registry.js'; import {ICopyData} from '../interfaces/i_copyable.js'; import {IPaster} from '../interfaces/i_paster.js'; import {State, append} from '../serialization/blocks.js'; diff --git a/core/clipboard/workspace_comment_paster.ts b/core/clipboard/workspace_comment_paster.ts index 766e045cbc0..85622764ce8 100644 --- a/core/clipboard/workspace_comment_paster.ts +++ b/core/clipboard/workspace_comment_paster.ts @@ -9,7 +9,7 @@ import {ICopyData} from '../interfaces/i_copyable.js'; import {Coordinate} from '../utils/coordinate.js'; import {WorkspaceSvg} from '../workspace_svg.js'; import {WorkspaceCommentSvg} from '../workspace_comment_svg.js'; -import {registry} from '../clipboard.js'; +import * as registry from './registry.js'; export class WorkspaceCommentPaster implements IPaster diff --git a/core/workspace_comment_svg.ts b/core/workspace_comment_svg.ts index 24f6efd9688..55236df6439 100644 --- a/core/workspace_comment_svg.ts +++ b/core/workspace_comment_svg.ts @@ -23,7 +23,7 @@ import type {CommentMove} from './events/events_comment_move.js'; import * as eventUtils from './events/utils.js'; import type {IBoundedElement} from './interfaces/i_bounded_element.js'; import type {IBubble} from './interfaces/i_bubble.js'; -import type {ICopyData, ICopyable} from './interfaces/i_copyable.js'; +import type {ICopyable} from './interfaces/i_copyable.js'; import * as Touch from './touch.js'; import {Coordinate} from './utils/coordinate.js'; import * as dom from './utils/dom.js'; @@ -32,6 +32,10 @@ import {Svg} from './utils/svg.js'; import * as svgMath from './utils/svg_math.js'; import {WorkspaceComment} from './workspace_comment.js'; import type {WorkspaceSvg} from './workspace_svg.js'; +import { + WorkspaceCommentCopyData, + WorkspaceCommentPaster, +} from './clipboard/workspace_comment_paster.js'; /** Size of the resize icon. */ const RESIZE_SIZE = 8; @@ -566,13 +570,11 @@ export class WorkspaceCommentSvg * Encode a comment for copying. * * @returns Copy metadata. - * @internal */ - toCopyData(): ICopyData { + toCopyData(): WorkspaceCommentCopyData { return { + paster: WorkspaceCommentPaster.TYPE, saveInfo: this.toXmlWithXY(), - source: this.workspace, - typeCounts: null, }; } From 0f81bf22b22b40d1295ae120b260d62a1dc7f49e Mon Sep 17 00:00:00 2001 From: Beka Westberg Date: Tue, 1 Aug 2023 16:42:42 +0000 Subject: [PATCH 4/4] chore: rename saveInfo to somthing more descriptive --- core/block_svg.ts | 2 +- core/clipboard/block_paster.ts | 10 ++++++---- core/clipboard/workspace_comment_paster.ts | 11 +++++++---- core/workspace_comment_svg.ts | 2 +- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/core/block_svg.ts b/core/block_svg.ts index 2d78d0569f6..ff251b2efbc 100644 --- a/core/block_svg.ts +++ b/core/block_svg.ts @@ -831,7 +831,7 @@ export class BlockSvg } return { paster: BlockPaster.TYPE, - saveInfo: blocks.save(this, { + blockState: blocks.save(this, { addCoordinates: true, addNextBlocks: false, }) as blocks.State, diff --git a/core/clipboard/block_paster.ts b/core/clipboard/block_paster.ts index 4838f6272b1..3ed8383db25 100644 --- a/core/clipboard/block_paster.ts +++ b/core/clipboard/block_paster.ts @@ -23,15 +23,17 @@ export class BlockPaster implements IPaster { if (!workspace.isCapacityAvailable(copyData.typeCounts!)) return null; if (coordinate) { - copyData.saveInfo['x'] = coordinate.x; - copyData.saveInfo['y'] = coordinate.y; + copyData.blockState['x'] = coordinate.x; + copyData.blockState['y'] = coordinate.y; } - return append(copyData.saveInfo, workspace, {recordUndo: true}) as BlockSvg; + return append(copyData.blockState, workspace, { + recordUndo: true, + }) as BlockSvg; } } export interface BlockCopyData extends ICopyData { - saveInfo: State; + blockState: State; typeCounts: {[key: string]: number}; } diff --git a/core/clipboard/workspace_comment_paster.ts b/core/clipboard/workspace_comment_paster.ts index 85622764ce8..b9933f5a18c 100644 --- a/core/clipboard/workspace_comment_paster.ts +++ b/core/clipboard/workspace_comment_paster.ts @@ -22,15 +22,18 @@ export class WorkspaceCommentPaster coordinate?: Coordinate, ): WorkspaceCommentSvg { if (coordinate) { - copyData.saveInfo.setAttribute('x', `${coordinate.x}`); - copyData.saveInfo.setAttribute('y', `${coordinate.y}`); + copyData.commentState.setAttribute('x', `${coordinate.x}`); + copyData.commentState.setAttribute('y', `${coordinate.y}`); } - return WorkspaceCommentSvg.fromXmlRendered(copyData.saveInfo, workspace); + return WorkspaceCommentSvg.fromXmlRendered( + copyData.commentState, + workspace, + ); } } export interface WorkspaceCommentCopyData extends ICopyData { - saveInfo: Element; + commentState: Element; } registry.register(WorkspaceCommentPaster.TYPE, new WorkspaceCommentPaster()); diff --git a/core/workspace_comment_svg.ts b/core/workspace_comment_svg.ts index 55236df6439..4e1a726112d 100644 --- a/core/workspace_comment_svg.ts +++ b/core/workspace_comment_svg.ts @@ -574,7 +574,7 @@ export class WorkspaceCommentSvg toCopyData(): WorkspaceCommentCopyData { return { paster: WorkspaceCommentPaster.TYPE, - saveInfo: this.toXmlWithXY(), + commentState: this.toXmlWithXY(), }; }