Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions blocks/logic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export const blocks = createBlockDefinitionsFromJsonArray([
'name': 'DO0',
},
],
'output': null,
'previousStatement': null,
'nextStatement': null,
'style': 'logic_blocks',
Expand Down Expand Up @@ -97,6 +98,7 @@ export const blocks = createBlockDefinitionsFromJsonArray([
'name': 'ELSE',
},
],
'output': null,
'previousStatement': null,
'nextStatement': null,
'style': 'logic_blocks',
Expand Down Expand Up @@ -228,6 +230,7 @@ export const blocks = createBlockDefinitionsFromJsonArray([
'type': 'controls_if_if',
'message0': '%{BKY_CONTROLS_IF_IF_TITLE_IF}',
'nextStatement': null,
'output': null,
'enableContextMenu': false,
'style': 'logic_blocks',
'tooltip': '%{BKY_CONTROLS_IF_IF_TOOLTIP}',
Expand All @@ -238,6 +241,7 @@ export const blocks = createBlockDefinitionsFromJsonArray([
'message0': '%{BKY_CONTROLS_IF_ELSEIF_TITLE_ELSEIF}',
'previousStatement': null,
'nextStatement': null,
'output': null,
'enableContextMenu': false,
'style': 'logic_blocks',
'tooltip': '%{BKY_CONTROLS_IF_ELSEIF_TOOLTIP}',
Expand All @@ -247,6 +251,7 @@ export const blocks = createBlockDefinitionsFromJsonArray([
'type': 'controls_if_else',
'message0': '%{BKY_CONTROLS_IF_ELSE_TITLE_ELSE}',
'previousStatement': null,
'output': null,
'enableContextMenu': false,
'style': 'logic_blocks',
'tooltip': '%{BKY_CONTROLS_IF_ELSE_TOOLTIP}',
Expand Down
6 changes: 6 additions & 0 deletions blocks/loops.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export const blocks = createBlockDefinitionsFromJsonArray([
],
'previousStatement': null,
'nextStatement': null,
'output': null,
'style': 'loop_blocks',
'tooltip': '%{BKY_CONTROLS_REPEAT_TOOLTIP}',
'helpUrl': '%{BKY_CONTROLS_REPEAT_HELPURL}',
Expand Down Expand Up @@ -80,6 +81,7 @@ export const blocks = createBlockDefinitionsFromJsonArray([
],
'previousStatement': null,
'nextStatement': null,
'output': null,
'style': 'loop_blocks',
'tooltip': '%{BKY_CONTROLS_REPEAT_TOOLTIP}',
'helpUrl': '%{BKY_CONTROLS_REPEAT_HELPURL}',
Expand Down Expand Up @@ -112,6 +114,7 @@ export const blocks = createBlockDefinitionsFromJsonArray([
],
'previousStatement': null,
'nextStatement': null,
'output': null,
'style': 'loop_blocks',
'helpUrl': '%{BKY_CONTROLS_WHILEUNTIL_HELPURL}',
'extensions': ['controls_whileUntil_tooltip'],
Expand Down Expand Up @@ -155,6 +158,7 @@ export const blocks = createBlockDefinitionsFromJsonArray([
'inputsInline': true,
'previousStatement': null,
'nextStatement': null,
'output': null,
'style': 'loop_blocks',
'helpUrl': '%{BKY_CONTROLS_FOR_HELPURL}',
'extensions': ['contextMenu_newGetVariableBlock', 'controls_for_tooltip'],
Expand Down Expand Up @@ -184,6 +188,7 @@ export const blocks = createBlockDefinitionsFromJsonArray([
],
'previousStatement': null,
'nextStatement': null,
'output': null,
'style': 'loop_blocks',
'helpUrl': '%{BKY_CONTROLS_FOREACH_HELPURL}',
'extensions': [
Expand All @@ -206,6 +211,7 @@ export const blocks = createBlockDefinitionsFromJsonArray([
},
],
'previousStatement': null,
'output': null,
'style': 'loop_blocks',
'helpUrl': '%{BKY_CONTROLS_FLOW_STATEMENTS_HELPURL}',
'suppressPrefixSuffix': true,
Expand Down
1 change: 1 addition & 0 deletions blocks/math.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ export const blocks = createBlockDefinitionsFromJsonArray([
],
'previousStatement': null,
'nextStatement': null,
'output': null,
'style': 'variable_blocks',
'helpUrl': '%{BKY_MATH_CHANGE_HELPURL}',
'extensions': ['math_change_tooltip'],
Expand Down
4 changes: 4 additions & 0 deletions blocks/text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export const blocks = createBlockDefinitionsFromJsonArray([
'name': 'STACK',
},
],
'output': null,
'style': 'text_blocks',
'tooltip': '%{BKY_TEXT_CREATE_JOIN_TOOLTIP}',
'enableContextMenu': false,
Expand All @@ -78,6 +79,7 @@ export const blocks = createBlockDefinitionsFromJsonArray([
'previousStatement': null,
'nextStatement': null,
'style': 'text_blocks',
'output': null,
'tooltip': '%{BKY_TEXT_CREATE_JOIN_ITEM_TOOLTIP}',
'enableContextMenu': false,
},
Expand All @@ -97,6 +99,7 @@ export const blocks = createBlockDefinitionsFromJsonArray([
],
'previousStatement': null,
'nextStatement': null,
'output': null,
'style': 'text_blocks',
'extensions': ['text_append_tooltip'],
},
Expand Down Expand Up @@ -387,6 +390,7 @@ blocks['text_print'] = {
'name': 'TEXT',
},
],
'output': null,
'previousStatement': null,
'nextStatement': null,
'style': 'text_blocks',
Expand Down
1 change: 1 addition & 0 deletions blocks/variables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export const blocks = createBlockDefinitionsFromJsonArray([
],
'previousStatement': null,
'nextStatement': null,
'output': null,
'style': 'variable_blocks',
'tooltip': '%{BKY_VARIABLES_SET_TOOLTIP}',
'helpUrl': '%{BKY_VARIABLES_SET_HELPURL}',
Expand Down
1 change: 1 addition & 0 deletions blocks/variables_dynamic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export const blocks = createBlockDefinitionsFromJsonArray([
'name': 'VALUE',
},
],
'output': null,
'previousStatement': null,
'nextStatement': null,
'style': 'variable_dynamic_blocks',
Expand Down
94 changes: 43 additions & 51 deletions core/block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import * as idGenerator from './utils/idgenerator.js';
import * as parsing from './utils/parsing.js';
import {Size} from './utils/size.js';
import type {Workspace} from './workspace.js';
import { BlockArg, JsonBlockDefinition } from './interfaces/i_json_block_definition.js'

/**
* Class for one block.
Expand Down Expand Up @@ -1709,20 +1710,20 @@ export class Block {
*
* @param json Structured data describing the block.
*/
jsonInit(json: AnyDuringMigration) {
const warningPrefix = json['type'] ? 'Block "' + json['type'] + '": ' : '';
jsonInit(json: JsonBlockDefinition) {
const warningPrefix = json.type ? 'Block "' + json.type + '": ' : '';

// Validate inputs.
if (json['output'] && json['previousStatement']) {
if (json.output && json.previousStatement) {
throw Error(
warningPrefix + 'Must not have both an output and a previousStatement.',
);
}

// Validate that each arg has a corresponding message
let n = 0;
while (json['args' + n]) {
if (json['message' + n] === undefined) {
while (json[`args${n}`]) {
if (json[`message${n}`] === undefined) {
throw Error(
warningPrefix +
`args${n} must have a corresponding message (message${n}).`,
Expand All @@ -1732,87 +1733,78 @@ export class Block {
}

// Set basic properties of block.
// Makes styles backward compatible with old way of defining hat style.
if (json['style'] && json['style'].hat) {
this.hat = json['style'].hat;
// Must set to null so it doesn't error when checking for style and
// colour.
json['style'] = null;
}

if (json['style'] && json['colour']) {
if (json.style && json.colour) {
throw Error(warningPrefix + 'Must not have both a colour and a style.');
} else if (json['style']) {
} else if (json.style) {
this.jsonInitStyle(json, warningPrefix);
} else {
this.jsonInitColour(json, warningPrefix);
}

// Interpolate the message blocks.
let i = 0;
while (json['message' + i] !== undefined) {
while (json[`message${i}`] !== undefined) {
this.interpolate(
json['message' + i],
json['args' + i] || [],
// Backwards compatibility: lastDummyAlign aliases implicitAlign.
json['implicitAlign' + i] || json['lastDummyAlign' + i],
json[`message${i}`]!,
json[`args${i}`] || [],
json[`implicitAlign${i}`],
warningPrefix,
);
i++;
}

if (json['inputsInline'] !== undefined) {
if (json.inputsInline !== undefined) {
eventUtils.disable();
this.setInputsInline(json['inputsInline']);
this.setInputsInline(json.inputsInline);
eventUtils.enable();
}

// Set output and previous/next connections.
if (json['output'] !== undefined) {
this.setOutput(true, json['output']);
if (json.output !== undefined) {
this.setOutput(true, json.output);
}
if (json['outputShape'] !== undefined) {
this.setOutputShape(json['outputShape']);
if (json.outputShape !== undefined) {
this.setOutputShape(json.outputShape);
}
if (json['previousStatement'] !== undefined) {
this.setPreviousStatement(true, json['previousStatement']);
if (json.previousStatement !== undefined) {
this.setPreviousStatement(true, json.previousStatement);
}
if (json['nextStatement'] !== undefined) {
this.setNextStatement(true, json['nextStatement']);
if (json.nextStatement !== undefined) {
this.setNextStatement(true, json.nextStatement);
}
if (json['tooltip'] !== undefined) {
const rawValue = json['tooltip'];
if (json.tooltip !== undefined) {
const rawValue = json.tooltip;
const localizedText = parsing.replaceMessageReferences(rawValue);
this.setTooltip(localizedText);
}
if (json['enableContextMenu'] !== undefined) {
this.contextMenu = !!json['enableContextMenu'];
if (json.enableContextMenu !== undefined) {
this.contextMenu = !!json.enableContextMenu;
}
if (json['suppressPrefixSuffix'] !== undefined) {
this.suppressPrefixSuffix = !!json['suppressPrefixSuffix'];
if (json.suppressPrefixSuffix !== undefined) {
this.suppressPrefixSuffix = !!json.suppressPrefixSuffix;
}
if (json['helpUrl'] !== undefined) {
const rawValue = json['helpUrl'];
if (json.helpUrl !== undefined) {
const rawValue = json.helpUrl;
const localizedValue = parsing.replaceMessageReferences(rawValue);
this.setHelpUrl(localizedValue);
}
if (typeof json['extensions'] === 'string') {
if (typeof json.extensions === 'string') {
console.warn(
warningPrefix +
"JSON attribute 'extensions' should be an array of" +
" strings. Found raw string in JSON for '" +
json['type'] +
json.type +
"' block.",
);
json['extensions'] = [json['extensions']]; // Correct and continue.
json.extensions = [json.extensions]; // Correct and continue.
}

// Add the mutator to the block.
if (json['mutator'] !== undefined) {
Extensions.apply(json['mutator'], this, true);
if (json.mutator !== undefined) {
Extensions.apply(json.mutator, this, true);
}

const extensionNames = json['extensions'];
const extensionNames = json.extensions;
if (Array.isArray(extensionNames)) {
for (let j = 0; j < extensionNames.length; j++) {
Extensions.apply(extensionNames[j], this, false);
Expand All @@ -1826,12 +1818,12 @@ export class Block {
* @param json Structured data describing the block.
* @param warningPrefix Warning prefix string identifying block.
*/
private jsonInitColour(json: AnyDuringMigration, warningPrefix: string) {
if ('colour' in json) {
if (json['colour'] === undefined) {
private jsonInitColour(json: JsonBlockDefinition, warningPrefix: string) {
if (json.colour) {
if (json.colour === undefined) {
console.warn(warningPrefix + 'Undefined colour value.');
} else {
const rawValue = json['colour'];
const rawValue = json.colour;
try {
this.setColour(rawValue);
} catch {
Expand All @@ -1847,8 +1839,8 @@ export class Block {
* @param json Structured data describing the block.
* @param warningPrefix Warning prefix string identifying block.
*/
private jsonInitStyle(json: AnyDuringMigration, warningPrefix: string) {
const blockStyleName = json['style'];
private jsonInitStyle(json: JsonBlockDefinition, warningPrefix: string) {
const blockStyleName = json.style!
try {
this.setStyle(blockStyleName);
} catch {
Expand Down Expand Up @@ -1901,7 +1893,7 @@ export class Block {
*/
private interpolate(
message: string,
args: AnyDuringMigration[],
args: BlockArg[],
implicitAlign: string | undefined,
warningPrefix: string,
) {
Expand Down
11 changes: 6 additions & 5 deletions core/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type {Connection} from './connection.js';
import {EventType} from './events/type.js';
import * as eventUtils from './events/utils.js';
import {getFocusManager} from './focus_manager.js';
import {JsonBlockDefinition} from './interfaces/i_json_block_definition.js';
import {ISelectable, isSelectable} from './interfaces/i_selectable.js';
import {ShortcutRegistry} from './shortcut_registry.js';
import type {Workspace} from './workspace.js';
Expand Down Expand Up @@ -238,7 +239,7 @@ export function getBlockTypeCounts(
* @returns A function that calls jsonInit with the correct value
* of jsonDef.
*/
function jsonInitFactory(jsonDef: AnyDuringMigration): () => void {
function jsonInitFactory(jsonDef: JsonBlockDefinition): () => void {
return function (this: Block) {
this.jsonInit(jsonDef);
};
Expand All @@ -250,14 +251,14 @@ function jsonInitFactory(jsonDef: AnyDuringMigration): () => void {
*
* @param jsonArray An array of JSON block definitions.
*/
export function defineBlocksWithJsonArray(jsonArray: AnyDuringMigration[]) {
export function defineBlocksWithJsonArray(jsonArray: JsonBlockDefinition[]) {
TEST_ONLY.defineBlocksWithJsonArrayInternal(jsonArray);
}

/**
* Private version of defineBlocksWithJsonArray for stubbing in tests.
*/
function defineBlocksWithJsonArrayInternal(jsonArray: AnyDuringMigration[]) {
function defineBlocksWithJsonArrayInternal(jsonArray: JsonBlockDefinition[]) {
defineBlocks(createBlockDefinitionsFromJsonArray(jsonArray));
}

Expand All @@ -270,7 +271,7 @@ function defineBlocksWithJsonArrayInternal(jsonArray: AnyDuringMigration[]) {
* definitions created.
*/
export function createBlockDefinitionsFromJsonArray(
jsonArray: AnyDuringMigration[],
jsonArray: JsonBlockDefinition[],
): {[key: string]: BlockDefinition} {
const blocks: {[key: string]: BlockDefinition} = {};
for (let i = 0; i < jsonArray.length; i++) {
Expand All @@ -279,7 +280,7 @@ export function createBlockDefinitionsFromJsonArray(
console.warn(`Block definition #${i} in JSON array is ${elem}. Skipping`);
continue;
}
const type = elem['type'];
const type = elem.type;
if (!type) {
console.warn(
`Block definition #${i} in JSON array is missing a type attribute. ` +
Expand Down
Loading