复制和粘贴

Blockly 支持对其许多内置组件(例如代码块、工作区注释和气泡)执行复制、剪切和粘贴操作。

默认剪贴板行为

Blockly 核心附带键盘快捷键,可用于剪切、复制或粘贴代码块、工作区注释以及实现 ICopyableIDraggableIDeletable 接口的任何其他组件。它还提供了一个用于复制块的上下文菜单选项。您可以根据需要修改或移除这些默认快捷方式和菜单项。

在默认剪贴板实现中,可复制的对象只能粘贴到复制来源的工作区,或者粘贴到从弹出式菜单复制到的目标工作区。这意味着您可以将某个弹出式菜单中的代码块复制到该弹出式菜单的目标工作区中,但无法将某个主工作区中的代码块复制到另一个主工作区中。

跨工作区和标签页复制和粘贴

如果您想允许用户将代码块从一个工作区复制并粘贴到另一个工作区,甚至粘贴到在另一个标签页中运行的应用副本中的工作区,可以安装 @blockly/plugin-cross-tab-copy-paste 插件

自定义剪贴板行为

如果您想要不同的行为,可以卸载 Blockly 附带的键盘快捷键,然后安装以不同方式运行的其他键盘快捷键,从而实现自定义剪贴板。为了方便起见,您可以使用 Blockly.clipboard 命名空间中的方法进行复制、粘贴或更精细的控制,例如设置对象复制自的工作区。

可复制的自定义对象

通过使用以下五个接口,任意项都可以与复制/粘贴系统兼容:ICopyableIDraggableIDeletable(用于表示可复制的对象)、ICopyData(用于表示已复制的对象)以及 IPaster(用于表示可将复制数据转换回可复制的对象)。每种类型的 ICopyable 都需要一个关联的 IPaster 来粘贴相应数据。

任何实现 ICopyableIDraggableIDeletable 且具有相应 IPasterICopyData 的对象都会自动与默认剪贴板系统搭配使用。

在极少数情况下,您可能需要实现自定义可复制对象或自定义粘贴器(例如多选插件),因为可复制对象是渲染的,而您无法向 Blockly 添加新的渲染对象。工作区中唯一可以存在的已渲染对象是块、气泡和工作区注释。

实现可复制

如需创建可复制的对象,您需要实现 ICopyableIDraggableIDeletable 接口。后两个接口是必需的,以便可以操纵和删除粘贴的对象。

可选择

ICopyable 接口扩展了 ISelectable 接口,这意味着您还需要实现这些方法和属性。

必须可供选择,因为键盘快捷键会查看所选对象,以确定要复制的内容。

class MyCopyable implements ISelectable {
  constructor(workspace) {
    this.id = Blockly.utils.idGenerator.genUid();
    this.workspace = workspace;
  }

  select() {
    // Visually indicate this draggable is selected.
  }

  unselect() {
    // Visually indicate this draggable is not selected.
  }
}

可复制

ICopyable 接口本身只有一个必需的方法 toCopyData,该方法会返回可复制对象状态的 JSON 可序列化表示形式,可用于重新创建可复制对象。

复制数据还必须包含 paster 属性,该属性包含与应粘贴此复制数据的粘贴器相关联的已注册字符串名称。如需详细了解粘贴器,请参阅实现粘贴器

class MyCopyable implements ICopyable {
  constructor(workspace, state) {
    this.workspace = workspace;
    this.myState = state;
  }

  toCopyData() {
    return {
      // This string matches the string used to register the paster.
      paster: 'MY_PASTER',
      state: this.myState,
    };
  }
}

ICopyable 还有一个可选方法 isCopyable,用于返回对象当前是否可复制。

可拖动和可删除

如需了解如何实现 IDraggableIDeletable,请参阅自定义可拖动对象

实现粘贴器

如需创建粘贴器,您需要实现 IPaster 接口。它只有一个方法 paste,该方法会接收要粘贴的内容的复制数据、要粘贴内容的工作区以及一个可选的坐标(即粘贴内容的位置)。

class MyPaster implements IPaster {
  paste(copyData, workspace, coordinate) {
    return new MyCopyable(workspace, copyData.state);
    // Optionally position the copyable at the passed coordinate.
    // Optionally select the copyable after it is pasted.
  }
}

注册

实现粘贴器后,您需要注册它,以便能够从其 paster 属性中找到与给定复制数据相关联的粘贴器。

// This string matches the string assigned to the 'paster' property.
Blockly.clipboard.registry.register('MY_PASTER', new MyPaster());