scratch-blocks 2.0.0-spork.2 → 2.0.0-spork.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/main.js +1 -1
  3. package/package.json +1 -1
  4. package/src/{block_reporting.js → block_reporting.ts} +7 -5
  5. package/src/blocks/{colour.js → colour.ts} +6 -6
  6. package/src/blocks/{control.js → control.ts} +21 -54
  7. package/src/blocks/{data.js → data.ts} +134 -142
  8. package/src/blocks/{event.js → event.ts} +12 -33
  9. package/src/blocks/{looks.js → looks.ts} +24 -73
  10. package/src/blocks/{math.js → math.ts} +6 -11
  11. package/src/blocks/{matrix.js → matrix.ts} +2 -3
  12. package/src/blocks/{motion.js → motion.ts} +23 -70
  13. package/src/blocks/{note.js → note.ts} +2 -3
  14. package/src/blocks/{operators.js → operators.ts} +18 -55
  15. package/src/blocks/{procedures.js → procedures.ts} +418 -269
  16. package/src/blocks/{sensing.js → sensing.ts} +21 -61
  17. package/src/blocks/{sound.js → sound.ts} +9 -28
  18. package/src/blocks/{text.js → text.ts} +1 -2
  19. package/src/blocks/{vertical_extensions.js → vertical_extensions.ts} +63 -100
  20. package/src/checkable_continuous_flyout.js +2 -2
  21. package/src/{checkbox_bubble.js → checkbox_bubble.ts} +36 -53
  22. package/src/{colours.js → colours.ts} +11 -4
  23. package/src/{constants.js → constants.ts} +13 -0
  24. package/src/{context_menu_items.js → context_menu_items.ts} +18 -12
  25. package/src/{data_category.js → data_category.ts} +216 -150
  26. package/src/events/{events_block_comment_base.js → events_block_comment_base.ts} +23 -4
  27. package/src/events/{events_block_comment_change.js → events_block_comment_change.ts} +29 -5
  28. package/src/events/{events_block_comment_collapse.js → events_block_comment_collapse.ts} +24 -6
  29. package/src/events/{events_block_comment_create.js → events_block_comment_create.ts} +36 -10
  30. package/src/events/{events_block_comment_delete.js → events_block_comment_delete.ts} +6 -2
  31. package/src/events/{events_block_comment_move.js → events_block_comment_move.ts} +36 -6
  32. package/src/events/events_block_comment_resize.ts +88 -0
  33. package/src/events/events_block_drag_end.ts +49 -0
  34. package/src/events/events_block_drag_outside.ts +44 -0
  35. package/src/events/{events_scratch_variable_create.js → events_scratch_variable_create.ts} +28 -15
  36. package/src/fields/{field_colour_slider.js → field_colour_slider.ts} +117 -106
  37. package/src/fields/{field_matrix.js → field_matrix.ts} +189 -215
  38. package/src/fields/{field_note.js → field_note.ts} +227 -286
  39. package/src/fields/{field_textinput_removable.js → field_textinput_removable.ts} +17 -20
  40. package/src/fields/{field_variable_getter.js → field_variable_getter.ts} +28 -17
  41. package/src/fields/{field_vertical_separator.js → field_vertical_separator.ts} +14 -30
  42. package/src/fields/{field_angle.js → scratch_field_angle.ts} +124 -80
  43. package/src/fields/{field_dropdown.js → scratch_field_dropdown.ts} +9 -7
  44. package/src/fields/{field_number.js → scratch_field_number.ts} +60 -55
  45. package/src/fields/{field_variable.js → scratch_field_variable.ts} +46 -27
  46. package/src/{flyout_checkbox_icon.js → flyout_checkbox_icon.ts} +15 -19
  47. package/src/{glows.js → glows.ts} +29 -18
  48. package/src/index.ts +59 -60
  49. package/src/procedures.ts +462 -0
  50. package/src/{recyclable_block_flyout_inflater.js → recyclable_block_flyout_inflater.ts} +35 -35
  51. package/src/renderer/{bowler_hat.js → bowler_hat.ts} +1 -1
  52. package/src/renderer/{constants.js → constants.ts} +26 -12
  53. package/src/renderer/{drawer.js → drawer.ts} +8 -3
  54. package/src/renderer/{path_object.js → path_object.ts} +2 -2
  55. package/src/renderer/{render_info.js → render_info.ts} +19 -7
  56. package/src/renderer/renderer.ts +76 -0
  57. package/src/{scratch_block_paster.js → scratch_block_paster.ts} +9 -7
  58. package/src/scratch_blocks_utils.ts +39 -0
  59. package/src/{scratch_comment_icon.js → scratch_comment_icon.ts} +43 -26
  60. package/src/scratch_connection_checker.ts +44 -0
  61. package/src/{scratch_continuous_category.js → scratch_continuous_category.ts} +20 -13
  62. package/src/{scratch_continuous_toolbox.js → scratch_continuous_toolbox.ts} +20 -18
  63. package/src/{scratch_dragger.js → scratch_dragger.ts} +97 -28
  64. package/src/{scratch_variable_map.js → scratch_variable_map.ts} +4 -1
  65. package/src/scratch_variable_model.ts +30 -0
  66. package/src/{shadows.js → shadows.ts} +8 -4
  67. package/src/{status_indicator_label.js → status_indicator_label.ts} +24 -36
  68. package/src/{status_indicator_label_flyout_inflater.js → status_indicator_label_flyout_inflater.ts} +9 -7
  69. package/src/{variables.js → variables.ts} +153 -123
  70. package/tsconfig.json +5 -0
  71. package/src/categories.js +0 -15
  72. package/src/events/events_block_comment_resize.js +0 -52
  73. package/src/events/events_block_drag_end.js +0 -33
  74. package/src/events/events_block_drag_outside.js +0 -30
  75. package/src/procedures.js +0 -425
  76. package/src/renderer/renderer.js +0 -74
  77. package/src/scratch_blocks_utils.js +0 -148
  78. package/src/scratch_connection_checker.js +0 -29
  79. package/src/scratch_variable_model.js +0 -24
  80. /package/src/{css.js → css.ts} +0 -0
  81. /package/{continuous-toolbox.d.ts → types/continuous-toolbox.d.ts} +0 -0
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2024 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import * as Blockly from "blockly/core";
8
+
9
+ /**
10
+ * Custom connection checker to restrict which blocks can be connected.
11
+ */
12
+ class ScratchConnectionChecker extends Blockly.ConnectionChecker {
13
+ /**
14
+ * Returns whether or not the two connections should be allowed to connect.
15
+ *
16
+ * @param a One of the connections to check.
17
+ * @param b The other connection to check.
18
+ * @param distance The maximum allowable distance between connections.
19
+ * @returns True if the connections should be allowed to connect.
20
+ */
21
+ doDragChecks(
22
+ a: Blockly.RenderedConnection,
23
+ b: Blockly.RenderedConnection,
24
+ distance: number
25
+ ): boolean {
26
+ // This check prevents dragging a block into the slot occupied by the
27
+ // procedure caller example block in a procedure definition block.
28
+ if (
29
+ b.getSourceBlock().type === "procedures_definition" &&
30
+ b.getParentInput()?.name === "custom_block"
31
+ ) {
32
+ return false;
33
+ }
34
+
35
+ return super.doDragChecks(a, b, distance);
36
+ }
37
+ }
38
+
39
+ Blockly.registry.register(
40
+ Blockly.registry.Type.CONNECTION_CHECKER,
41
+ Blockly.registry.DEFAULT,
42
+ ScratchConnectionChecker,
43
+ true
44
+ );
@@ -7,34 +7,41 @@
7
7
  import * as Blockly from "blockly/core";
8
8
  import { ContinuousCategory } from "@blockly/continuous-toolbox";
9
9
 
10
+ type StatusIndicatorCategoryInfo = Blockly.utils.toolbox.CategoryInfo & {
11
+ showStatusButton?: string;
12
+ };
13
+
14
+ /**
15
+ * Selectable category shown in the Scratch toolbox.
16
+ */
10
17
  export class ScratchContinuousCategory extends ContinuousCategory {
11
18
  /**
12
19
  * Whether this toolbox category has a status indicator button on its label
13
20
  * in the flyout, typically for extensions that interface with hardware
14
21
  * devices.
15
- * @type {boolean}
16
22
  */
17
- showStatusButton = false;
23
+ private showStatusButton = false;
18
24
 
19
25
  /** Creates a new ScratchContinuousCategory.
20
26
  *
21
- * @param {!Blockly.toolbox.CategoryInfo} toolboxItemDef A toolbox item
22
- * definition.
23
- * @param {!Blockly.Toolbox} parentToolbox The toolbox this category is being
24
- * added to.
25
- * @param {?Blockly.ICollapsibleToolboxItem} opt_parent The parent toolbox
26
- * category, if any.
27
+ * @param toolboxItemDef A toolbox item definition.
28
+ * @param parentToolbox The toolbox this category is being added to.
29
+ * @param opt_parent The parent toolbox category, if any.
27
30
  */
28
- constructor(toolboxItemDef, parentToolbox, opt_parent) {
31
+ constructor(
32
+ toolboxItemDef: StatusIndicatorCategoryInfo,
33
+ parentToolbox: Blockly.Toolbox,
34
+ opt_parent?: Blockly.ICollapsibleToolboxItem
35
+ ) {
29
36
  super(toolboxItemDef, parentToolbox, opt_parent);
30
37
  this.showStatusButton = toolboxItemDef["showStatusButton"] === "true";
31
38
  }
32
39
 
33
40
  /**
34
41
  * Creates a DOM element for this category's icon.
35
- * @returns {!HTMLElement} A DOM element for this category's icon.
42
+ * @returns A DOM element for this category's icon.
36
43
  */
37
- createIconDom_() {
44
+ createIconDom_(): HTMLElement {
38
45
  if (this.toolboxItemDef_.iconURI) {
39
46
  const icon = document.createElement("img");
40
47
  icon.src = this.toolboxItemDef_.iconURI;
@@ -49,9 +56,9 @@ export class ScratchContinuousCategory extends ContinuousCategory {
49
56
 
50
57
  /**
51
58
  * Sets whether or not this category is selected.
52
- * @param {boolean} isSelected True if this category is selected.
59
+ * @param isSelected True if this category is selected.
53
60
  */
54
- setSelected(isSelected) {
61
+ setSelected(isSelected: boolean) {
55
62
  super.setSelected(isSelected);
56
63
  // Prevent hardcoding the background color to grey.
57
64
  this.rowDiv_.style.backgroundColor = "";
@@ -6,23 +6,30 @@
6
6
 
7
7
  import * as Blockly from "blockly/core";
8
8
  import { ContinuousToolbox } from "@blockly/continuous-toolbox";
9
- import { ScratchContinuousCategory } from "./scratch_continuous_category.js";
9
+ import { ScratchContinuousCategory } from "./scratch_continuous_category";
10
10
 
11
+ /**
12
+ * A toolbox that displays items from all categories in one scrolling list.
13
+ */
11
14
  export class ScratchContinuousToolbox extends ContinuousToolbox {
12
- postRenderCallbacks = [];
15
+ /**
16
+ * List of functions to run after the next time the toolbox renders.
17
+ */
18
+ private postRenderCallbacks: (() => void)[] = [];
13
19
 
14
20
  refreshSelection() {
15
- // Intentionally a no-op, Scratch manually manages refreshing the toolbox via forceRerender().
21
+ // Intentionally a no-op, Scratch manually manages refreshing the toolbox
22
+ // via forceRerender().
16
23
  }
17
24
 
18
25
  /**
19
26
  * Gets the contents that should be shown in the flyout.
20
- * @returns {!Blockly.utils.toolbox.FlyoutItemInfoArray} Flyout contents.
27
+ *
28
+ * @returns Flyout contents.
21
29
  */
22
- getInitialFlyoutContents_() {
30
+ getInitialFlyoutContents_(): Blockly.utils.toolbox.FlyoutItemInfoArray {
23
31
  // TODO(#211) Clean this up when the continuous toolbox plugin is updated.
24
- /** @type {!Blockly.utils.toolbox.FlyoutItemInfoArray} */
25
- let contents = [];
32
+ let contents: Blockly.utils.toolbox.FlyoutItemInfoArray = [];
26
33
  for (const toolboxItem of this.getToolboxItems()) {
27
34
  if (toolboxItem instanceof ScratchContinuousCategory) {
28
35
  if (toolboxItem.shouldShowStatusButton()) {
@@ -35,19 +42,14 @@ export class ScratchContinuousToolbox extends ContinuousToolbox {
35
42
  // Create a label node to go at the top of the category
36
43
  contents.push({ kind: "LABEL", text: toolboxItem.getName() });
37
44
  }
38
- /**
39
- * @type {string|Blockly.utils.toolbox.FlyoutItemInfoArray|
40
- * Blockly.utils.toolbox.FlyoutItemInfo}
41
- */
42
45
  let itemContents = toolboxItem.getContents();
43
46
 
44
47
  // Handle custom categories (e.g. variables and functions)
45
48
  if (typeof itemContents === "string") {
46
- itemContents =
47
- /** @type {!Blockly.utils.toolbox.DynamicCategoryInfo} */ ({
48
- custom: itemContents,
49
- kind: "CATEGORY",
50
- });
49
+ itemContents = {
50
+ custom: itemContents,
51
+ kind: "CATEGORY",
52
+ };
51
53
  }
52
54
  contents = contents.concat(itemContents);
53
55
  }
@@ -70,9 +72,9 @@ export class ScratchContinuousToolbox extends ContinuousToolbox {
70
72
 
71
73
  /**
72
74
  * Runs the specified callback after the next rerender.
73
- * @param {!Function} A callback to run whenever the toolbox next rerenders.
75
+ * @param callback A callback to run whenever the toolbox next rerenders.
74
76
  */
75
- runAfterRerender(callback) {
77
+ runAfterRerender(callback: () => void) {
76
78
  this.postRenderCallbacks.push(callback);
77
79
  }
78
80
  }
@@ -5,23 +5,44 @@
5
5
  */
6
6
 
7
7
  import * as Blockly from "blockly/core";
8
- import { BlockDragOutside } from "./events/events_block_drag_outside.js";
9
- import { BlockDragEnd } from "./events/events_block_drag_end.js";
8
+ import { BlockDragOutside } from "./events/events_block_drag_outside";
9
+ import { BlockDragEnd } from "./events/events_block_drag_end";
10
+ import { isProcedureBlock, getCallers } from "./procedures";
10
11
 
12
+ /**
13
+ * CSS class that allows the workspace to overflow its bounds when set.
14
+ */
11
15
  const BOUNDLESS_CLASS = "boundless";
12
16
 
13
- class ScratchDragger extends Blockly.dragging.Dragger {
14
- constructor(draggable, workspace) {
15
- super(draggable, workspace);
16
- this.draggedOutOfBounds = false;
17
- this.originatedFromFlyout = false;
18
- }
17
+ /**
18
+ * Class responsible for managing dragging items on the workspace.
19
+ */
20
+ export class ScratchDragger extends Blockly.dragging.Dragger {
21
+ /**
22
+ * Whether or not the current drag location is outside of the main workspace.
23
+ */
24
+ draggedOutOfBounds = false;
25
+
26
+ /**
27
+ * Whether or not the current drag started from the flyout.
28
+ */
29
+ originatedFromFlyout = false;
19
30
 
20
- setDraggable(draggable) {
31
+ /**
32
+ * Sets the current item being dragged.
33
+ *
34
+ * @param draggable The item being dragged.
35
+ */
36
+ setDraggable(draggable: Blockly.IDraggable) {
21
37
  this.draggable = draggable;
22
38
  }
23
39
 
24
- onDragStart(event) {
40
+ /**
41
+ * Handles the start of a drag operation.
42
+ *
43
+ * @param event The event that triggered the drag.
44
+ */
45
+ onDragStart(event: PointerEvent) {
25
46
  super.onDragStart(event);
26
47
  if (this.draggable instanceof Blockly.BlockSvg) {
27
48
  this.workspace.addClass(BOUNDLESS_CLASS);
@@ -41,17 +62,28 @@ class ScratchDragger extends Blockly.dragging.Dragger {
41
62
  }
42
63
  }
43
64
 
44
- onDrag(event, totalDelta) {
65
+ /**
66
+ * Handles motion during an ongoing drag operation.
67
+ *
68
+ * @param event The event that triggered this call.
69
+ * @param totalDelta The change in pointer position since the last invocation.
70
+ */
71
+ onDrag(event: PointerEvent, totalDelta: Blockly.utils.Coordinate) {
45
72
  super.onDrag(event, totalDelta);
46
73
  this.updateOutOfBoundsState(event);
47
74
  }
48
75
 
49
- updateOutOfBoundsState(event) {
76
+ /**
77
+ * Records whether or not the current drag is out of the workspace's bounds.
78
+ *
79
+ * @param event The event that triggered this call.
80
+ */
81
+ updateOutOfBoundsState(event: PointerEvent) {
50
82
  if (this.draggable instanceof Blockly.BlockSvg) {
51
83
  const outOfBounds = !this.isInsideWorkspace(event);
52
84
  if (outOfBounds !== this.draggedOutOfBounds) {
53
85
  const event = new BlockDragOutside(
54
- this.getDragRoot(this.draggable),
86
+ this.getDragRoot(this.draggable) as Blockly.BlockSvg,
55
87
  outOfBounds
56
88
  );
57
89
  Blockly.Events.fire(event);
@@ -60,18 +92,30 @@ class ScratchDragger extends Blockly.dragging.Dragger {
60
92
  }
61
93
  }
62
94
 
63
- onDragEnd(event) {
95
+ /**
96
+ * Handles the end of a drag.
97
+ *
98
+ * @param event The event that ended the drag.
99
+ */
100
+ onDragEnd(event: PointerEvent) {
64
101
  if (
65
102
  this.draggable instanceof Blockly.BlockSvg &&
66
103
  this.draggable.type === "procedures_definition" &&
67
104
  this.wouldDeleteDraggable(event, this.draggable.getRootBlock())
68
105
  ) {
69
- const procCode = this.draggable
70
- .getInputTargetBlock("custom_block")
71
- .getProcCode();
72
- const hasCaller = this.workspace
73
- .getBlocksByType("procedures_call")
74
- .some((b) => b.getProcCode() === procCode);
106
+ const prototype = this.draggable
107
+ .getInput("custom_block")
108
+ .connection.targetBlock();
109
+ const hasCaller =
110
+ prototype instanceof Blockly.BlockSvg &&
111
+ isProcedureBlock(prototype) &&
112
+ getCallers(
113
+ prototype.getProcCode(),
114
+ this.draggable.workspace,
115
+ this.draggable.getRootBlock(),
116
+ false
117
+ ).length > 0;
118
+
75
119
  if (hasCaller) {
76
120
  Blockly.dialog.alert(Blockly.Msg.PROCEDURE_USED);
77
121
  this.draggable.revertDrag();
@@ -85,7 +129,7 @@ class ScratchDragger extends Blockly.dragging.Dragger {
85
129
  this.updateOutOfBoundsState(event);
86
130
  if (this.draggable instanceof Blockly.BlockSvg) {
87
131
  const event = new BlockDragEnd(
88
- this.getDragRoot(this.draggable),
132
+ this.getDragRoot(this.draggable) as Blockly.BlockSvg,
89
133
  this.draggedOutOfBounds
90
134
  );
91
135
  Blockly.Events.fire(event);
@@ -95,14 +139,25 @@ class ScratchDragger extends Blockly.dragging.Dragger {
95
139
  // deleted.
96
140
  if (this.originatedFromFlyout && this.draggedOutOfBounds) {
97
141
  Blockly.renderManagement.finishQueuedRenders().then(() => {
98
- this.getDragRoot(this.draggable).dispose();
142
+ const rootBlock = this.getDragRoot(this.draggable);
143
+ if (rootBlock instanceof Blockly.BlockSvg) {
144
+ rootBlock.dispose();
145
+ }
99
146
  });
100
147
  }
101
148
  }
102
149
  this.workspace.removeClass(BOUNDLESS_CLASS);
103
150
  }
104
151
 
105
- shouldReturnToStart(event, rootDraggable) {
152
+ /**
153
+ * Returns whether or not the dragged item should return to its starting
154
+ * position.
155
+ *
156
+ * @param event The drag event that triggered this check.
157
+ * @param rootDraggable The topmost item being dragged.
158
+ * @returns True if the draggable should return to its starting position.
159
+ */
160
+ shouldReturnToStart(event: PointerEvent, rootDraggable: Blockly.IDraggable) {
106
161
  // If a block is dragged out of the workspace to be e.g. dropped on another
107
162
  // sprite, it should remain in the same place on the workspace where it was,
108
163
  // rather than being moved to an invisible part of the workspace.
@@ -111,18 +166,32 @@ class ScratchDragger extends Blockly.dragging.Dragger {
111
166
  );
112
167
  }
113
168
 
114
- getDragRoot(block) {
169
+ /**
170
+ * Returns the root element being dragged. For shadow blocks, this is the
171
+ * parent block.
172
+ *
173
+ * @param draggable The element being dragged directly.
174
+ * @returns The element being dragged, or its parent.
175
+ */
176
+ getDragRoot(draggable: Blockly.IDraggable) {
115
177
  // We can't just use getRootBlock() here because, when blocks are detached
116
178
  // from a stack via dragging, getRootBlock() still returns the root of that
117
179
  // stack.
118
- if (block.isShadow()) {
119
- return block.getParent();
180
+ if (draggable instanceof Blockly.BlockSvg && draggable.isShadow()) {
181
+ return draggable.getParent();
120
182
  }
121
183
 
122
- return block;
184
+ return draggable;
123
185
  }
124
186
 
125
- isInsideWorkspace(event) {
187
+ /**
188
+ * Returns whether or not the given event occurred within the bounds of the
189
+ * workspace.
190
+ *
191
+ * @param event The event to check.
192
+ * @returns True if the event occurred inside the workspace.
193
+ */
194
+ isInsideWorkspace(event: PointerEvent) {
126
195
  const bounds = this.workspace.getParentSvg().getBoundingClientRect();
127
196
  const workspaceRect = new Blockly.utils.Rect(
128
197
  bounds.top,
@@ -6,8 +6,11 @@
6
6
 
7
7
  import * as Blockly from "blockly/core";
8
8
 
9
+ /**
10
+ * Class that provides storage for variables.
11
+ */
9
12
  class ScratchVariableMap extends Blockly.VariableMap {
10
- getVariable(name, type) {
13
+ getVariable(name: string, type: string) {
11
14
  // Variable names in Blockly are case-insensitive, but case sensitive in
12
15
  // Scratch. Override the implementation to only return a variable whose name
13
16
  // is identical to the one requested.
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2024 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import * as Blockly from "blockly/core";
8
+
9
+ /**
10
+ * Class that represents a variable with extra fields for Scratch.
11
+ */
12
+ export class ScratchVariableModel extends Blockly.VariableModel {
13
+ constructor(
14
+ workspace: Blockly.Workspace,
15
+ name: string,
16
+ type: string,
17
+ id: string,
18
+ public isLocal = false,
19
+ public isCloud = false
20
+ ) {
21
+ super(workspace, name, type, id);
22
+ }
23
+ }
24
+
25
+ Blockly.registry.register(
26
+ Blockly.registry.Type.VARIABLE_MODEL,
27
+ Blockly.registry.DEFAULT,
28
+ ScratchVariableModel,
29
+ true
30
+ );
@@ -5,9 +5,13 @@
5
5
  */
6
6
 
7
7
  import * as Blockly from "blockly/core";
8
- import { Colours } from "./colours.js";
8
+ import { Colours } from "./colours";
9
9
 
10
- export function buildShadowFilter(workspace) {
10
+ /**
11
+ * Creates an SVG filter to apply drop shadows to blocks being dragged and
12
+ * inserts it into the DOM.
13
+ */
14
+ export function buildShadowFilter(workspace: Blockly.WorkspaceSvg) {
11
15
  const svg = workspace.getParentSvg();
12
16
  const defs = Blockly.utils.dom.createSvgElement(
13
17
  Blockly.utils.Svg.DEFS,
@@ -15,7 +19,7 @@ export function buildShadowFilter(workspace) {
15
19
  svg
16
20
  );
17
21
  // Adjust these width/height, x/y properties to stop the shadow from clipping
18
- var dragShadowFilter = Blockly.utils.dom.createSvgElement(
22
+ const dragShadowFilter = Blockly.utils.dom.createSvgElement(
19
23
  "filter",
20
24
  {
21
25
  id: "blocklyDragShadowFilter",
@@ -34,7 +38,7 @@ export function buildShadowFilter(workspace) {
34
38
  },
35
39
  dragShadowFilter
36
40
  );
37
- var componentTransfer = Blockly.utils.dom.createSvgElement(
41
+ const componentTransfer = Blockly.utils.dom.createSvgElement(
38
42
  "feComponentTransfer",
39
43
  { result: "offsetBlur" },
40
44
  dragShadowFilter
@@ -33,42 +33,37 @@ import * as Blockly from "blockly/core";
33
33
  export class StatusIndicatorLabel extends Blockly.FlyoutButton {
34
34
  /**
35
35
  * The ID of the Scratch extension whose status is indicated by this label.
36
- * @type {string}
37
36
  */
38
- extensionId;
37
+ extensionId: string;
39
38
 
40
39
  /**
41
40
  * DOM element that displays the status indicator dot.
42
- * @type {!SVGImageElement}
43
41
  */
44
- imageElement;
42
+ imageElement: SVGImageElement;
45
43
 
46
44
  /**
47
45
  * Opaque data for mouse up listener used to unbind it in dispose().
48
- * @type {!Blockly.browserEvents.Data}
49
46
  */
50
- mouseUpwrapper;
47
+ mouseUpWrapper: Blockly.browserEvents.Data;
51
48
 
52
49
  /**
53
50
  * Function to be invoked when the status indicator is clicked.
54
- * @type {?Function}
55
51
  */
56
- static statusButtonCallback;
52
+ static statusButtonCallback: (extensionId: string) => void;
57
53
 
58
54
  /**
59
55
  * Creates a new StatusIndicatorLabel.
60
56
  *
61
- * @param {!Blockly.WorkspaceSvg} workspace The workspace in which to place
62
- * this header.
63
- * @param {!Blockly.WorkspaceSvg} targetWorkspace The flyout's target
64
- * workspace.
65
- * @param {!Element} xml The XML specifying the header.
57
+ * @param workspace The workspace in which to place this header.
58
+ * @param targetWorkspace The flyout's target workspace.
59
+ * @param json The JSON specifying the header.
66
60
  */
67
- constructor(workspace, targetWorkspace, json, isFlyoutLabel) {
68
- super(workspace, targetWorkspace, json, isFlyoutLabel);
69
- /**
70
- * @type {string}
71
- */
61
+ constructor(
62
+ workspace: Blockly.WorkspaceSvg,
63
+ targetWorkspace: Blockly.WorkspaceSvg,
64
+ json: Blockly.utils.toolbox.LabelInfo
65
+ ) {
66
+ super(workspace, targetWorkspace, json, true);
72
67
  this.extensionId = json["id"];
73
68
 
74
69
  const heightDelta = 40 - this.height;
@@ -76,7 +71,7 @@ export class StatusIndicatorLabel extends Blockly.FlyoutButton {
76
71
  const text = this.getSvgRoot().querySelector("text");
77
72
  const previousY = Number(text.getAttribute("y"));
78
73
 
79
- text.setAttribute("y", previousY + heightDelta / 2);
74
+ text.setAttribute("y", `${previousY + heightDelta / 2}`);
80
75
 
81
76
  const statusButtonWidth = 30;
82
77
  const marginX = 20;
@@ -88,7 +83,6 @@ export class StatusIndicatorLabel extends Blockly.FlyoutButton {
88
83
  ? marginX - flyoutWidth + statusButtonWidth
89
84
  : (flyoutWidth - statusButtonWidth - marginX) / workspace.scale;
90
85
 
91
- /** @type {SVGElement} */
92
86
  this.imageElement = Blockly.utils.dom.createSvgElement(
93
87
  "image",
94
88
  {
@@ -140,31 +134,25 @@ export class StatusIndicatorLabel extends Blockly.FlyoutButton {
140
134
 
141
135
  /**
142
136
  * Set the source URL of the image for the button.
143
- * @param {?string} src New source.
137
+ * @param src New source.
144
138
  * @package
145
139
  */
146
- setImageSrc(src) {
147
- if (src === null) {
148
- // No change if null.
149
- return;
150
- }
151
- this.imageSrc = src;
140
+ setImageSrc(src: string) {
152
141
  if (this.imageElement) {
153
142
  this.imageElement.setAttributeNS(
154
143
  "http://www.w3.org/1999/xlink",
155
144
  "xlink:href",
156
- this.imageSrc || ""
145
+ src
157
146
  );
158
147
  }
159
148
  }
160
149
 
161
150
  /**
162
151
  * Gets the extension state. Overridden externally.
163
- * @param {string} extensionId The ID of the extension in question.
164
- * @return {Blockly.StatusButtonState} The state of the extension.
165
- * @public
152
+ * @param extensionId The ID of the extension in question.
153
+ * @return The state of the extension.
166
154
  */
167
- getExtensionState(extensionId) {
155
+ getExtensionState(extensionId: string): StatusButtonState {
168
156
  return StatusButtonState.NOT_READY;
169
157
  }
170
158
 
@@ -180,7 +168,7 @@ export class StatusIndicatorLabel extends Blockly.FlyoutButton {
180
168
  /**
181
169
  * Set of available states for a status indicator.
182
170
  */
183
- export const StatusButtonState = {
184
- READY: "ready",
185
- NOT_READY: "not ready",
186
- };
171
+ export enum StatusButtonState {
172
+ READY = "ready",
173
+ NOT_READY = "not ready",
174
+ }
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import * as Blockly from "blockly/core";
8
- import { StatusIndicatorLabel } from "./status_indicator_label.js";
8
+ import { StatusIndicatorLabel } from "./status_indicator_label";
9
9
 
10
10
  /**
11
11
  * Flyout inflater responsible for creating status indicator labels.
@@ -13,17 +13,19 @@ import { StatusIndicatorLabel } from "./status_indicator_label.js";
13
13
  class StatusIndicatorLabelFlyoutInflater extends Blockly.LabelFlyoutInflater {
14
14
  /**
15
15
  * Creates a status indicator label on the flyout from the given state.
16
- * @param {!Object} state JSON representation of a status indicator label.
17
- * @param {!Blockly.WorkspaceSvg} flyoutWorkspace The workspace to create the
16
+ * @param state JSON representation of a status indicator label.
17
+ * @param flyoutWorkspace The workspace to create the
18
18
  * label on.
19
- * @returns {!StatusIndicatorLabel} The newly created status indicator label.
19
+ * @returns The newly created status indicator label.
20
20
  */
21
- load(state, flyoutWorkspace) {
21
+ load(
22
+ state: Blockly.utils.toolbox.LabelInfo,
23
+ flyoutWorkspace: Blockly.WorkspaceSvg
24
+ ): StatusIndicatorLabel {
22
25
  const label = new StatusIndicatorLabel(
23
26
  flyoutWorkspace,
24
27
  flyoutWorkspace.targetWorkspace,
25
- state,
26
- true
28
+ state
27
29
  );
28
30
  label.show();
29
31
  return label;