@blockly/block-test
Version:
A group of Blockly test blocks.
578 lines (550 loc) • 14 kB
JavaScript
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
'use strict';
/**
* @fileoverview Field validators test blocks.
* @author samelh@google.com (Sam El-Husseini)
*/
import * as Blockly from 'blockly/core';
Blockly.Blocks['test_validators_dispose_block'] = {
init: function () {
this.appendDummyInput()
.appendField('dispose block')
.appendField(
new Blockly.FieldTextInput('default', this.validate),
'INPUT',
);
this.setColour(230);
this.setCommentText(
'Any changes to the text cause the block to be' + ' disposed',
);
},
validate: function (newValue) {
if (newValue != 'default') {
this.getSourceBlock().dispose(true);
}
},
};
Blockly.Blocks['test_validators_text_null'] = {
init: function () {
this.appendDummyInput()
.appendField('always null')
.appendField(
new Blockly.FieldTextInput('default', this.validate),
'INPUT',
);
this.setColour(230);
this.setCommentText(
'All input validates to null (invalid). The display' +
' text will remain the input text, but the value should be the' +
' default text. The input should be red after the first keystroke.',
);
},
validate: function (newValue) {
return null;
},
};
Blockly.Blocks['test_validators_text_A'] = {
init: function () {
this.appendDummyInput()
.appendField("remove 'a'")
.appendField(
new Blockly.FieldTextInput('default', this.validate),
'INPUT',
);
this.setColour(230);
this.setCommentText(
"All 'a' characters are removed from field value." +
" The display text will include invalid 'a' characters while the" +
' field is being edited, but the value will not.',
);
},
validate: function (newValue) {
return newValue.replace(/a/g, '');
},
};
Blockly.Blocks['test_validators_text_B'] = {
init: function () {
this.appendDummyInput()
.appendField("'b' -> null")
.appendField(
new Blockly.FieldTextInput('default', this.validate),
'INPUT',
);
this.setColour(230);
this.setCommentText(
"Upon detecting a 'b' character the input will" +
' validated to null (invalid). Upon removal it should revert to' +
' being valid. The display text will remain the input text, but if' +
' the input text is invalid the value should be the default text.',
);
},
validate: function (newValue) {
if (newValue.indexOf('b') !== -1) {
return null;
}
return newValue;
},
};
Blockly.Blocks['test_validators_checkbox_null'] = {
init: function () {
this.appendDummyInput()
.appendField('always null')
.appendField(new Blockly.FieldCheckbox(true, this.validate), 'INPUT');
this.setColour(230);
this.setCommentText(
'The new input always validates to null (invalid).' +
' This means that the field value should not change.',
);
},
validate: function (newValue) {
return null;
},
};
Blockly.Blocks['test_validators_checkbox_match'] = {
init: function () {
this.appendDummyInput()
.appendField('force match')
.appendField(new Blockly.FieldCheckbox(true), 'MATCH')
.appendField(new Blockly.FieldCheckbox(true, this.validate), 'INPUT');
this.setColour(230);
this.setCommentText(
'The validator for this block only works on the end-most checkbox.' +
' The validator will always return the value of the start-most' +
' checkbox. Therefore they should always match.',
);
},
validate: function (newValue) {
return this.sourceBlock_.getFieldValue('MATCH');
},
};
Blockly.Blocks['test_validators_checkbox_not_match_null'] = {
init: function () {
this.appendDummyInput()
.appendField('not match -> null')
.appendField(new Blockly.FieldCheckbox(true), 'MATCH')
.appendField(new Blockly.FieldCheckbox(true, this.validate), 'INPUT');
this.setColour(230);
this.setCommentText(
'The validator for this block only works on the' +
' end-most checkbox. If the new value does not match the value of the' +
' start-most checkbox, it will return null (invalid), which means the' +
' field value should not change. Therefore they should always match.',
);
},
validate: function (newValue) {
if (this.sourceBlock_.getFieldValue('MATCH') != newValue) {
return null;
}
return newValue;
},
};
Blockly.Blocks['test_validators_dropdown_null'] = {
init: function () {
this.appendDummyInput()
.appendField('always null')
.appendField(
new Blockly.FieldDropdown(
[
['1a', '1A'],
['1b', '1B'],
['1c', '1C'],
['2a', '2A'],
['2b', '2B'],
['2c', '2C'],
],
this.validate,
),
'INPUT',
);
this.setColour(230);
this.setCommentText(
'All input validates to null (invalid). This means' +
' the field value should not change.',
);
},
validate: function (newValue) {
return null;
},
};
Blockly.Blocks['test_validators_dropdown_force_1s'] = {
init: function () {
this.appendDummyInput()
.appendField('force 1s')
.appendField(
new Blockly.FieldDropdown(
[
['1a', '1A'],
['1b', '1B'],
['1c', '1C'],
['2a', '2A'],
['2b', '2B'],
['2c', '2C'],
],
this.validate,
),
'INPUT',
);
this.setColour(230);
this.setCommentText(
"The input's value will always change to start with 1.",
);
},
validate: function (newValue) {
return '1' + newValue.charAt(1);
},
};
Blockly.Blocks['test_validators_dropdown_1s_null'] = {
init: function () {
this.appendDummyInput()
.appendField('not 1s -> null')
.appendField(
new Blockly.FieldDropdown(
[
['1a', '1A'],
['1b', '1B'],
['1c', '1C'],
['2a', '2A'],
['2b', '2B'],
['2c', '2C'],
],
this.validate,
),
'INPUT',
);
this.setColour(230);
this.setCommentText(
'If the input does not start with 1, the input will validate to' +
' null (invalid). Otherwise it will return the input value.',
);
},
validate: function (newValue) {
if (newValue.charAt(0) != '1') {
return null;
}
return newValue;
},
};
Blockly.Blocks['test_validators_number_null'] = {
init: function () {
this.appendDummyInput()
.appendField('always null')
.appendField(
new Blockly.FieldNumber(123, null, null, null, this.validate),
'INPUT',
);
this.setColour(230);
this.setCommentText(
'All input validates to null (invalid). The field will display the' +
' input while the field is being edited, but the value should be the' +
' default value. The input should be red after the first' +
' keystroke.',
);
},
validate: function (newValue) {
return null;
},
};
Blockly.Blocks['test_validators_number_mult10_force'] = {
init: function () {
this.appendDummyInput()
.appendField('force mult of 10')
.appendField(
new Blockly.FieldNumber(123, null, null, null, this.validate),
'INPUT',
);
this.setColour(230);
this.setCommentText(
'The input value will be rounded to the nearest' +
' multiple of 10. The field will display the input while the field is' +
' being edited, but the value should be the validated (rounded)' +
' value. Note: If you want to do rounding this is not the proper' +
' way, use the precision option of the number field constructor' +
' instead.',
);
},
validate: function (newValue) {
return Math.round(newValue / 10) * 10;
},
};
Blockly.Blocks['test_validators_number_mult10_null'] = {
init: function () {
this.appendDummyInput()
.appendField('not mult of 10 -> null')
.appendField(
new Blockly.FieldNumber(123, null, null, null, this.validate),
'INPUT',
);
this.setColour(230);
this.setCommentText(
'If the input value is not a multiple of 10, the' +
' input will validate to null (invalid). The field will display the' +
' input while the field is being edited, but if the input value is' +
' invalid the value should be the default value.',
);
},
validate: function (newValue) {
if (newValue % 10 != 0) {
return null;
}
return newValue;
},
};
Blockly.Blocks['test_validators_variable_null'] = {
init: function () {
this.appendDummyInput()
.appendField('always null')
.appendField(new Blockly.FieldVariable('1a', this.validate), 'INPUT');
this.setColour(230);
this.setCommentText(
'All ids validate to null (invalid). This means' +
' the variable should not change.',
);
},
validate: function (newValue) {
return null;
},
};
Blockly.Blocks['test_validators_variable_force_1s'] = {
init: function () {
this.appendDummyInput()
.appendField('force 1s')
.appendField(new Blockly.FieldVariable('1a', this.validate), 'INPUT');
this.setColour(230);
this.setCommentText('The id will always change to start with 1.');
},
validate: function (newValue) {
return '1' + newValue.charAt(1);
},
};
Blockly.Blocks['test_validators_variable_1s_null'] = {
init: function () {
this.appendDummyInput()
.appendField('not 1s -> null')
.appendField(new Blockly.FieldVariable('1a', this.validate), 'INPUT');
this.setColour(230);
this.setCommentText(
'If the id does not start with 1, the id will' +
' validate to null (invalid). Otherwise it will return the id.',
);
},
validate: function (newValue) {
if (newValue.charAt(0) != '1') {
return null;
}
return newValue;
},
};
/**
* The Validators field category.
*/
export const category = {
kind: 'CATEGORY',
name: 'Validators',
contents: [
{
kind: 'BUTTON',
text: 'add blocks to workspace',
callbackkey: 'addAllBlocksToWorkspace',
},
{
kind: 'SEP',
gap: '8',
},
{
kind: 'BUTTON',
text: 'set input',
callbackkey: 'setInput',
},
{
kind: 'LABEL',
text: 'Dispose block',
},
{
kind: 'SEP',
gap: '12',
},
{
kind: 'BLOCK',
type: 'test_validators_dispose_block',
},
{
kind: 'LABEL',
text: 'Checkboxes',
},
{
kind: 'SEP',
gap: '12',
},
{
kind: 'BLOCK',
type: 'test_validators_checkbox_null',
},
{
kind: 'SEP',
gap: '12',
},
{
kind: 'BLOCK',
type: 'test_validators_checkbox_match',
},
{
kind: 'SEP',
gap: '12',
},
{
kind: 'BLOCK',
type: 'test_validators_checkbox_not_match_null',
},
{
kind: 'LABEL',
text: 'Dropdowns',
},
{
kind: 'SEP',
gap: '12',
},
{
kind: 'BLOCK',
type: 'test_validators_dropdown_null',
},
{
kind: 'SEP',
gap: '12',
},
{
kind: 'BLOCK',
type: 'test_validators_dropdown_force_1s',
},
{
kind: 'SEP',
gap: '12',
},
{
kind: 'BLOCK',
type: 'test_validators_dropdown_1s_null',
},
{
kind: 'LABEL',
text: 'Numbers',
},
{
kind: 'SEP',
gap: '12',
},
{
kind: 'BLOCK',
type: 'test_validators_number_null',
},
{
kind: 'SEP',
gap: '12',
},
{
kind: 'BLOCK',
type: 'test_validators_number_mult10_force',
},
{
kind: 'SEP',
gap: '12',
},
{
kind: 'BLOCK',
type: 'test_validators_number_mult10_null',
},
{
kind: 'LABEL',
text: 'Text',
},
{
kind: 'SEP',
gap: '12',
},
{
kind: 'BLOCK',
type: 'test_validators_text_null',
},
{
kind: 'SEP',
gap: '12',
},
{
kind: 'BLOCK',
type: 'test_validators_text_A',
},
{
kind: 'SEP',
gap: '12',
},
{
kind: 'BLOCK',
type: 'test_validators_text_B',
},
{
kind: 'LABEL',
text: 'Variables',
},
{
kind: 'SEP',
gap: '8',
},
{
'kind': 'BUTTON',
'text': 'add test variables',
'callbackkey': 'addVariables',
'web-class': 'modifiesWorkspace',
},
{
kind: 'SEP',
gap: '12',
},
{
kind: 'BLOCK',
type: 'test_validators_variable_null',
},
{
kind: 'SEP',
gap: '12',
},
{
kind: 'BLOCK',
type: 'test_validators_variable_force_1s',
},
{
kind: 'SEP',
gap: '12',
},
{
kind: 'BLOCK',
type: 'test_validators_variable_1s_null',
},
],
};
/**
* Initialize this toolbox category.
* @param {!Blockly.WorkspaceSvg} workspace The Blockly workspace.
*/
export function onInit(workspace) {
const addVariables = function (button) {
workspace.createVariable('1b', '', '1B');
workspace.createVariable('1c', '', '1C');
workspace.createVariable('2a', '', '2A');
workspace.createVariable('2b', '', '2B');
workspace.createVariable('2c', '', '2C');
};
const setInput = function (button) {
Blockly.dialog.prompt('Input text to set.', 'ab', function (input) {
const blocks = button.getTargetWorkspace().getAllBlocks(false);
for (let i = 0, block; (block = blocks[i]); i++) {
if (block.getField('INPUT')) {
block.setFieldValue(input, 'INPUT');
}
}
});
};
workspace.registerButtonCallback('addVariables', addVariables);
workspace.registerButtonCallback('setInput', setInput);
}