向 Block Factory 添加插件字段

借助 Blockly 开发者工具,您可以使用各种块创建自定义块!除了核心 Blockly 附带的字段之外,它还支持以插件形式发布的字段。如果您创建了自定义字段 可以按照本指南向 Block Factory 添加对它的支持。自定义 字段必须在 npm 上发布,然后才能添加对它的支持。您还需要承诺更新您的字段,以跟上 Blockly 的变化,否则我们日后可能需要将其从 Block Factory 中移除。

在 Block Factory 上进行开发

Block Factory 的源代码位于 blockly-samples 中 examples/developer-tools 中的代码库 目录。

若要提交对块样本中的开发者工具所做的更改,您需要 按照典型步骤开发 blockly-samples。不过,与使用插件不同,您需要直接从 examples/developer-tools 目录运行 npm install,而不是在 blockly-samples 的根级别运行。

安装插件

为了让 Block Factory 在预览中显示自定义字段, 您需要安装自定义字段将您的字段添加为 developer-tools 的 npm 依赖项。然后,在 developer-tools/src/blocks/index.ts 中注册该监听器或执行任何其他必要的设置工作。

为该字段创建块

由于 Block 工厂使用块来创建自定义块,因此您需要一个表示自定义字段的块。

创建块定义

您需要为字段设计块;如果您想获取元数据,甚至可以使用 Block Factory 来设计元数据!该块应允许用户配置 字段所需的设置,例如默认值和名称。添加此项 屏蔽定义 developer-tools/src/blocks/fields.ts,并将其导入 developer-tools/src/blocks/index.ts

向工具箱中添加数据块

接下来,您需要将此块添加到 Toolbox 定义中,以便用户可以访问该块。工具箱定义位于 developer-tools/src/toolbox.ts。您的代码块应添加到“字段”类别。

代码生成器

Block Factory 通过使用您已有的代码生成器系统来运作 每个分块都有一个分块代码生成器,用于生成分块工厂生成的每种类型的输出,父分块会将子分块的代码组装成正确的输出。添加对自定义 您需要为每个代码添加区块码生成器函数 生成器类。

output-generators/fields 目录中。您将在此文件中添加以下每个生成器的代码块生成器。在 blocks/index.ts 文件中导入此文件,以便将块代码生成器函数加载到应用中。

JavaScript 定义

javascriptDefinitionGenerator 会创建将包含在 包含自定义字段的块的 JavaScript 定义。通常 这意味着块代码生成器应返回一行代码,如 .appendField(new YourFieldConstructor(arg1, arg2), 'userSpecifiedName')。请注意,这行代码包含英文分号,因为包含多个字段的输入将会将对 appendField 的多次调用串联在一起。构造函数中的实参会从用户在字段块上设置的值中提取。以下是适用于 FieldAngle 的此代码块生成器的示例:

javascriptDefinitionGenerator.forBlock['field_angle'] = function (
  block: Blockly.Block,
  generator: JavascriptDefinitionGenerator,
): string {
  const name = generator.quote_(block.getFieldValue('FIELDNAME'));
  const angle = block.getFieldValue('ANGLE');
  return `.appendField(new FieldAngle(${angle}), ${name})`;
};

用户从“Block Factory”工具箱的“Fields”(字段)类别中拖动的角度块上有两个字段:

  • FIELDNAME:用户可以在自定义块中设置字段的名称
  • ANGLE:用户可以设置默认角度值

在此块码生成器中,我们会获取默认的 angle 值,并将其作为 FieldAngle 构造函数的唯一参数。字段名称始终会传递 作为 appendField 的第二个参数。

JSON 定义

jsonDefinitionGenerator 也与之类似,但这会输出 JSON 文件的一部分。 。通常,此代码是一个 JSON 对象,其中包含:

  • type:对应于 Blockly 字段注册表中的字段名称
  • name:用户可以在自定义块中设置字段的名称
  • 字段的 JSON 初始化方法所需的任何其他自定义属性。

下面是 FieldAngle 中的示例:

jsonDefinitionGenerator.forBlock['field_angle'] = function (
  block: Blockly.Block,
  generator: JsonDefinitionGenerator,
): string {
  const code = {
    type: 'field_angle',
    name: block.getFieldValue('FIELDNAME'),
    angle: block.getFieldValue('ANGLE'),
  };
  return JSON.stringify(code);
};

代码标头

代码头生成器会创建 Block 工厂中显示的代码头输出。此输出可以在 esmodule 导入和脚本标记之间切换, 具体取决于用户希望以何种方式加载代码,因此 不同的生成器实例:每种情况对应一个。您需要添加一个区块代码 生成器。下面是一个 FieldAngle 示例:

importHeaderGenerator.forBlock['field_angle'] = function (
  block: Blockly.Block,
  generator: CodeHeaderGenerator,
): string {
  generator.addHeaderLine(
    `import {registerFieldAngle, FieldAngle} from '@blockly/field-angle';`,
  );
  generator.addHeaderLine(`registerFieldAngle();`);
  return '';
};

scriptHeaderGenerator.forBlock['field_angle'] = function (
  block: Blockly.Block,
  generator: CodeHeaderGenerator,
): string {
  generator.addHeaderLine(
    `<script src="https://unpkg.com/@blockly/field-angle"></script>`,
  );
  generator.addHeaderLine(`registerFieldAngle();`);
  return '';
};

这些生成器有一个名为 addHeaderLine 的方法,可让您指定在代码中使用字段之前应调用的代码行。通常,这包括导入字段或通过脚本标记加载字段等工作,还可能调用一个函数,以便将字段注册到 Blockly 的字段注册表。

对于这两个块码生成器,所有代码都应通过调用 发送至 addHeaderLine。此函数可确保每个标题行仅显示一次,即使您在一个自定义块中多次使用自定义字段块也是如此。代码块生成器应返回空字符串。

生成器存根

最后,我们有一个生成器,用于为字段创建生成器桩。在此代码块生成器中,您将编写代码来生成代码,以帮助用户编写代码来生成代码。还不清楚?这比听起来要简单得多!

自定义块的生成器桩包含一个预创建的变量 来代表块上的每个字段然后是用户必须执行的 TODO 以便将所有这些变量汇编到最终的代码字符串中, 系统就会返回相应的自定义屏蔽设置这通常意味着 只需返回用于创建此自定义变量的代码行即可。假设用户正在制作一个自定义块,用于向画布添加阳光。他们向该代码块添加了一个角度字段,并将其命名为 "SUN_DIRECTION"。此代码块的生成器桩将包含 const angle_sun_direction = block.getFieldValue("SUN_DIRECTION"); 行。这是角度字段的块代码生成器需要返回的代码行:

generatorStubGenerator.forBlock['field_angle'] = function (
  block: Blockly.Block,
  generator: GeneratorStubGenerator,
): string {
  const name = block.getFieldValue('FIELDNAME');
  const fieldVar = generator.createVariableName('angle', name);
  return `const ${fieldVar} = block.getFieldValue(${generator.quote_(
    name,
  )});\n`;
};

要获取变量的标准化名称,您可以调用 generator.createVariableName 并传入字段类型(例如 anglenumber 等)以及用户为其字段命名的名称。

测试应用

编写好所有这些部分后,您应该能够启动 Block 通过在 blockly-samples/examples/developer-tools 中运行 npm start 来实现工厂 目录。您应该能够从字段类别中拖动您的块,将其添加到块上的输入,然后观察输出变化。检查该代码块的预览是否正常,以及每个输出部分的代码是否正确。