JSON と JavaScript

Blockly では、ブロックを定義する方法が 2 つあります。Key-Value ペアを使用する JSON オブジェクトと、Blockly の API を呼び出す JavaScript 関数です。JSON 形式は、ローカライズを簡素化し、読み取りと書き込みが容易であるため、推奨されます。ただし、ミュータタやバリデータなどの高度な機能を直接定義することはできません。これらは JavaScript で記述する必要があります。通常は拡張機能として記述します。

JSON または JavaScript を使用する

このブロックは、次の処理を行います。

string_length ブロック。

は、次のように JSON または JavaScript で定義できます。

JSON

Blockly.common.defineBlocksWithJsonArray([{
  "type": "string_length",
  "message0": 'length of %1',
  "args0": [
    {
      "type": "input_value",
      "name": "VALUE",
      "check": "String"
    }
  ],
  "output": "Number",
  "colour": 160,
  "tooltip": "Returns number of letters in the provided text.",
  "helpUrl": "http://www.w3schools.com/jsref/jsref_length_string.asp"
}]);

defineBlocksWithJsonArray は、init 関数を使用して各 JSON オブジェクトをブロック定義オブジェクトに変換します。これらのオブジェクトは Blockly.Blocks に保存されます。

JavaScript

Blockly.Blocks['string_length'] = {
  init: function() {
    this.appendValueInput('VALUE')
        .setCheck('String')
        .appendField('length of');
    this.setOutput(true, 'Number');
    this.setColour(160);
    this.setTooltip('Returns number of letters in the provided text.');
    this.setHelpUrl('http://www.w3schools.com/jsref/jsref_length_string.asp');
  }
};

ブロック定義オブジェクトはブロック オブジェクトに混在するため、キーワード this は作成される実際のブロックを参照します。

どちらの方法でも、ブロック定義オブジェクトがブロックタイプ名(string_length)のキーで Blockly.Blocks に保存されます。ブロック定義オブジェクトには、ブロックの形状を定義する単一のメソッド(init)があります。

JSON と JavaScript を組み合わせる

JSON 形式は主に、ブロックの外観を定義するために使用されます。バリデータやミュータタなど、関数の定義が必要な一部の機能は直接定義できません。この問題を解決するには、ブロックのできるだけ多くの部分を JSON で定義し、残りの部分には JavaScript を使用します。

次の例では、init 関数を使用してブロック定義を作成します。この関数は、jsonInit を使用して JSON オブジェクトを読み込み、JavaScript API を使用して動的ツールチップを定義します。

JavaScript

// Define the block structure in JSON.
var mathChangeJson = {
  "message0": "change %1 by %2",
  "args0": [
    {"type": "field_variable", "name": "VAR", "variable": "item", "variableTypes": [""]},
    {"type": "input_value", "name": "DELTA", "check": "Number"}
  ],
  "previousStatement": null,
  "nextStatement": null,
  "colour": 230
};

Blockly.Blocks['math_change'] = {
  init: function() {
    // Use jsonInit to load the JSON block structure.
    this.jsonInit(mathChangeJson);

    // Use JavaScript to define a tooltip function.
    // Assign 'this' to a variable for use in the tooltip closure below.
    var thisBlock = this;
    this.setTooltip(function() {
      return 'Add a number to variable "%1".'.replace('%1',
          thisBlock.getFieldValue('VAR'));
    });
  }
};

ブロック定義 API

このセクションでは、カスタム ブロックの定義に使用されるオブジェクトと関数の概要について説明します。

Blockly.Blocks

Blockly.Blocks は、ブロック定義を格納するオブジェクトです。キーはブロックタイプの名前で、値はブロック定義オブジェクトです。JavaScript でブロックを定義する場合は、Blockly.Blocks を使用します。

Blockly.Blocks['my_block'] = {
  init: function() {/* ... */},
  onchange: function() {/* ... */},
  // ...
}

よくある間違いは、Blockly.Blocks がブロックを格納していると想定して、次のようなことを試すことです。これは、Blockly.Blocks がブロックではなくブロック定義を格納するため失敗します。

// Fails with "Blockly.Blocks.my_block.setColour is not a function".
Blockly.Blocks['my_block'].setColour(150);

defineBlocksWithJsonArray

defineBlocksWithJsonArray は、JSON オブジェクトの配列を受け取り、ブロック定義を作成して Blockly.Blocks に追加します。

Blockly.common.defineBlocksWithJsonArray([
  {
    type: 'my_block1',
    // ...
  }
  {
    type: 'my_block3',
    // ...
  }
  {
    type: 'my_block2',
    // ...
  }
]);

createBlockDefinitionsFromJsonArray と defineBlocks

createBlockDefinitionsFromJsonArray は、JSON オブジェクトの配列を受け取り、ブロックタイプ名をブロック定義にマッピングするオブジェクトを返します。これは通常、defineBlocks とともに使用され、ブロック定義を Blockly.Blocks に追加します。

const myBlockDefinitions = Blockly.common.createBlockDefinitionsFromJsonArray([
  {
    type: 'my_block1',
    // ...
  }
  {
    type: 'my_block3',
    // ...
  }
  {
    type: 'my_block2',
    // ...
  }
]);
Blockly.common.defineBlocks(myBlockDefinitions);

Block.jsonInit

jsonInit は JSON オブジェクトを受け取り、Block で対応するメソッドを呼び出します。たとえば、Key-Value ペア colour: 150 を含む JSON オブジェクトは、this.setColour(150) の呼び出しになります。init 関数で jsonInit を使用して JSON オブジェクトを読み込みます。

var myJson = {
  // ...
};

Blockly.Blocks['my_block'] = {
  init: function() {
    this.jsonInit(myJson);
    // The rest of the init function.
  }
};