2019 年 7 月(リリース 2.20190722)に、よりコード化されたフィールド API が追加されました。可能な限り下位互換性を持たせることを目的としています。つまり、2019 年 7 月より前にカスタム フィールドを作成した場合、そのフィールドは引き続き機能する可能性が高いということです。カスタム フィールドをアップグレードする必要があるかどうかを判断する前に、危険な領域のセクションを読み、フィールドを徹底的にテストする必要があります。
2019 年 7 月以前はフィールド間の標準化が不足していたため、デベロッパーが行う必要のあるすべての変更を網羅することは困難です。このドキュメントでは、考えられるすべての変更を網羅しようとしていますが、このドキュメントで説明されていない内容については、アップグレードのサポートを受けるのセクションをご覧ください。
危険区域
危険な領域は、API が変更された既知の場所であり、フィールドが破損する可能性があります。
Blockly.Field.register
フィールドは Blockly.Field.register();
を介して登録されなくなりました。登録を処理する fieldRegistry
Namespace が追加されました。
Blockly.Field.register('my_field_name', myFieldClass);
置き換えると次のようになります。
Blockly.fieldRegistry.register('my_field_name', myFieldClass);
setText
setText
関数は Blockly コアによって呼び出されなくなったため、setText
関数にロジックが含まれている場合は、値処理関数群、getText
関数、レンダリング関数に移動する必要があります(setText
関数が何をしているかによって異なります)。
CustomFields.UpgradeField.prototype.setText = function(newText) {
// Do validation.
if (typeof newText != 'string' || newText === this.text_) {
return;
}
// Fire event.
if (this.sourceBlock_ && Blockly.Events.isEnabled()) {
Blockly.events.fire(new Blockly.Events.BlockChange(
this.sourceBlock_, 'field', this.name, this.text_, newText
));
}
// Update text value.
this.text_ = 'prefix' + newText;
// Rerender.
this.size_.width = 0;
};
置き換えると次のようになります。
CustomFields.UpgradeField.prototype.doClassValidation_ = function(newValue) {
if (typeof newValue != 'string') {
return null;
}
return newValue;
};
CustomFields.UpgradeField.prototype.getText = function() {
return 'prefix' + this.value_;
}
Blockly は次の処理を自動的に行います。
- 新しい値が古い値と異なるかどうかを確認します。
- 値を更新しています。
- 変更イベントをトリガーします。
- フィールドを再レンダリングします。
次の処理が必要になります。
- 値の検証(
doClassValidation_
)。 - フィールド テキスト(
getText
)。 - Field UI
おすすめのアップグレード
推奨されるアップグレードは、フィールド API が変更された場所です。変更しない場合でも、フィールドは引き続き機能する可能性が高くなります。
SERIALIZABLE
EDITABLE
プロパティと SERIALIZABLE
プロパティの詳細については、編集可能でシリアル化可能なプロパティをご覧ください。
CustomFields.UpgradeField.prototype.SERIALIZABLE = true;
以下の警告は無視できますが、SERIALIZABLE
プロパティを定義することで解決できます。
Detected an editable field that was not serializable. Please define
SERIALIZABLE property as true on all editable custom fields. Proceeding
with serialization.
上記の警告は、Blockly がフィールドをシリアル化したいと考えている(EDITABLE
プロパティが true であるため)が、SERIALIZABLE
プロパティが定義されるまで確信できないことを意味します。このままにしておいても、すべてが正常に機能し、フィールドはシリアル化されますが、コンソールに警告が表示されます。
size_.width
this.size_.width = 0;
置き換えると次のようになります。
this.isDirty_ = true;
次の警告は無視できますが、size_.width
プロパティではなく isDirty_
プロパティを設定することで解決できます。
Deprecated use of setting size_.width to 0 to rerender a field. Set
field.isDirty_ to true instead.
上記の警告は、Blockly がフィールドの再レンダリングに古いメソッドが使用されていることを検出し、新しいメソッドを使用することを推奨していることを意味します。
isDirty_
プロパティの詳細については、isDirty_ をご覧ください。
init
init
関数は、サブクラス内の重複コードを減らすためにテンプレート関数に変換されました。
CustomFields.UpgradeField.prototype.init = function() {
if (this.fieldGroup_) {
// Already initialized once.
return;
}
// Call superclass.
CustomFields.UpgradeField.superClass_.init.call(this);
// Create DOM elements.
this.extraDom_ = Blockly.utils.dom.createSvgElement('image',
{
'height': '10px',
'width': '10px'
});
this.extraDom_.setAttributeNS('http://www.w3.org/1999/xlink',
'xlink:href', 'image.svg');
this.extraDom_.style.cursor = 'pointer';
this.fieldGroup_.appendChild(this.extraDom_);
// Bind events.
this.mouseOverWrapper_ =
Blockly.browserEvents.bind(
this.getClickTarget_(), 'mouseover', this, this.onMouseOver_);
this.mouseOutWrapper_ =
Blockly.browserEvents.bind(
this.getClickTarget_(), 'mouseout', this, this.onMouseOut_);
// Render.
this.setValue(this.getValue());
};
置き換えると次のようになります。
CustomFields.UpgradeField.prototype.initView = function() {
CustomFields.UpgradeField.superClass_.initView.call(this);
this.extraDom_ = Blockly.utils.dom.createSvgElement('image',
{
'height': '10px',
'width': '10px'
});
this.extraDom_.setAttributeNS('http://www.w3.org/1999/xlink',
'xlink:href', 'image.svg');
this.extraDom_.style.cursor = 'pointer';
this.fieldGroup_.appendChild(this.extraDom_);
};
CustomFields.UpgradeField.prototype.bindEvents_ = function() {
CustomFields.UpgradeField.superClass_.bindEvents_.call(this);
this.mouseOverWrapper_ =
Blockly.bindEvent_(
this.getClickTarget_(), 'mouseover', this, this.onMouseOver_);
this.mouseOutWrapper_ =
Blockly.bindEvent_(
this.getClickTarget_(), 'mouseout', this, this.onMouseOut_);
};
つまり、Blockly で次の処理が自動的に行われるようになります。
- フィールドがすでに初期化されているかどうかを確認します。
fieldGroup_
を作成します。- フィールドのレンダリング。
- ツールチップのバインディングとエディタ イベントの表示。
次の処理が必要になります。
- 追加の DOM 要素(
initView
)を追加します。 - 追加のイベント バインディング(
bindEvents_
)を追加します。 - イベント バインディング(
dispose
)の破棄。
onMouseDown_
CustomFields.UpgradeField.prototype.onMouseDown_ = function(e) {
// ...
};
置き換えると次のようになります。
CustomFields.UpgradeField.prototype.showEditor_ = function() {
// ...
}
onMouseDown_
関数ではなく showEditor_
関数をオーバーライドして、マウスのクリックを処理することをおすすめします。これにより、ジェスチャー システムを介して入力を渡すことができます。
エディタの詳細については、エディタをご覧ください。
setValue
setValue
関数は、サブクラス内の重複コードを減らすためのテンプレート関数になりました。setValue
関数にロジックが含まれている場合は、値の処理で説明されている値の処理パスに適合するようにリファクタリングすることを検討してください。
text_
フィールドの text_
プロパティに直接アクセスしたり、更新したりしないことをおすすめします。代わりに、getText
関数を使用してフィールドのユーザーが読めるテキストにアクセスし、setValue
関数を使用してフィールドの保存値を更新します。
フィールドの値とテキストの詳細については、フィールドの構造をご覧ください。
アップグレードのサポートを受ける
提供するもの
サポートを求める場合は、具体的な質問をすることをおすすめします。
非推奨: 「このフィールドの問題点」
「このフィールドをアップグレードしてください」もおすすめしません。
推奨: 「フィールドのテキストが正しく更新されません。」
また、支援してくれる人にリソースを提供することも必要です。これらのファイルは、他のユーザーが簡単に使用できるようにする必要があります。
非推奨:
- コードの画像。
- コードが不完全です。
推奨:
- テキスト形式のフィールド コードを完成させます。
- フィールドの不適切な動作の GIF 画像。
- フィールドの不正な動作を再現する手順。
- アップグレード元の Blockly のバージョン。
投稿場所
アップグレードに関する質問は、Blockly デベロッパー フォーラムに投稿してください。
問題が Blockly コアの問題であることが確実な場合は、Blockly GitHub に問題を投稿することもできます。問題を投稿する場合は、必要な情報をすべて記入してください。