將外掛程式欄位新增至 Block Factory

Blockly Developer Tools 可讓您使用區塊建立自訂模塊!除了核心 Blockly 隨附的欄位之外,也支援以外掛程式形式發布的欄位。如果您建立了自訂欄位,可以按照本指南,對該欄位新增對封鎖工廠的支援。自訂欄位必須在 npm 發布,才能新增對其支援。您還需要承諾更新欄位,以配合 Blockly 的變更,否則我們未來可能需要將其從 Block Factory 移除。

區塊工廠上的開發

Block Factory 的原始碼位於 examples/developer-tools 目錄的區塊範例存放區中。

如要透過區塊範例提交對開發人員工具的變更,您需要按照一般步驟操作,在區塊樣本中進行開發。不過,與使用外掛程式不同,您必須直接從 examples/developer-tools 目錄執行 npm install,而不是在區塊範例的根層級執行。

安裝外掛程式

為了讓 Block Factory 在預覽畫面中顯示自訂欄位,您需要安裝自訂欄位。將您的欄位新增為開發人員工具的 npm 依附元件。接著,在 developer-tools/src/blocks/index.ts 中註冊此 API 或執行其他必要的設定工作。

為欄位建立區塊

由於 Block Factory 使用區塊來建立自訂區塊,因此您必須建立代表自訂欄位的區塊。

建立區塊定義

您需要為欄位設計區塊,如要取得中繼,甚至可以使用 Block Factory!該區塊應允許使用者調整欄位需要的設定,例如預設值和名稱。將這個區塊定義新增至 developer-tools/src/blocks/fields.ts,並匯入 developer-tools/src/blocks/index.ts

將區塊新增至工具箱

接下來,您需要將這個區塊新增至工具箱定義,方便使用者存取。工具箱定義位於 developer-tools/src/toolbox.ts。區塊應新增至「欄位」類別

程式碼產生器

Block Factory 會使用您熟悉的 Blockly 程式碼產生器系統。每個區塊都有區塊程式碼產生器,可擷取由 Block Factory 產生的每種輸出內容類型,而父項區塊會將子項區塊的程式碼組合成正確的輸出內容。如要新增自訂欄位的支援,您必須為每個 CodeGenerator 類別新增區塊程式碼產生器函式。

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})`;
};

使用者從 BlockFactory 工具箱的「欄位」類別拖曳的角度區塊,當中有兩個欄位:

  • FIELDNAME:使用者可以在自訂區塊中設定欄位名稱
  • 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);
};

程式碼標頭

程式碼標頭產生器會建立區塊工廠中顯示的程式碼標頭輸出內容。根據使用者想要載入程式碼的方式,輸出的輸出內容可在 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 等),以及使用者為欄位命名的名稱。

測試

寫入上述所有部分後,應該就能在 blockly-samples/examples/developer-tools 目錄中執行 npm start 來啟動 Block Factory。您應該可以從欄位類別拖曳區塊、將區塊新增至區塊的輸入項目,然後觀察輸出結果的變化。請檢查區塊的預覽畫面,以及每個輸出區段的程式碼是否正確。