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
@@ -6,12 +6,12 @@
6
6
 
7
7
  import * as Blockly from "blockly/core";
8
8
 
9
- class FieldDropdown extends Blockly.FieldDropdown {
10
- originalStyle;
9
+ class ScratchFieldDropdown extends Blockly.FieldDropdown {
10
+ private originalStyle: string;
11
11
 
12
- showEditor_(event) {
12
+ showEditor_(event: PointerEvent) {
13
13
  super.showEditor_(event);
14
- const sourceBlock = this.getSourceBlock();
14
+ const sourceBlock = this.getSourceBlock() as Blockly.BlockSvg;
15
15
  const style = sourceBlock.style;
16
16
  if (sourceBlock.isShadow()) {
17
17
  this.originalStyle = sourceBlock.getStyleName();
@@ -19,7 +19,9 @@ class FieldDropdown extends Blockly.FieldDropdown {
19
19
  } else if (this.borderRect_) {
20
20
  this.borderRect_.setAttribute(
21
21
  "fill",
22
- style.colourQuaternary ?? style.colourTertiary
22
+ "colourQuaternary" in style
23
+ ? `${style.colourQuaternary}`
24
+ : style.colourTertiary
23
25
  );
24
26
  }
25
27
  }
@@ -36,7 +38,7 @@ class FieldDropdown extends Blockly.FieldDropdown {
36
38
  /**
37
39
  * Register the field and any dependencies.
38
40
  */
39
- export function registerFieldDropdown() {
41
+ export function registerScratchFieldDropdown() {
40
42
  Blockly.fieldRegistry.unregister("field_dropdown");
41
- Blockly.fieldRegistry.register("field_dropdown", FieldDropdown);
43
+ Blockly.fieldRegistry.register("field_dropdown", ScratchFieldDropdown);
42
44
  }
@@ -23,7 +23,7 @@
23
23
  * @author tmickel@mit.edu (Tim Mickel)
24
24
  */
25
25
  import * as Blockly from "blockly/core";
26
- import { Colours } from "../colours.js";
26
+ import { Colours } from "../colours";
27
27
 
28
28
  /**
29
29
  * Class for an editable number field.
@@ -45,7 +45,10 @@ import { Colours } from "../colours.js";
45
45
  * @extends {Blockly.FieldTextInput}
46
46
  * @constructor
47
47
  */
48
- class FieldNumberPicker extends Blockly.FieldTextInput {
48
+ class ScratchFieldNumber extends Blockly.FieldTextInput {
49
+ private negativeAllowed_ = true;
50
+ private decimalAllowed_ = true;
51
+ private exponentialAllowed_ = true;
49
52
  /**
50
53
  * Fixed width of the num-pad drop-down, in px.
51
54
  * @type {number}
@@ -96,7 +99,7 @@ class FieldNumberPicker extends Blockly.FieldTextInput {
96
99
  Colours.numPadText +
97
100
  '"/></svg>';
98
101
 
99
- configure_(config) {
102
+ configure_(config: Blockly.FieldNumberFromJsonConfig) {
100
103
  super.configure_(config);
101
104
  this.decimalAllowed_ =
102
105
  typeof config.precision == "undefined" ||
@@ -114,7 +117,7 @@ class FieldNumberPicker extends Blockly.FieldTextInput {
114
117
  * @return {!RegExp} Regular expression for this FieldNumber's restrictor.
115
118
  */
116
119
  getNumRestrictor() {
117
- var pattern = "[\\d]"; // Always allow digits.
120
+ let pattern = "[\\d]"; // Always allow digits.
118
121
  if (this.decimalAllowed_) {
119
122
  pattern += "|[\\.]";
120
123
  }
@@ -130,11 +133,10 @@ class FieldNumberPicker extends Blockly.FieldTextInput {
130
133
  /**
131
134
  * Show the inline free-text editor on top of the text and the num-pad if
132
135
  * appropriate.
133
- * @private
134
136
  */
135
- showEditor_(e) {
137
+ showEditor_(e: PointerEvent) {
136
138
  // Do not focus on mobile devices so we can show the num-pad
137
- var showNumPad = e && e.pointerType === "touch";
139
+ const showNumPad = e && e.pointerType === "touch";
138
140
  super.showEditor_(e, showNumPad);
139
141
 
140
142
  // Show a numeric keypad in the drop-down on touch
@@ -144,7 +146,7 @@ class FieldNumberPicker extends Blockly.FieldTextInput {
144
146
  }
145
147
  }
146
148
 
147
- onHtmlInputKeyDown_(e) {
149
+ onHtmlInputKeyDown_(e: KeyboardEvent) {
148
150
  super.onHtmlInputKeyDown_(e);
149
151
  // key can be things like "Backspace", so only validate when it represents a single
150
152
  // character so as to allow non-textual input to work as normal.
@@ -158,10 +160,9 @@ class FieldNumberPicker extends Blockly.FieldTextInput {
158
160
 
159
161
  /**
160
162
  * Show the number pad.
161
- * @private
162
163
  */
163
- showNumPad_() {
164
- var contentDiv = Blockly.DropDownDiv.getContentDiv();
164
+ private showNumPad_() {
165
+ const contentDiv = Blockly.DropDownDiv.getContentDiv();
165
166
 
166
167
  // Accessibility properties
167
168
  contentDiv.setAttribute("role", "menu");
@@ -170,36 +171,37 @@ class FieldNumberPicker extends Blockly.FieldTextInput {
170
171
  this.addButtons_(contentDiv);
171
172
 
172
173
  // Set colour and size of drop-down
174
+ const sourceBlock = this.getSourceBlock() as Blockly.BlockSvg;
173
175
  Blockly.DropDownDiv.setColour(
174
- this.sourceBlock_.parentBlock_.getColour(),
175
- this.sourceBlock_.getColourTertiary()
176
+ sourceBlock.getParent().getColour(),
177
+ sourceBlock.getColourTertiary()
176
178
  );
177
- contentDiv.style.width = FieldNumberPicker.DROPDOWN_WIDTH + "px";
179
+ contentDiv.style.width = ScratchFieldNumber.DROPDOWN_WIDTH + "px";
178
180
 
179
181
  this.position_();
180
182
  }
181
183
 
182
184
  /**
183
185
  * Figure out where to place the drop-down, and move it there.
184
- * @private
185
186
  */
186
- position_() {
187
+ private position_() {
187
188
  // Calculate positioning for the drop-down
188
189
  // sourceBlock_ is the rendered shadow field input box
189
- var scale = this.sourceBlock_.workspace.scale;
190
- var bBox = this.sourceBlock_.getHeightWidth();
190
+ const sourceBlock = this.getSourceBlock() as Blockly.BlockSvg;
191
+ const scale = sourceBlock.workspace.scale;
192
+ let bBox = sourceBlock.getHeightWidth();
191
193
  bBox.width *= scale;
192
194
  bBox.height *= scale;
193
- var position = this.getAbsoluteXY_();
195
+ const position = this.getAbsoluteXY_();
194
196
  // If we can fit it, render below the shadow block
195
- var primaryX = position.x + bBox.width / 2;
196
- var primaryY = position.y + bBox.height;
197
+ const primaryX = position.x + bBox.width / 2;
198
+ const primaryY = position.y + bBox.height;
197
199
  // If we can't fit it, render above the entire parent block
198
- var secondaryX = primaryX;
199
- var secondaryY = position.y;
200
+ const secondaryX = primaryX;
201
+ const secondaryY = position.y;
200
202
 
201
203
  Blockly.DropDownDiv.setBoundsElement(
202
- this.sourceBlock_.workspace.getParentSvg().parentNode
204
+ sourceBlock.workspace.getParentSvg().parentElement
203
205
  );
204
206
  Blockly.DropDownDiv.show(
205
207
  this,
@@ -215,17 +217,18 @@ class FieldNumberPicker extends Blockly.FieldTextInput {
215
217
  /**
216
218
  * Add number, punctuation, and erase buttons to the numeric keypad's content
217
219
  * div.
218
- * @param {Element} contentDiv The div for the numeric keypad.
219
- * @private
220
+ *
221
+ * @param contentDiv The div for the numeric keypad.
220
222
  */
221
- addButtons_(contentDiv) {
222
- var buttonColour = this.sourceBlock_.parentBlock_.getColour();
223
- var buttonBorderColour = this.sourceBlock_.parentBlock_.getColourTertiary();
223
+ private addButtons_(contentDiv: Element) {
224
+ const sourceBlock = this.getSourceBlock() as Blockly.BlockSvg;
225
+ const buttonColour = sourceBlock.getParent().getColour();
226
+ const buttonBorderColour = sourceBlock.getParent().getColourTertiary();
224
227
 
225
228
  // Add numeric keypad buttons
226
- var buttons = FieldNumberPicker.NUMPAD_BUTTONS;
227
- for (var i = 0, buttonText; (buttonText = buttons[i]); i++) {
228
- var button = document.createElement("button");
229
+ const buttons = ScratchFieldNumber.NUMPAD_BUTTONS;
230
+ for (let i = 0, buttonText; (buttonText = buttons[i]); i++) {
231
+ const button = document.createElement("button");
229
232
  button.setAttribute("role", "menuitem");
230
233
  button.setAttribute("class", "blocklyNumPadButton");
231
234
  button.setAttribute(
@@ -258,7 +261,7 @@ class FieldNumberPicker extends Blockly.FieldTextInput {
258
261
  contentDiv.appendChild(button);
259
262
  }
260
263
  // Add erase button to the end
261
- var eraseButton = document.createElement("button");
264
+ const eraseButton = document.createElement("button");
262
265
  eraseButton.setAttribute("role", "menuitem");
263
266
  eraseButton.setAttribute("class", "blocklyNumPadButton");
264
267
  eraseButton.setAttribute(
@@ -272,8 +275,8 @@ class FieldNumberPicker extends Blockly.FieldTextInput {
272
275
  );
273
276
  eraseButton.title = "Delete";
274
277
 
275
- var eraseImage = document.createElement("img");
276
- eraseImage.src = FieldNumberPicker.NUMPAD_DELETE_ICON;
278
+ const eraseImage = document.createElement("img");
279
+ eraseImage.src = ScratchFieldNumber.NUMPAD_DELETE_ICON;
277
280
  eraseButton.appendChild(eraseImage);
278
281
 
279
282
  Blockly.browserEvents.bind(
@@ -288,19 +291,20 @@ class FieldNumberPicker extends Blockly.FieldTextInput {
288
291
  /**
289
292
  * Call for when a num-pad number or punctuation button is touched.
290
293
  * Determine what the user is inputting and update the text field appropriately.
291
- * @param {Event} e DOM event triggering the touch.
294
+ *
295
+ * @param e DOM event triggering the touch.
292
296
  */
293
- numPadButtonTouch(e) {
297
+ numPadButtonTouch(e: PointerEvent) {
294
298
  // String of the button (e.g., '7')
295
- var spliceValue = e.target.innerText;
299
+ const spliceValue = (e.target as HTMLElement).innerText;
296
300
  // Old value of the text field
297
- var oldValue = this.htmlInput_.value;
301
+ const oldValue = this.htmlInput_.value;
298
302
  // Determine the selected portion of the text field
299
- var selectionStart = this.htmlInput_.selectionStart;
300
- var selectionEnd = this.htmlInput_.selectionEnd;
303
+ const selectionStart = this.htmlInput_.selectionStart;
304
+ const selectionEnd = this.htmlInput_.selectionEnd;
301
305
 
302
306
  // Splice in the new value
303
- var newValue =
307
+ const newValue =
304
308
  oldValue.slice(0, selectionStart) +
305
309
  spliceValue +
306
310
  oldValue.slice(selectionEnd);
@@ -318,14 +322,15 @@ class FieldNumberPicker extends Blockly.FieldTextInput {
318
322
  /**
319
323
  * Call for when the num-pad erase button is touched.
320
324
  * Determine what the user is asking to erase, and erase it.
321
- * @param {Event} e DOM event triggering the touch.
325
+ *
326
+ * @param e DOM event triggering the touch.
322
327
  */
323
- numPadEraseButtonTouch(e) {
328
+ numPadEraseButtonTouch(e: PointerEvent) {
324
329
  // Old value of the text field
325
- var oldValue = this.htmlInput_.value;
330
+ const oldValue = this.htmlInput_.value;
326
331
  // Determine what is selected to erase (if anything)
327
- var selectionStart = this.htmlInput_.selectionStart;
328
- var selectionEnd = this.htmlInput_.selectionEnd;
332
+ let selectionStart = this.htmlInput_.selectionStart;
333
+ const selectionEnd = this.htmlInput_.selectionEnd;
329
334
 
330
335
  // If selection is zero-length, shift start to the left 1 character
331
336
  if (selectionStart == selectionEnd) {
@@ -333,7 +338,7 @@ class FieldNumberPicker extends Blockly.FieldTextInput {
333
338
  }
334
339
 
335
340
  // Cut out selected range
336
- var newValue =
341
+ const newValue =
337
342
  oldValue.slice(0, selectionStart) + oldValue.slice(selectionEnd);
338
343
 
339
344
  this.updateDisplay_(newValue, selectionStart);
@@ -347,11 +352,11 @@ class FieldNumberPicker extends Blockly.FieldTextInput {
347
352
 
348
353
  /**
349
354
  * Update the displayed value and resize/scroll the text field as needed.
350
- * @param {string} newValue The new text to display.
351
- * @param {string} newSelection The new index to put the cursor
352
- * @private
355
+ *
356
+ * @param newValue The new text to display.
357
+ * @param newSelection The new index to put the cursor
353
358
  */
354
- updateDisplay_(newValue, newSelection) {
359
+ private updateDisplay_(newValue: string, newSelection: number) {
355
360
  this.setEditorValue_(newValue);
356
361
  // Resize and scroll the text field appropriately
357
362
  const htmlInput = this.htmlInput_;
@@ -369,12 +374,12 @@ class FieldNumberPicker extends Blockly.FieldTextInput {
369
374
  }
370
375
  }
371
376
 
372
- FieldNumberPicker.prototype.DEFAULT_VALUE = "";
377
+ ScratchFieldNumber.prototype.DEFAULT_VALUE = "";
373
378
 
374
379
  /**
375
380
  * Register the field and any dependencies.
376
381
  */
377
- export function registerFieldNumber() {
382
+ export function registerScratchFieldNumber() {
378
383
  Blockly.fieldRegistry.unregister("field_number");
379
- Blockly.fieldRegistry.register("field_number", FieldNumberPicker);
384
+ Blockly.fieldRegistry.register("field_number", ScratchFieldNumber);
380
385
  }
@@ -23,24 +23,31 @@
23
23
  * @author fraser@google.com (Neil Fraser)
24
24
  */
25
25
  import * as Blockly from "blockly/core";
26
- import * as Constants from "../constants.js";
26
+ import * as Constants from "../constants";
27
27
  import { ScratchMsgs } from "../../msg/scratch_msgs.js";
28
- import { createVariable, renameVariable } from "../variables.js";
28
+ import { createVariable, renameVariable } from "../variables";
29
+ import type { ScratchVariableModel } from "../scratch_variable_model";
29
30
 
30
- class FieldVariable extends Blockly.FieldVariable {
31
- originalStyle;
31
+ export class ScratchFieldVariable extends Blockly.FieldVariable {
32
+ private originalStyle: string;
32
33
 
33
- constructor(varName, validator, variableTypes, defaultType, config) {
34
+ constructor(
35
+ varName: string | null | typeof Blockly.Field.SKIP_SETUP,
36
+ validator?: Blockly.FieldVariableValidator,
37
+ variableTypes?: string[],
38
+ defaultType?: string,
39
+ config?: Blockly.FieldVariableConfig
40
+ ) {
34
41
  super(varName, validator, variableTypes, defaultType, config);
35
- this.menuGenerator_ = FieldVariable.dropdownCreate;
42
+ this.menuGenerator_ = ScratchFieldVariable.dropdownCreate;
36
43
  }
37
44
 
38
45
  initModel() {
39
- if (!this.variable) {
46
+ if (!this.getVariable()) {
40
47
  const sourceBlock = this.getSourceBlock();
41
48
  if (sourceBlock) {
42
49
  const broadcastVariable = this.initFlyoutBroadcast(
43
- sourceBlock.workspace
50
+ sourceBlock.workspace as Blockly.WorkspaceSvg
44
51
  );
45
52
  if (broadcastVariable) {
46
53
  this.doValueUpdate_(broadcastVariable.getId());
@@ -59,12 +66,14 @@ class FieldVariable extends Blockly.FieldVariable {
59
66
  * selected option when the workspace is refreshed.
60
67
  * Re-sort the broadcast messages by name, and set the field value to the id
61
68
  * of the variable that comes first in sorted order.
62
- * @param {!Blockly.Workspace} workspace The flyout workspace containing the
63
- * broadcast block.
64
- * @return {string} The variable of type 'broadcast_msg' that comes
65
- * first in sorted order.
69
+ *
70
+ * @param workspace The flyout workspace containing the broadcast block.
71
+ * @returns The variable of type 'broadcast_msg' that comes first in sorted
72
+ * order.
66
73
  */
67
- initFlyoutBroadcast(workspace) {
74
+ initFlyoutBroadcast(
75
+ workspace: Blockly.WorkspaceSvg
76
+ ): Blockly.IVariableModel<Blockly.IVariableState> {
68
77
  const broadcastVars = workspace.getVariablesOfType(
69
78
  Constants.BROADCAST_MESSAGE_VARIABLE_TYPE
70
79
  );
@@ -81,10 +90,10 @@ class FieldVariable extends Blockly.FieldVariable {
81
90
  /**
82
91
  * Return a sorted list of variable names for variable dropdown menus.
83
92
  * Include a special option at the end for creating a new variable name.
84
- * @return {!Array.<string>} Array of variable names.
85
- * @this {Blockly.FieldVariable}
93
+ *
94
+ * @returns Array of variable names.
86
95
  */
87
- static dropdownCreate() {
96
+ static dropdownCreate(this: ScratchFieldVariable): Blockly.MenuOption[] {
88
97
  const options = super.dropdownCreate();
89
98
  const type = this.getDefaultType();
90
99
  if (type === Constants.BROADCAST_MESSAGE_VARIABLE_TYPE) {
@@ -112,16 +121,17 @@ class FieldVariable extends Blockly.FieldVariable {
112
121
  * Special case the 'Rename variable...', 'Delete variable...',
113
122
  * and 'New message...' options.
114
123
  * In the rename case, prompt the user for a new name.
115
- * @param {!Blockly.Menu} menu The Menu component clicked.
116
- * @param {!Blockly.MenuItem} menuItem The MenuItem selected within menu.
124
+ *
125
+ * @param menu The Menu component clicked.
126
+ * @param menuItem The MenuItem selected within menu.
117
127
  */
118
- onItemSelected_(menu, menuItem) {
128
+ onItemSelected_(menu: Blockly.Menu, menuItem: Blockly.MenuItem) {
119
129
  const sourceBlock = this.getSourceBlock();
120
130
  if (sourceBlock && !sourceBlock.isDeadOrDying()) {
121
131
  const selectedItem = menuItem.getValue();
122
132
  if (selectedItem === Constants.NEW_BROADCAST_MESSAGE_ID) {
123
133
  createVariable(
124
- sourceBlock.workspace,
134
+ sourceBlock.workspace as Blockly.WorkspaceSvg,
125
135
  (varId) => {
126
136
  if (varId) {
127
137
  this.setValue(varId);
@@ -131,24 +141,33 @@ class FieldVariable extends Blockly.FieldVariable {
131
141
  );
132
142
  return;
133
143
  } else if (selectedItem === Blockly.RENAME_VARIABLE_ID) {
134
- renameVariable(sourceBlock.workspace, this.variable);
144
+ renameVariable(
145
+ sourceBlock.workspace as Blockly.WorkspaceSvg,
146
+ this.getVariable() as ScratchVariableModel
147
+ );
135
148
  return;
136
149
  }
137
150
  }
138
151
  super.onItemSelected_(menu, menuItem);
139
152
  }
140
153
 
141
- showEditor_(event) {
154
+ showEditor_(event: PointerEvent) {
142
155
  super.showEditor_(event);
143
156
  const sourceBlock = this.getSourceBlock();
144
- const style = sourceBlock.style;
157
+ const styleName = sourceBlock.getStyleName();
158
+ const style = (sourceBlock.workspace as Blockly.WorkspaceSvg)
159
+ .getRenderer()
160
+ .getConstants()
161
+ .getBlockStyle(styleName);
145
162
  if (sourceBlock.isShadow()) {
146
- this.originalStyle = sourceBlock.getStyleName();
163
+ this.originalStyle = styleName;
147
164
  sourceBlock.setStyle(`${this.originalStyle}_selected`);
148
165
  } else if (this.borderRect_) {
149
166
  this.borderRect_.setAttribute(
150
167
  "fill",
151
- style.colourQuaternary ?? style.colourTertiary
168
+ "colourQuaternary" in style
169
+ ? `${style.colourQuaternary}`
170
+ : style.colourTertiary
152
171
  );
153
172
  }
154
173
  }
@@ -165,7 +184,7 @@ class FieldVariable extends Blockly.FieldVariable {
165
184
  /**
166
185
  * Register the field and any dependencies.
167
186
  */
168
- export function registerFieldVariable() {
187
+ export function registerScratchFieldVariable() {
169
188
  Blockly.fieldRegistry.unregister("field_variable");
170
- Blockly.fieldRegistry.register("field_variable", FieldVariable);
189
+ Blockly.fieldRegistry.register("field_variable", ScratchFieldVariable);
171
190
  }
@@ -5,55 +5,51 @@
5
5
  */
6
6
 
7
7
  import * as Blockly from "blockly/core";
8
- import { CheckboxBubble } from "./checkbox_bubble.js";
8
+ import { CheckboxBubble } from "./checkbox_bubble";
9
9
 
10
10
  /**
11
11
  * Invisible icon that exists solely to host the corresponding checkbox bubble.
12
- * @implements {Blockly.IIcon}
13
- * @implements {Blockly.IHasBubble}
14
12
  */
15
- export class FlyoutCheckboxIcon {
16
- sourceBlock;
17
- checkboxBubble;
18
- type = new Blockly.icons.IconType("checkbox");
13
+ export class FlyoutCheckboxIcon implements Blockly.IIcon, Blockly.IHasBubble {
14
+ private checkboxBubble: CheckboxBubble;
15
+ private type = new Blockly.icons.IconType("checkbox");
19
16
 
20
- constructor(sourceBlock) {
21
- this.sourceBlock = sourceBlock;
17
+ constructor(private sourceBlock: Blockly.BlockSvg) {
22
18
  if (this.sourceBlock.workspace.isFlyout) {
23
19
  this.checkboxBubble = new CheckboxBubble(this.sourceBlock);
24
20
  }
25
21
  }
26
22
 
27
- getType() {
23
+ getType(): Blockly.icons.IconType<FlyoutCheckboxIcon> {
28
24
  return this.type;
29
25
  }
30
26
 
31
- getWeight() {
27
+ getWeight(): number {
32
28
  return -1;
33
29
  }
34
30
 
35
- getSize() {
31
+ getSize(): Blockly.utils.Size {
36
32
  // Awful hack to cancel out the default padding added to icons.
37
33
  return new Blockly.utils.Size(-8, 0);
38
34
  }
39
35
 
40
- isShownWhenCollapsed() {
36
+ isShownWhenCollapsed(): boolean {
41
37
  return false;
42
38
  }
43
39
 
44
- isClickableInFlyout() {
40
+ isClickableInFlyout(): boolean {
45
41
  return false;
46
42
  }
47
43
 
48
- bubbleIsVisible() {
44
+ bubbleIsVisible(): boolean {
49
45
  return this.sourceBlock.workspace.isFlyout;
50
46
  }
51
47
 
52
- onLocationChange(blockOrigin) {
48
+ onLocationChange(blockOrigin: Blockly.utils.Coordinate) {
53
49
  this.checkboxBubble?.updateLocation();
54
50
  }
55
51
 
56
- setChecked(checked) {
52
+ setChecked(checked: boolean) {
57
53
  this.checkboxBubble?.setChecked(checked);
58
54
  }
59
55
 
@@ -75,9 +71,9 @@ export class FlyoutCheckboxIcon {
75
71
 
76
72
  onClick() {}
77
73
 
78
- async setBubbleVisible(visible) {}
74
+ async setBubbleVisible(visible: boolean) {}
79
75
 
80
- initView(pointerDownListener) {}
76
+ initView(pointerDownListener: (e: PointerEvent) => void) {}
81
77
  }
82
78
 
83
79
  Blockly.registry.register(
@@ -1,30 +1,41 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2024 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
1
7
  import * as Blockly from "blockly/core";
2
- import { Colours } from "./colours.js";
8
+ import { Colours } from "./colours";
3
9
 
4
10
  /**
5
11
  * Glow/unglow a stack in the workspace.
6
- * @param {?string} id ID of block which starts the stack.
7
- * @param {boolean} isGlowingStack Whether to glow the stack.
12
+ *
13
+ * @param id ID of block which starts the stack.
14
+ * @param isGlowingStack Whether to glow the stack.
8
15
  */
9
- export function glowStack(id, isGlowingStack) {
10
- if (id) {
11
- const block =
12
- Blockly.getMainWorkspace().getBlockById(id) ||
13
- Blockly.getMainWorkspace().getFlyout().getWorkspace().getBlockById(id);
14
- if (!block) {
15
- throw "Tried to glow block that does not exist.";
16
- }
16
+ export function glowStack(id: string, isGlowingStack: boolean) {
17
+ const block = (Blockly.getMainWorkspace().getBlockById(id) ||
18
+ (Blockly.getMainWorkspace() as Blockly.WorkspaceSvg)
19
+ .getFlyout()
20
+ .getWorkspace()
21
+ .getBlockById(id)) as Blockly.BlockSvg;
22
+ if (!block) {
23
+ throw "Tried to glow block that does not exist.";
24
+ }
17
25
 
18
- const svg = block.getSvgRoot();
19
- if (isGlowingStack && !svg.hasAttribute("filter")) {
20
- svg.setAttribute("filter", "url(#blocklyStackGlowFilter)");
21
- } else if (!isGlowingStack && svg.hasAttribute("filter")) {
22
- svg.removeAttribute("filter");
23
- }
26
+ const svg = block.getSvgRoot();
27
+ if (isGlowingStack && !svg.hasAttribute("filter")) {
28
+ svg.setAttribute("filter", "url(#blocklyStackGlowFilter)");
29
+ } else if (!isGlowingStack && svg.hasAttribute("filter")) {
30
+ svg.removeAttribute("filter");
24
31
  }
25
32
  }
26
33
 
27
- export function buildGlowFilter(workspace) {
34
+ /**
35
+ * Creates an SVG filter to render block glows and adds it to the DOM.
36
+ * @param workspace The workspace whose DOM the filter will be inserted in.
37
+ */
38
+ export function buildGlowFilter(workspace: Blockly.WorkspaceSvg) {
28
39
  const svg = workspace.getParentSvg();
29
40
  const defs = Blockly.utils.dom.createSvgElement(
30
41
  Blockly.utils.Svg.DEFS,