diff --git a/src/events_scratch_variable_create.js b/src/events_scratch_variable_create.js new file mode 100644 index 0000000000..d5ab39d6e7 --- /dev/null +++ b/src/events_scratch_variable_create.js @@ -0,0 +1,67 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; + +class ScratchVariableCreate extends Blockly.Events.VarCreate { + constructor(variable) { + super(variable); + if (!variable) return; + + this.isLocal = variable.isLocal; + this.isCloud = variable.isCloud; + } + + toJson() { + const json = super.toJson(); + json["isLocal"] = this.isLocal; + json["isCloud"] = this.isCloud; + return json; + } + + static fromJson(json, workspace, event) { + const newEvent = super.fromJson(json, workspace, event); + newEvent.isLocal = json["isLocal"]; + newEvent.isCloud = json["isCloud"]; + return newEvent; + } + + run(forward) { + const workspace = this.getEventWorkspace_(); + const variableMap = workspace.getVariableMap(); + if (forward) { + const VariableModel = Blockly.registry.getObject( + Blockly.registry.Type.VARIABLE_MODEL, + Blockly.registry.DEFAULT, + true + ); + const variable = new VariableModel( + workspace, + this.varName, + this.varType, + this.varId, + this.isLocal, + this.isCloud + ); + variableMap.addVariable(variable); + Blockly.Events.fire( + new (Blockly.Events.get(Blockly.Events.VAR_CREATE))(variable) + ); + } else { + const variable = variableMap.getVariableById(this.varId); + if (variable) { + variableMap.deleteVariable(variable); + } + } + } +} + +Blockly.registry.register( + Blockly.registry.Type.EVENT, + Blockly.Events.VAR_CREATE, + ScratchVariableCreate, + true +); diff --git a/src/index.js b/src/index.js index 3f61eb2d01..3011f69149 100644 --- a/src/index.js +++ b/src/index.js @@ -4,58 +4,60 @@ * SPDX-License-Identifier: Apache-2.0 */ -import * as Blockly from 'blockly/core'; -import {registerFieldAngle} from '@blockly/field-angle'; +import * as Blockly from "blockly/core"; +import { registerFieldAngle } from "@blockly/field-angle"; registerFieldAngle(); -import '../blocks_common/colour.js'; -import '../blocks_common/math.js'; -import '../blocks_common/matrix.js'; -import '../blocks_common/note.js'; -import '../blocks_common/text.js'; -import '../blocks_vertical/vertical_extensions.js'; -import '../blocks_vertical/control.js'; -import '../blocks_vertical/data.js'; -import '../blocks_vertical/event.js'; -import '../blocks_vertical/looks.js'; -import '../blocks_vertical/motion.js'; -import '../blocks_vertical/operators.js'; -import '../blocks_vertical/procedures.js'; -import '../blocks_vertical/sensing.js'; -import '../blocks_vertical/sound.js'; -import * as scratchBlocksUtils from '../core/scratch_blocks_utils.js'; -import '../core/css.js'; -import '../core/field_vertical_separator.js'; +import "../blocks_common/colour.js"; +import "../blocks_common/math.js"; +import "../blocks_common/matrix.js"; +import "../blocks_common/note.js"; +import "../blocks_common/text.js"; +import "../blocks_vertical/vertical_extensions.js"; +import "../blocks_vertical/control.js"; +import "../blocks_vertical/data.js"; +import "../blocks_vertical/event.js"; +import "../blocks_vertical/looks.js"; +import "../blocks_vertical/motion.js"; +import "../blocks_vertical/operators.js"; +import "../blocks_vertical/procedures.js"; +import "../blocks_vertical/sensing.js"; +import "../blocks_vertical/sound.js"; +import * as scratchBlocksUtils from "../core/scratch_blocks_utils.js"; +import "../core/css.js"; +import "../core/field_vertical_separator.js"; import { ContinuousToolbox, ContinuousFlyout, ContinuousMetrics, -} from '@blockly/continuous-toolbox'; -import {CheckableContinuousFlyout} from './checkable_continuous_flyout.js'; -import {buildGlowFilter, glowStack} from './glows.js'; -import {ScratchContinuousToolbox} from './scratch_continuous_toolbox.js'; -import './scratch_continuous_category.js'; -import './scratch_comment_icon.js'; -import './events_block_comment_change.js'; -import './events_block_comment_collapse.js'; -import './events_block_comment_create.js'; -import './events_block_comment_delete.js'; -import './events_block_comment_move.js'; -import './events_block_comment_resize.js'; -import {buildShadowFilter} from './shadows.js'; +} from "@blockly/continuous-toolbox"; +import { CheckableContinuousFlyout } from "./checkable_continuous_flyout.js"; +import { buildGlowFilter, glowStack } from "./glows.js"; +import { ScratchContinuousToolbox } from "./scratch_continuous_toolbox.js"; +import "./scratch_continuous_category.js"; +import "./scratch_comment_icon.js"; +import "./scratch_variable_model.js"; +import "./events_block_comment_change.js"; +import "./events_block_comment_collapse.js"; +import "./events_block_comment_create.js"; +import "./events_block_comment_delete.js"; +import "./events_block_comment_move.js"; +import "./events_block_comment_resize.js"; +import "./events_scratch_variable_create.js"; +import { buildShadowFilter } from "./shadows.js"; -export * from 'blockly'; -export * from './block_reporting.js'; -export * from './categories.js'; -export * from './procedures.js'; -export * from '../core/colours.js'; -export * from '../core/field_colour_slider.js'; -export * from '../core/field_matrix.js'; -export * from '../core/field_note.js'; -export * from '../core/field_number.js'; -export * from '../msg/scratch_msgs.js'; -export {glowStack}; -export {scratchBlocksUtils}; -export {CheckableContinuousFlyout}; +export * from "blockly"; +export * from "./block_reporting.js"; +export * from "./categories.js"; +export * from "./procedures.js"; +export * from "../core/colours.js"; +export * from "../core/field_colour_slider.js"; +export * from "../core/field_matrix.js"; +export * from "../core/field_note.js"; +export * from "../core/field_number.js"; +export * from "../msg/scratch_msgs.js"; +export { glowStack }; +export { scratchBlocksUtils }; +export { CheckableContinuousFlyout }; export function inject(container, options) { Object.assign(options, { @@ -66,11 +68,12 @@ export function inject(container, options) { }, }); const workspace = Blockly.inject(container, options); - workspace.getRenderer().getConstants().selectedGlowFilterId = ''; + workspace.getRenderer().getConstants().selectedGlowFilterId = ""; const flyout = workspace.getFlyout(); if (flyout) { - flyout.getWorkspace().getRenderer().getConstants().selectedGlowFilterId = ''; + flyout.getWorkspace().getRenderer().getConstants().selectedGlowFilterId = + ""; } buildGlowFilter(workspace); @@ -88,6 +91,6 @@ export function inject(container, options) { Blockly.Scrollbar.scrollbarThickness = Blockly.Touch.TOUCH_ENABLED ? 14 : 11; Blockly.FlyoutButton.TEXT_MARGIN_X = 40; Blockly.FlyoutButton.TEXT_MARGIN_Y = 10; -Blockly.ContextMenuRegistry.registry.unregister('blockDisable'); -Blockly.ContextMenuRegistry.registry.unregister('blockInline'); +Blockly.ContextMenuRegistry.registry.unregister("blockDisable"); +Blockly.ContextMenuRegistry.registry.unregister("blockInline"); Blockly.ContextMenuItems.registerCommentOptions(); diff --git a/src/scratch_variable_model.js b/src/scratch_variable_model.js new file mode 100644 index 0000000000..92284e42b8 --- /dev/null +++ b/src/scratch_variable_model.js @@ -0,0 +1,24 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; + +class ScratchVariableModel extends Blockly.VariableModel { + constructor(workspace, name, type, id, isLocal, isCloud) { + super(workspace, name, type, id); + // isLocal and isCloud may not be passed when creating broadcast message + // variables, which conveniently are neither local nor cloud. + this.isLocal = !!isLocal; + this.isCloud = !!isCloud; + } +} + +Blockly.registry.register( + Blockly.registry.Type.VARIABLE_MODEL, + Blockly.registry.DEFAULT, + ScratchVariableModel, + true +);