scratch-blocks 2.0.1 → 2.0.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 (276) hide show
  1. package/AGENTS.md +140 -0
  2. package/commitlint.config.js +2 -2
  3. package/dist/main.mjs +1 -2
  4. package/dist/types/msg/scratch_msgs.d.ts.map +1 -1
  5. package/dist/types/src/block_reporting.d.ts.map +1 -1
  6. package/dist/types/src/blocks/colour.d.ts +0 -19
  7. package/dist/types/src/blocks/colour.d.ts.map +1 -1
  8. package/dist/types/src/blocks/control.d.ts +0 -19
  9. package/dist/types/src/blocks/control.d.ts.map +1 -1
  10. package/dist/types/src/blocks/data.d.ts +0 -19
  11. package/dist/types/src/blocks/data.d.ts.map +1 -1
  12. package/dist/types/src/blocks/event.d.ts +0 -19
  13. package/dist/types/src/blocks/event.d.ts.map +1 -1
  14. package/dist/types/src/blocks/looks.d.ts +0 -19
  15. package/dist/types/src/blocks/looks.d.ts.map +1 -1
  16. package/dist/types/src/blocks/math.d.ts +0 -19
  17. package/dist/types/src/blocks/math.d.ts.map +1 -1
  18. package/dist/types/src/blocks/matrix.d.ts +0 -19
  19. package/dist/types/src/blocks/matrix.d.ts.map +1 -1
  20. package/dist/types/src/blocks/motion.d.ts +0 -19
  21. package/dist/types/src/blocks/motion.d.ts.map +1 -1
  22. package/dist/types/src/blocks/note.d.ts +0 -19
  23. package/dist/types/src/blocks/note.d.ts.map +1 -1
  24. package/dist/types/src/blocks/operators.d.ts +0 -19
  25. package/dist/types/src/blocks/operators.d.ts.map +1 -1
  26. package/dist/types/src/blocks/procedures.d.ts +6 -9
  27. package/dist/types/src/blocks/procedures.d.ts.map +1 -1
  28. package/dist/types/src/blocks/sensing.d.ts +0 -19
  29. package/dist/types/src/blocks/sensing.d.ts.map +1 -1
  30. package/dist/types/src/blocks/sound.d.ts +0 -19
  31. package/dist/types/src/blocks/sound.d.ts.map +1 -1
  32. package/dist/types/src/blocks/text.d.ts +0 -19
  33. package/dist/types/src/blocks/text.d.ts.map +1 -1
  34. package/dist/types/src/blocks/vertical_extensions.d.ts +0 -19
  35. package/dist/types/src/blocks/vertical_extensions.d.ts.map +1 -1
  36. package/dist/types/src/checkable_continuous_flyout.d.ts +2 -7
  37. package/dist/types/src/checkable_continuous_flyout.d.ts.map +1 -1
  38. package/dist/types/src/checkbox_bubble.d.ts +13 -12
  39. package/dist/types/src/checkbox_bubble.d.ts.map +1 -1
  40. package/dist/types/src/colours.d.ts.map +1 -1
  41. package/dist/types/src/constants.d.ts +0 -7
  42. package/dist/types/src/constants.d.ts.map +1 -1
  43. package/dist/types/src/context_menu_items.d.ts +0 -5
  44. package/dist/types/src/context_menu_items.d.ts.map +1 -1
  45. package/dist/types/src/data_category.d.ts +2 -4
  46. package/dist/types/src/data_category.d.ts.map +1 -1
  47. package/dist/types/src/events/events_block_comment_base.d.ts +2 -3
  48. package/dist/types/src/events/events_block_comment_base.d.ts.map +1 -1
  49. package/dist/types/src/events/events_block_comment_change.d.ts +0 -5
  50. package/dist/types/src/events/events_block_comment_change.d.ts.map +1 -1
  51. package/dist/types/src/events/events_block_comment_collapse.d.ts +0 -5
  52. package/dist/types/src/events/events_block_comment_collapse.d.ts.map +1 -1
  53. package/dist/types/src/events/events_block_comment_create.d.ts +0 -5
  54. package/dist/types/src/events/events_block_comment_create.d.ts.map +1 -1
  55. package/dist/types/src/events/events_block_comment_delete.d.ts +0 -5
  56. package/dist/types/src/events/events_block_comment_delete.d.ts.map +1 -1
  57. package/dist/types/src/events/events_block_comment_move.d.ts +0 -5
  58. package/dist/types/src/events/events_block_comment_move.d.ts.map +1 -1
  59. package/dist/types/src/events/events_block_comment_resize.d.ts +0 -5
  60. package/dist/types/src/events/events_block_comment_resize.d.ts.map +1 -1
  61. package/dist/types/src/events/events_block_drag_end.d.ts +1 -2
  62. package/dist/types/src/events/events_block_drag_end.d.ts.map +1 -1
  63. package/dist/types/src/events/events_block_drag_outside.d.ts +1 -2
  64. package/dist/types/src/events/events_block_drag_outside.d.ts.map +1 -1
  65. package/dist/types/src/events/events_scratch_variable_create.d.ts +0 -5
  66. package/dist/types/src/events/events_scratch_variable_create.d.ts.map +1 -1
  67. package/dist/types/src/fields/field_colour_slider.d.ts +7 -31
  68. package/dist/types/src/fields/field_colour_slider.d.ts.map +1 -1
  69. package/dist/types/src/fields/field_matrix.d.ts +0 -19
  70. package/dist/types/src/fields/field_matrix.d.ts.map +1 -1
  71. package/dist/types/src/fields/field_note.d.ts +8 -23
  72. package/dist/types/src/fields/field_note.d.ts.map +1 -1
  73. package/dist/types/src/fields/field_textinput_removable.d.ts +2 -4
  74. package/dist/types/src/fields/field_textinput_removable.d.ts.map +1 -1
  75. package/dist/types/src/fields/field_variable_getter.d.ts +0 -19
  76. package/dist/types/src/fields/field_variable_getter.d.ts.map +1 -1
  77. package/dist/types/src/fields/field_vertical_separator.d.ts +0 -19
  78. package/dist/types/src/fields/field_vertical_separator.d.ts.map +1 -1
  79. package/dist/types/src/fields/scratch_field_angle.d.ts +0 -19
  80. package/dist/types/src/fields/scratch_field_angle.d.ts.map +1 -1
  81. package/dist/types/src/fields/scratch_field_dropdown.d.ts +0 -5
  82. package/dist/types/src/fields/scratch_field_dropdown.d.ts.map +1 -1
  83. package/dist/types/src/fields/scratch_field_number.d.ts +0 -19
  84. package/dist/types/src/fields/scratch_field_number.d.ts.map +1 -1
  85. package/dist/types/src/fields/scratch_field_variable.d.ts +5 -8
  86. package/dist/types/src/fields/scratch_field_variable.d.ts.map +1 -1
  87. package/dist/types/src/flyout_checkbox_icon.d.ts +2 -3
  88. package/dist/types/src/flyout_checkbox_icon.d.ts.map +1 -1
  89. package/dist/types/src/glows.d.ts +1 -3
  90. package/dist/types/src/glows.d.ts.map +1 -1
  91. package/dist/types/src/index.d.ts +50 -51
  92. package/dist/types/src/index.d.ts.map +1 -1
  93. package/dist/types/src/procedures.d.ts +6 -8
  94. package/dist/types/src/procedures.d.ts.map +1 -1
  95. package/dist/types/src/recyclable_block_flyout_inflater.d.ts +3 -5
  96. package/dist/types/src/recyclable_block_flyout_inflater.d.ts.map +1 -1
  97. package/dist/types/src/renderer/bowler_hat.d.ts +2 -3
  98. package/dist/types/src/renderer/bowler_hat.d.ts.map +1 -1
  99. package/dist/types/src/renderer/cat/cat_face.d.ts +6 -5
  100. package/dist/types/src/renderer/cat/cat_face.d.ts.map +1 -1
  101. package/dist/types/src/renderer/cat/constants.d.ts +2 -2
  102. package/dist/types/src/renderer/cat/constants.d.ts.map +1 -1
  103. package/dist/types/src/renderer/cat/drawer.d.ts +4 -5
  104. package/dist/types/src/renderer/cat/drawer.d.ts.map +1 -1
  105. package/dist/types/src/renderer/cat/path_object.d.ts +2 -3
  106. package/dist/types/src/renderer/cat/path_object.d.ts.map +1 -1
  107. package/dist/types/src/renderer/cat/render_info.d.ts +3 -4
  108. package/dist/types/src/renderer/cat/render_info.d.ts.map +1 -1
  109. package/dist/types/src/renderer/cat/renderer.d.ts +7 -8
  110. package/dist/types/src/renderer/cat/renderer.d.ts.map +1 -1
  111. package/dist/types/src/renderer/constants.d.ts +41 -0
  112. package/dist/types/src/renderer/constants.d.ts.map +1 -0
  113. package/dist/types/src/renderer/drawer.d.ts +7 -6
  114. package/dist/types/src/renderer/drawer.d.ts.map +1 -1
  115. package/dist/types/src/renderer/path_object.d.ts +1 -3
  116. package/dist/types/src/renderer/path_object.d.ts.map +1 -1
  117. package/dist/types/src/renderer/render_info.d.ts +3 -4
  118. package/dist/types/src/renderer/render_info.d.ts.map +1 -1
  119. package/dist/types/src/renderer/renderer.d.ts +9 -16
  120. package/dist/types/src/renderer/renderer.d.ts.map +1 -1
  121. package/dist/types/src/scratch_block_paster.d.ts +0 -5
  122. package/dist/types/src/scratch_block_paster.d.ts.map +1 -1
  123. package/dist/types/src/scratch_blocks_utils.d.ts +0 -20
  124. package/dist/types/src/scratch_blocks_utils.d.ts.map +1 -1
  125. package/dist/types/src/scratch_comment_bubble.d.ts +3 -6
  126. package/dist/types/src/scratch_comment_bubble.d.ts.map +1 -1
  127. package/dist/types/src/scratch_comment_icon.d.ts +3 -4
  128. package/dist/types/src/scratch_comment_icon.d.ts.map +1 -1
  129. package/dist/types/src/scratch_connection_checker.d.ts +0 -5
  130. package/dist/types/src/scratch_connection_checker.d.ts.map +1 -1
  131. package/dist/types/src/scratch_continuous_category.d.ts +5 -5
  132. package/dist/types/src/scratch_continuous_category.d.ts.map +1 -1
  133. package/dist/types/src/scratch_continuous_toolbox.d.ts +3 -6
  134. package/dist/types/src/scratch_continuous_toolbox.d.ts.map +1 -1
  135. package/dist/types/src/scratch_dragger.d.ts +2 -11
  136. package/dist/types/src/scratch_dragger.d.ts.map +1 -1
  137. package/dist/types/src/scratch_insertion_marker_previewer.d.ts +0 -5
  138. package/dist/types/src/scratch_insertion_marker_previewer.d.ts.map +1 -1
  139. package/dist/types/src/scratch_variable_map.d.ts +0 -5
  140. package/dist/types/src/scratch_variable_map.d.ts.map +1 -1
  141. package/dist/types/src/scratch_variable_model.d.ts +2 -3
  142. package/dist/types/src/scratch_variable_model.d.ts.map +1 -1
  143. package/dist/types/src/scratch_zoom_controls.d.ts +4 -6
  144. package/dist/types/src/scratch_zoom_controls.d.ts.map +1 -1
  145. package/dist/types/src/shadows.d.ts +2 -2
  146. package/dist/types/src/shadows.d.ts.map +1 -1
  147. package/dist/types/src/status_indicator_label.d.ts +4 -6
  148. package/dist/types/src/status_indicator_label.d.ts.map +1 -1
  149. package/dist/types/src/status_indicator_label_flyout_inflater.d.ts +1 -6
  150. package/dist/types/src/status_indicator_label_flyout_inflater.d.ts.map +1 -1
  151. package/dist/types/src/variables.d.ts +4 -8
  152. package/dist/types/src/variables.d.ts.map +1 -1
  153. package/dist/types/src/xml.d.ts +2 -3
  154. package/dist/types/src/xml.d.ts.map +1 -1
  155. package/dist/types/tests/jsunit/block_test.d.ts.map +1 -1
  156. package/dist/types/tests/jsunit/connection_db_test.d.ts +3 -3
  157. package/dist/types/tests/jsunit/connection_db_test.d.ts.map +1 -1
  158. package/dist/types/tests/jsunit/connection_test.d.ts.map +1 -1
  159. package/dist/types/tests/jsunit/event_test.d.ts.map +1 -1
  160. package/dist/types/tests/jsunit/extensions_test.d.ts.map +1 -1
  161. package/dist/types/tests/jsunit/field_number_test.d.ts.map +1 -1
  162. package/dist/types/tests/jsunit/field_test.d.ts.map +1 -1
  163. package/dist/types/tests/jsunit/field_variable_getter_test.d.ts.map +1 -1
  164. package/dist/types/tests/jsunit/field_variable_test.d.ts.map +1 -1
  165. package/dist/types/tests/jsunit/gesture_test.d.ts.map +1 -1
  166. package/dist/types/tests/jsunit/input_test.d.ts +1 -0
  167. package/dist/types/tests/jsunit/input_test.d.ts.map +1 -1
  168. package/dist/types/tests/jsunit/json_test.d.ts.map +1 -1
  169. package/dist/types/tests/jsunit/names_test.d.ts.map +1 -1
  170. package/dist/types/tests/jsunit/procedure_test.d.ts.map +1 -1
  171. package/dist/types/tests/jsunit/scratch_block_comment_test.d.ts.map +1 -1
  172. package/dist/types/tests/jsunit/svg_test.d.ts.map +1 -1
  173. package/dist/types/tests/jsunit/test_utilities.d.ts.map +1 -1
  174. package/dist/types/tests/jsunit/utils_test.d.ts.map +1 -1
  175. package/dist/types/tests/jsunit/variable_map_test.d.ts.map +1 -1
  176. package/dist/types/tests/jsunit/variable_model_test.d.ts.map +1 -1
  177. package/dist/types/tests/jsunit/widget_div_test.d.ts.map +1 -1
  178. package/dist/types/tests/jsunit/workspace_comment_test.d.ts.map +1 -1
  179. package/dist/types/tests/jsunit/workspace_test.d.ts.map +1 -1
  180. package/dist/types/tests/jsunit/workspace_undo_redo_test.d.ts.map +1 -1
  181. package/dist/types/tests/jsunit/xml_test.d.ts.map +1 -1
  182. package/dist/types/tests/workspace_svg/workspace_svg_test.d.ts.map +1 -1
  183. package/eslint.config.mjs +69 -0
  184. package/i18n/create_scratch_msgs.js +44 -45
  185. package/i18n/js_to_json.js +40 -32
  186. package/i18n/json_to_js.js +37 -37
  187. package/i18n/sync_tx_translations.js +64 -65
  188. package/i18n/test_scratch_msgs.js +66 -63
  189. package/msg/js/en.js +289 -287
  190. package/msg/json/en.json +284 -284
  191. package/msg/messages.js +289 -287
  192. package/msg/scratch_msgs.js +22959 -22970
  193. package/package.json +13 -10
  194. package/prettier.config.mjs +3 -0
  195. package/release.config.js +7 -7
  196. package/renovate.json5 +7 -9
  197. package/src/block_reporting.ts +16 -19
  198. package/src/blocks/colour.ts +12 -15
  199. package/src/blocks/control.ts +171 -174
  200. package/src/blocks/data.ts +233 -272
  201. package/src/blocks/event.ts +121 -123
  202. package/src/blocks/looks.ts +165 -167
  203. package/src/blocks/math.ts +44 -46
  204. package/src/blocks/matrix.ts +11 -13
  205. package/src/blocks/motion.ts +151 -153
  206. package/src/blocks/note.ts +11 -13
  207. package/src/blocks/operators.ts +158 -160
  208. package/src/blocks/procedures.ts +421 -511
  209. package/src/blocks/sensing.ts +163 -165
  210. package/src/blocks/sound.ts +58 -60
  211. package/src/blocks/text.ts +10 -12
  212. package/src/blocks/vertical_extensions.ts +86 -102
  213. package/src/checkable_continuous_flyout.ts +25 -42
  214. package/src/checkbox_bubble.ts +83 -100
  215. package/src/colours.ts +35 -37
  216. package/src/constants.ts +22 -29
  217. package/src/context_menu_items.ts +59 -84
  218. package/src/css.ts +3 -4
  219. package/src/data_category.ts +137 -251
  220. package/src/events/events_block_comment_base.ts +23 -30
  221. package/src/events/events_block_comment_change.ts +21 -42
  222. package/src/events/events_block_comment_collapse.ts +27 -36
  223. package/src/events/events_block_comment_create.ts +32 -46
  224. package/src/events/events_block_comment_delete.ts +12 -19
  225. package/src/events/events_block_comment_move.ts +27 -52
  226. package/src/events/events_block_comment_resize.ts +28 -55
  227. package/src/events/events_block_drag_end.ts +16 -26
  228. package/src/events/events_block_drag_outside.ts +12 -22
  229. package/src/events/events_scratch_variable_create.ts +37 -42
  230. package/src/fields/field_colour_slider.ts +186 -216
  231. package/src/fields/field_matrix.ts +202 -270
  232. package/src/fields/field_note.ts +277 -375
  233. package/src/fields/field_textinput_removable.ts +25 -40
  234. package/src/fields/field_variable_getter.ts +26 -31
  235. package/src/fields/field_vertical_separator.ts +19 -24
  236. package/src/fields/scratch_field_angle.ts +151 -187
  237. package/src/fields/scratch_field_dropdown.ts +15 -19
  238. package/src/fields/scratch_field_number.ts +125 -181
  239. package/src/fields/scratch_field_variable.ts +57 -75
  240. package/src/flyout_checkbox_icon.ts +18 -28
  241. package/src/glows.ts +52 -59
  242. package/src/index.ts +119 -133
  243. package/src/procedures.ts +150 -209
  244. package/src/recyclable_block_flyout_inflater.ts +14 -25
  245. package/src/renderer/bowler_hat.ts +6 -8
  246. package/src/renderer/cat/cat_face.ts +98 -99
  247. package/src/renderer/cat/constants.ts +67 -87
  248. package/src/renderer/cat/drawer.ts +21 -27
  249. package/src/renderer/cat/path_object.ts +3 -5
  250. package/src/renderer/cat/render_info.ts +5 -8
  251. package/src/renderer/cat/renderer.ts +12 -16
  252. package/src/renderer/constants.ts +34 -49
  253. package/src/renderer/drawer.ts +35 -51
  254. package/src/renderer/path_object.ts +4 -10
  255. package/src/renderer/render_info.ts +39 -56
  256. package/src/renderer/renderer.ts +17 -30
  257. package/src/scratch_block_paster.ts +12 -20
  258. package/src/scratch_blocks_utils.ts +4 -7
  259. package/src/scratch_comment_bubble.ts +76 -105
  260. package/src/scratch_comment_icon.ts +75 -124
  261. package/src/scratch_connection_checker.ts +7 -17
  262. package/src/scratch_continuous_category.ts +24 -28
  263. package/src/scratch_continuous_toolbox.ts +20 -27
  264. package/src/scratch_dragger.ts +42 -81
  265. package/src/scratch_insertion_marker_previewer.ts +6 -11
  266. package/src/scratch_variable_map.ts +5 -12
  267. package/src/scratch_variable_model.ts +6 -13
  268. package/src/scratch_zoom_controls.ts +101 -156
  269. package/src/shadows.ts +32 -37
  270. package/src/status_indicator_label.ts +54 -67
  271. package/src/status_indicator_label_flyout_inflater.ts +11 -21
  272. package/src/variables.ts +92 -141
  273. package/src/xml.ts +21 -35
  274. package/tsconfig.json +3 -7
  275. package/types/continuous-toolbox.d.ts +1 -1
  276. package/dist/main.mjs.LICENSE.txt +0 -163
@@ -1,5 +1,4 @@
1
1
  /**
2
- * @license
3
2
  * Visual Blocks Editor
4
3
  *
5
4
  * Copyright 2012 Google Inc.
@@ -17,32 +16,31 @@
17
16
  * See the License for the specific language governing permissions and
18
17
  * limitations under the License.
19
18
  */
20
-
21
19
  /**
22
- * @fileoverview Procedure blocks for Scratch.
20
+ * @file Procedure blocks for Scratch.
23
21
  */
24
-
25
- import * as Blockly from "blockly/core";
26
- import { FieldTextInputRemovable } from "../fields/field_textinput_removable";
27
- import type { ScratchDragger } from "../scratch_dragger";
22
+ import * as Blockly from 'blockly/core'
23
+ import { FieldTextInputRemovable } from '../fields/field_textinput_removable'
24
+ import type { ScratchDragger } from '../scratch_dragger'
28
25
 
29
26
  /**
30
27
  * An object mapping argument IDs to blocks and shadow DOMs.
31
28
  */
32
- type ConnectionMap = {
33
- [key: string]: {
34
- shadow: Element;
35
- block: Blockly.BlockSvg;
36
- };
37
- };
29
+ type ConnectionMap = Record<
30
+ string,
31
+ {
32
+ shadow: Element
33
+ block: Blockly.BlockSvg
34
+ } | null
35
+ >
38
36
 
39
37
  /**
40
38
  * Possible types for procedure arguments.
41
39
  */
42
40
  enum ArgumentType {
43
- STRING = "s",
44
- NUMBER = "n",
45
- BOOLEAN = "b",
41
+ STRING = 's',
42
+ NUMBER = 'n',
43
+ BOOLEAN = 'b',
46
44
  }
47
45
 
48
46
  /**
@@ -52,48 +50,59 @@ class DuplicateOnDragDraggable implements Blockly.IDraggable {
52
50
  /**
53
51
  * The newly-created duplicate block.
54
52
  */
55
- private copy?: Blockly.BlockSvg;
53
+ private copy?: Blockly.BlockSvg
56
54
  constructor(private block: Blockly.BlockSvg) {}
57
55
 
58
56
  /**
59
- * Returns whether or not this draggable is movable. */
57
+ * Returns whether or not this draggable is movable.
58
+ * @returns Always true.
59
+ */
60
60
  isMovable(): boolean {
61
- return true;
61
+ return true
62
62
  }
63
63
 
64
64
  /**
65
65
  * Handles the start of a drag.
66
- *
67
66
  * @param e The event that triggered the drag.
68
67
  */
69
68
  startDrag(e: PointerEvent) {
70
- const data = this.block.toCopyData();
71
- this.copy = Blockly.clipboard.paste(
72
- data,
73
- this.block.workspace
74
- ) as Blockly.BlockSvg;
75
- this.copy.startDrag(e);
69
+ const data = this.block.toCopyData()
70
+ if (!data) {
71
+ console.warn(
72
+ 'DuplicateOnDragDraggable.startDrag: failed to serialize block for copy',
73
+ this.block.type,
74
+ this.block.id,
75
+ )
76
+ return
77
+ }
78
+ this.copy = Blockly.clipboard.paste(data, this.block.workspace) as Blockly.BlockSvg
79
+ this.copy.startDrag(e)
76
80
  }
77
81
 
78
82
  drag(newLoc: Blockly.utils.Coordinate, e?: PointerEvent) {
79
- (
80
- this.block.workspace.getGesture(e).getCurrentDragger() as ScratchDragger
81
- ).setDraggable(this.copy);
82
- this.copy.drag(newLoc, e);
83
+ const gesture = this.block.workspace.getGesture(e)
84
+ if (!gesture || !this.copy) {
85
+ console.warn('DuplicateOnDragDraggable.drag: missing gesture or copied block', {
86
+ hasGesture: Boolean(gesture),
87
+ hasCopy: Boolean(this.copy),
88
+ blockId: this.block.id,
89
+ })
90
+ return
91
+ }
92
+ ;(gesture.getCurrentDragger() as ScratchDragger).setDraggable(this.copy)
93
+ this.copy.drag(newLoc, e)
83
94
  }
84
95
 
85
96
  endDrag(e: PointerEvent) {
86
- this.copy?.endDrag(e);
97
+ this.copy?.endDrag(e)
87
98
  }
88
99
 
89
100
  revertDrag() {
90
- this.copy?.dispose();
101
+ this.copy?.dispose()
91
102
  }
92
103
 
93
104
  getRelativeToSurfaceXY() {
94
- return this.copy
95
- ? this.copy.getRelativeToSurfaceXY()
96
- : this.block.getRelativeToSurfaceXY();
105
+ return this.copy ? this.copy.getRelativeToSurfaceXY() : this.block.getRelativeToSurfaceXY()
97
106
  }
98
107
  }
99
108
 
@@ -102,85 +111,71 @@ class DuplicateOnDragDraggable implements Blockly.IDraggable {
102
111
  /**
103
112
  * Create XML to represent the (non-editable) name and arguments of a procedure
104
113
  * call block.
105
- *
106
114
  * @returns XML storage element.
107
115
  */
108
116
  function callerMutationToDom(this: ProcedureCallBlock): Element {
109
- const container = document.createElement("mutation");
110
- container.setAttribute("proccode", this.procCode_);
111
- container.setAttribute("argumentids", JSON.stringify(this.argumentIds_));
112
- container.setAttribute("warp", JSON.stringify(this.warp_));
113
- return container;
117
+ const container = document.createElement('mutation')
118
+ container.setAttribute('proccode', this.procCode_)
119
+ container.setAttribute('argumentids', JSON.stringify(this.argumentIds_))
120
+ container.setAttribute('warp', JSON.stringify(this.warp_))
121
+ return container
114
122
  }
115
123
 
116
124
  /**
117
125
  * Parse XML to restore the (non-editable) name and arguments of a procedure
118
126
  * call block.
119
- *
120
127
  * @param xmlElement XML storage element.
121
128
  */
122
129
  function callerDomToMutation(this: ProcedureCallBlock, xmlElement: Element) {
123
- this.procCode_ = xmlElement.getAttribute("proccode");
124
- this.generateShadows_ = JSON.parse(
125
- xmlElement.getAttribute("generateshadows")
126
- );
127
- this.argumentIds_ = JSON.parse(xmlElement.getAttribute("argumentids"));
128
- this.warp_ = JSON.parse(xmlElement.getAttribute("warp"));
129
- this.updateDisplay_();
130
+ this.procCode_ = xmlElement.getAttribute('proccode')!
131
+ this.generateShadows_ = JSON.parse(xmlElement.getAttribute('generateshadows')!)
132
+ this.argumentIds_ = JSON.parse(xmlElement.getAttribute('argumentids')!)
133
+ this.warp_ = JSON.parse(xmlElement.getAttribute('warp')!)
134
+ this.updateDisplay_()
130
135
  }
131
136
 
132
137
  /**
133
138
  * Create XML to represent the (non-editable) name and arguments of a
134
139
  * procedures_prototype block or a procedures_declaration block.
135
- *
136
140
  * @param opt_generateShadows Whether to include the generateshadows flag in the
137
141
  * generated XML. False if not provided.
138
142
  * @returns XML storage element.
139
143
  */
140
144
  function definitionMutationToDom(
141
145
  this: ProcedurePrototypeBlock | ProcedureDeclarationBlock,
142
- opt_generateShadows?: boolean
146
+ opt_generateShadows?: boolean,
143
147
  ): Element {
144
- const container = document.createElement("mutation");
148
+ const container = document.createElement('mutation')
145
149
 
146
150
  if (opt_generateShadows) {
147
- container.setAttribute("generateshadows", "true");
151
+ container.setAttribute('generateshadows', 'true')
148
152
  }
149
- container.setAttribute("proccode", this.procCode_);
150
- container.setAttribute("argumentids", JSON.stringify(this.argumentIds_));
151
- container.setAttribute("argumentnames", JSON.stringify(this.displayNames_));
152
- container.setAttribute(
153
- "argumentdefaults",
154
- JSON.stringify(this.argumentDefaults_)
155
- );
156
- container.setAttribute("warp", JSON.stringify(this.warp_));
157
- return container;
153
+ container.setAttribute('proccode', this.procCode_)
154
+ container.setAttribute('argumentids', JSON.stringify(this.argumentIds_))
155
+ container.setAttribute('argumentnames', JSON.stringify(this.displayNames_))
156
+ container.setAttribute('argumentdefaults', JSON.stringify(this.argumentDefaults_))
157
+ container.setAttribute('warp', JSON.stringify(this.warp_))
158
+ return container
158
159
  }
159
160
 
160
161
  /**
161
162
  * Parse XML to restore the (non-editable) name and arguments of a
162
163
  * procedures_prototype block or a procedures_declaration block.
163
- *
164
164
  * @param xmlElement XML storage element.
165
165
  */
166
- function definitionDomToMutation(
167
- this: ProcedurePrototypeBlock | ProcedureDeclarationBlock,
168
- xmlElement: Element
169
- ) {
170
- this.procCode_ = xmlElement.getAttribute("proccode");
171
- this.warp_ = JSON.parse(xmlElement.getAttribute("warp"));
172
-
173
- const prevArgIds = this.argumentIds_;
174
- const prevDisplayNames = this.displayNames_;
175
-
176
- this.argumentIds_ = JSON.parse(xmlElement.getAttribute("argumentids"));
177
- this.displayNames_ = JSON.parse(xmlElement.getAttribute("argumentnames"));
178
- this.argumentDefaults_ = JSON.parse(
179
- xmlElement.getAttribute("argumentdefaults")
180
- );
181
- this.updateDisplay_();
182
- if ("updateArgumentReporterNames_" in this) {
183
- this.updateArgumentReporterNames_(prevArgIds, prevDisplayNames);
166
+ function definitionDomToMutation(this: ProcedurePrototypeBlock | ProcedureDeclarationBlock, xmlElement: Element) {
167
+ this.procCode_ = xmlElement.getAttribute('proccode')!
168
+ this.warp_ = JSON.parse(xmlElement.getAttribute('warp')!)
169
+
170
+ const prevArgIds = this.argumentIds_
171
+ const prevDisplayNames = this.displayNames_
172
+
173
+ this.argumentIds_ = JSON.parse(xmlElement.getAttribute('argumentids')!)
174
+ this.displayNames_ = JSON.parse(xmlElement.getAttribute('argumentnames')!)
175
+ this.argumentDefaults_ = JSON.parse(xmlElement.getAttribute('argumentdefaults')!)
176
+ this.updateDisplay_()
177
+ if ('updateArgumentReporterNames_' in this) {
178
+ this.updateArgumentReporterNames_(prevArgIds, prevDisplayNames)
184
179
  }
185
180
  }
186
181
 
@@ -191,11 +186,10 @@ function definitionDomToMutation(
191
186
  /**
192
187
  * Returns the name of the procedure this block calls, or the empty string if
193
188
  * it has not yet been set.
194
- *
195
189
  * @returns Procedure name.
196
190
  */
197
191
  function getProcCode(this: ProcedureBlock): string {
198
- return this.procCode_;
192
+ return this.procCode_
199
193
  }
200
194
 
201
195
  /**
@@ -203,10 +197,10 @@ function getProcCode(this: ProcedureBlock): string {
203
197
  * mutation.
204
198
  */
205
199
  function updateDisplay_(this: ProcedureBlock) {
206
- const connectionMap = this.disconnectOldBlocks_();
207
- this.removeAllInputs_();
208
- this.createAllInputs_(connectionMap);
209
- this.deleteShadows_(connectionMap);
200
+ const connectionMap = this.disconnectOldBlocks_()
201
+ this.removeAllInputs_()
202
+ this.createAllInputs_(connectionMap)
203
+ this.deleteShadows_(connectionMap)
210
204
  }
211
205
 
212
206
  /**
@@ -214,27 +208,26 @@ function updateDisplay_(this: ProcedureBlock) {
214
208
  * in case they can be reattached later. Also save the shadow DOM if it exists.
215
209
  * The result is a map from argument ID to information that was associated with
216
210
  * that argument at the beginning of the mutation.
217
- *
218
211
  * @returns An object mapping argument IDs to blocks and shadow DOMs.
219
212
  */
220
213
  function disconnectOldBlocks_(this: ProcedureBlock): ConnectionMap {
221
214
  // Remove old stuff
222
- const connectionMap: ConnectionMap = {};
215
+ const connectionMap: ConnectionMap = {}
223
216
  for (const input of this.inputList) {
224
217
  if (input.connection) {
225
- const target = input.connection.targetBlock() as Blockly.BlockSvg;
218
+ const target = input.connection.targetBlock() as Blockly.BlockSvg
226
219
  const saveInfo = {
227
- shadow: input.connection.getShadowDom(true),
220
+ shadow: input.connection.getShadowDom(true)!,
228
221
  block: target,
229
- };
230
- connectionMap[input.name] = saveInfo;
222
+ }
223
+ connectionMap[input.name] = saveInfo
231
224
 
232
225
  if (target) {
233
- input.connection.disconnect();
226
+ input.connection.disconnect()
234
227
  }
235
228
  }
236
229
  }
237
- return connectionMap;
230
+ return connectionMap
238
231
  }
239
232
 
240
233
  /**
@@ -244,29 +237,26 @@ function disconnectOldBlocks_(this: ProcedureBlock): ConnectionMap {
244
237
  function removeAllInputs_(this: ProcedureBlock) {
245
238
  // Delete inputs directly instead of with block.removeInput to avoid splicing
246
239
  // out of the input list at every index.
247
- this.inputList.forEach((input: Blockly.Input) => input.dispose());
248
- this.inputList = [];
240
+ this.inputList.forEach((input: Blockly.Input) => input.dispose())
241
+ this.inputList = []
249
242
  }
250
243
 
251
244
  /**
252
245
  * Create all inputs specified by the new procCode, and populate them with
253
246
  * shadow blocks or reconnected old blocks as appropriate.
254
- *
255
247
  * @param connectionMap An object mapping argument IDs to blocks and shadow DOMs.
256
248
  */
257
249
  function createAllInputs_(this: ProcedureBlock, connectionMap: ConnectionMap) {
258
250
  // Split the proc into components, by %n, %b, and %s (ignoring escaped).
259
- const procComponents = this.procCode_
260
- .split(/(?=[^\\]%[nbs])/)
261
- .map(function (c: string) {
262
- return c.trim(); // Strip whitespace.
263
- });
251
+ const procComponents = this.procCode_.split(/(?=[^\\]%[nbs])/).map(
252
+ (c: string) => c.trim(), // Strip whitespace.
253
+ )
264
254
  // Create arguments and labels as appropriate.
265
- let argumentCount = 0;
255
+ let argumentCount = 0
266
256
  for (const component of procComponents) {
267
- let labelText;
268
- if (component.substring(0, 1) === "%") {
269
- const argumentType = component.substring(1, 2);
257
+ let labelText
258
+ if (component.startsWith('%')) {
259
+ const argumentType = component.substring(1, 2)
270
260
  if (
271
261
  !(
272
262
  argumentType === ArgumentType.NUMBER ||
@@ -274,36 +264,27 @@ function createAllInputs_(this: ProcedureBlock, connectionMap: ConnectionMap) {
274
264
  argumentType === ArgumentType.STRING
275
265
  )
276
266
  ) {
277
- throw new Error(
278
- "Found an custom procedure with an invalid type: " + argumentType
279
- );
267
+ throw new Error('Found an custom procedure with an invalid type: ' + argumentType)
280
268
  }
281
- labelText = component.substring(2).trim();
269
+ labelText = component.substring(2).trim()
282
270
 
283
- const id = this.argumentIds_[argumentCount];
271
+ const id = this.argumentIds_[argumentCount]
284
272
 
285
- const input = this.appendValueInput(id);
273
+ const input = this.appendValueInput(id)
286
274
  if (argumentType === ArgumentType.BOOLEAN) {
287
- input.setCheck("Boolean");
275
+ input.setCheck('Boolean')
288
276
  }
289
- this.populateArgument_(
290
- argumentType,
291
- argumentCount,
292
- connectionMap,
293
- id,
294
- input
295
- );
296
- argumentCount++;
277
+ this.populateArgument_(argumentType, argumentCount, connectionMap, id, input)
278
+ argumentCount++
297
279
  } else {
298
- labelText = component.trim();
280
+ labelText = component.trim()
299
281
  }
300
- this.addProcedureLabel_(labelText.replace(/\\%/, "%"));
282
+ this.addProcedureLabel_(labelText.replace(/\\%/, '%'))
301
283
  }
302
284
  }
303
285
 
304
286
  /**
305
287
  * Delete all shadow blocks in the given map.
306
- *
307
288
  * @param connectionMap An object mapping argument IDs to the blocks that were
308
289
  * connected to those IDs at the beginning of the mutation.
309
290
  */
@@ -311,12 +292,12 @@ function deleteShadows_(this: ProcedureBlock, connectionMap: ConnectionMap) {
311
292
  // Get rid of all of the old shadow blocks if they aren't connected.
312
293
  if (connectionMap) {
313
294
  for (const id in connectionMap) {
314
- const saveInfo = connectionMap[id];
295
+ const saveInfo = connectionMap[id]
315
296
  if (saveInfo) {
316
- const block = saveInfo["block"];
297
+ const block = saveInfo.block
317
298
  if (block && block.isShadow()) {
318
- block.dispose();
319
- connectionMap[id] = null;
299
+ block.dispose()
300
+ connectionMap[id] = null
320
301
  // At this point we know which shadow DOMs are about to be orphaned in
321
302
  // the VM. What do we do with that information?
322
303
  }
@@ -329,104 +310,84 @@ function deleteShadows_(this: ProcedureBlock, connectionMap: ConnectionMap) {
329
310
  /**
330
311
  * Add a label field with the given text to a procedures_call or
331
312
  * procedures_prototype block.
332
- *
333
- * @param text The label text.
313
+ * @param text The string to display in the block's label field.
334
314
  */
335
- function addLabelField_(
336
- this: ProcedureCallBlock | ProcedurePrototypeBlock,
337
- text: string
338
- ) {
339
- this.appendDummyInput().appendField(text);
315
+ function addLabelField_(this: ProcedureCallBlock | ProcedurePrototypeBlock, text: string) {
316
+ this.appendDummyInput().appendField(text)
340
317
  }
341
318
 
342
319
  /**
343
320
  * Add a label editor with the given text to a procedures_declaration
344
321
  * block. Editing the text in the label editor updates the text of the
345
322
  * corresponding label fields on function calls.
346
- *
347
- * @param text The label text.
323
+ * @param text The initial string to show in the label editor.
348
324
  */
349
325
  function addLabelEditor_(this: ProcedureDeclarationBlock, text: string) {
350
326
  if (text) {
351
- this.appendDummyInput(Blockly.utils.idGenerator.genUid()).appendField(
352
- new FieldTextInputRemovable(text)
353
- );
327
+ this.appendDummyInput(Blockly.utils.idGenerator.genUid()).appendField(new FieldTextInputRemovable(text))
354
328
  }
355
329
  }
356
330
 
357
331
  /**
358
332
  * Build a DOM node representing a shadow block of the given type.
359
- *
360
333
  * @param type One of 's' (string) or 'n' (number).
361
334
  * @returns The DOM node representing the new shadow block.
362
335
  */
363
336
  function buildShadowDom_(type: ArgumentType): Element {
364
- const shadowDom = document.createElement("shadow");
365
- let shadowType, fieldName, fieldValue;
337
+ const shadowDom = document.createElement('shadow')
338
+ let shadowType, fieldName, fieldValue
366
339
  if (type === ArgumentType.NUMBER) {
367
- shadowType = "math_number";
368
- fieldName = "NUM";
369
- fieldValue = "1";
340
+ shadowType = 'math_number'
341
+ fieldName = 'NUM'
342
+ fieldValue = '1'
370
343
  } else {
371
- shadowType = "text";
372
- fieldName = "TEXT";
373
- fieldValue = "";
344
+ shadowType = 'text'
345
+ fieldName = 'TEXT'
346
+ fieldValue = ''
374
347
  }
375
- shadowDom.setAttribute("type", shadowType);
376
- const fieldDom = document.createElement("field");
377
- fieldDom.textContent = fieldValue;
378
- fieldDom.setAttribute("name", fieldName);
379
- shadowDom.appendChild(fieldDom);
380
- return shadowDom;
348
+ shadowDom.setAttribute('type', shadowType)
349
+ const fieldDom = document.createElement('field')
350
+ fieldDom.textContent = fieldValue
351
+ fieldDom.setAttribute('name', fieldName)
352
+ shadowDom.appendChild(fieldDom)
353
+ return shadowDom
381
354
  }
382
355
 
383
356
  /**
384
357
  * Create a new shadow block and attach it to the given input.
385
- *
386
358
  * @param input The value input to attach a block to.
387
359
  * @param argumentType One of 'b' (boolean), 's' (string) or
388
360
  * 'n' (number).
389
361
  */
390
- function attachShadow_(
391
- this: ProcedureCallBlock,
392
- input: Blockly.Input,
393
- argumentType: ArgumentType
394
- ) {
395
- if (
396
- argumentType === ArgumentType.NUMBER ||
397
- argumentType === ArgumentType.STRING
398
- ) {
399
- const blockType =
400
- argumentType === ArgumentType.NUMBER ? "math_number" : "text";
401
- Blockly.Events.disable();
402
- let newBlock;
362
+ function attachShadow_(this: ProcedureCallBlock, input: Blockly.Input, argumentType: ArgumentType) {
363
+ if (argumentType === ArgumentType.NUMBER || argumentType === ArgumentType.STRING) {
364
+ const blockType = argumentType === ArgumentType.NUMBER ? 'math_number' : 'text'
365
+ Blockly.Events.disable()
366
+ let newBlock
403
367
  try {
404
- newBlock = this.workspace.newBlock(blockType);
368
+ newBlock = this.workspace.newBlock(blockType)
405
369
  if (argumentType === ArgumentType.NUMBER) {
406
- newBlock.setFieldValue("1", "NUM");
370
+ newBlock.setFieldValue('1', 'NUM')
407
371
  } else {
408
- newBlock.setFieldValue("", "TEXT");
372
+ newBlock.setFieldValue('', 'TEXT')
409
373
  }
410
- newBlock.setShadow(true);
374
+ newBlock.setShadow(true)
411
375
  if (!this.isInsertionMarker()) {
412
- newBlock.initSvg();
413
- newBlock.render();
376
+ newBlock.initSvg()
377
+ newBlock.render()
414
378
  }
415
379
  } finally {
416
- Blockly.Events.enable();
380
+ Blockly.Events.enable()
417
381
  }
418
382
  if (Blockly.Events.isEnabled()) {
419
- Blockly.Events.fire(
420
- new (Blockly.Events.get(Blockly.Events.BLOCK_CREATE))(newBlock)
421
- );
383
+ Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.BLOCK_CREATE))(newBlock))
422
384
  }
423
- newBlock.outputConnection.connect(input.connection);
385
+ newBlock.outputConnection.connect(input.connection!)
424
386
  }
425
387
  }
426
388
 
427
389
  /**
428
390
  * Create a new argument reporter block.
429
- *
430
391
  * @param argumentType One of 'b' (boolean), 's' (string) or
431
392
  * 'n' (number).
432
393
  * @param displayName The name of the argument as provided by the
@@ -436,42 +397,36 @@ function attachShadow_(
436
397
  function createArgumentReporter_(
437
398
  this: ProcedurePrototypeBlock,
438
399
  argumentType: ArgumentType,
439
- displayName: string
400
+ displayName: string,
440
401
  ): Blockly.BlockSvg {
441
- let blockType;
442
- if (
443
- argumentType === ArgumentType.NUMBER ||
444
- argumentType === ArgumentType.STRING
445
- ) {
446
- blockType = "argument_reporter_string_number";
402
+ let blockType
403
+ if (argumentType === ArgumentType.NUMBER || argumentType === ArgumentType.STRING) {
404
+ blockType = 'argument_reporter_string_number'
447
405
  } else {
448
- blockType = "argument_reporter_boolean";
406
+ blockType = 'argument_reporter_boolean'
449
407
  }
450
- Blockly.Events.disable();
451
- let newBlock;
408
+ Blockly.Events.disable()
409
+ let newBlock
452
410
  try {
453
- newBlock = this.workspace.newBlock(blockType);
454
- newBlock.setShadow(true);
455
- newBlock.setFieldValue(displayName, "VALUE");
411
+ newBlock = this.workspace.newBlock(blockType)
412
+ newBlock.setShadow(true)
413
+ newBlock.setFieldValue(displayName, 'VALUE')
456
414
  if (!this.isInsertionMarker()) {
457
- newBlock.initSvg();
458
- newBlock.render();
415
+ newBlock.initSvg()
416
+ newBlock.render()
459
417
  }
460
418
  } finally {
461
- Blockly.Events.enable();
419
+ Blockly.Events.enable()
462
420
  }
463
421
  if (Blockly.Events.isEnabled()) {
464
- Blockly.Events.fire(
465
- new (Blockly.Events.get(Blockly.Events.BLOCK_CREATE))(newBlock)
466
- );
422
+ Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.BLOCK_CREATE))(newBlock))
467
423
  }
468
- return newBlock;
424
+ return newBlock
469
425
  }
470
426
 
471
427
  /**
472
428
  * Populate the argument by attaching the correct child block or shadow to the
473
429
  * given input.
474
- *
475
430
  * @param type One of 'b' (boolean), 's' (string) or 'n' (number).
476
431
  * @param index The index of this argument into the argument id array.
477
432
  * @param connectionMap An object mapping argument IDs to blocks and shadow DOMs.
@@ -484,33 +439,32 @@ function populateArgumentOnCaller_(
484
439
  index: number,
485
440
  connectionMap: ConnectionMap,
486
441
  id: string,
487
- input: Blockly.Input
442
+ input: Blockly.Input,
488
443
  ) {
489
- let oldBlock: Blockly.BlockSvg;
490
- let oldShadow: Element;
444
+ let oldBlock: Blockly.BlockSvg | undefined
445
+ let oldShadow: Element | undefined
491
446
  if (connectionMap && id in connectionMap) {
492
- const saveInfo = connectionMap[id];
493
- oldBlock = saveInfo["block"];
494
- oldShadow = saveInfo["shadow"];
447
+ const saveInfo = connectionMap[id]
448
+ oldBlock = saveInfo?.block
449
+ oldShadow = saveInfo?.shadow
495
450
  }
496
451
 
497
452
  if (connectionMap && oldBlock) {
498
453
  // Reattach the old block and shadow DOM.
499
- connectionMap[input.name] = null;
500
- oldBlock.outputConnection.connect(input.connection);
454
+ connectionMap[input.name] = null
455
+ oldBlock.outputConnection.connect(input.connection!)
501
456
  if (type !== ArgumentType.BOOLEAN && this.generateShadows_) {
502
- const shadowDom = oldShadow || this.buildShadowDom_(type);
503
- input.connection.setShadowDom(shadowDom);
457
+ const shadowDom = oldShadow || this.buildShadowDom_(type)
458
+ input.connection!.setShadowDom(shadowDom)
504
459
  }
505
460
  } else if (this.generateShadows_) {
506
- this.attachShadow_(input, type);
461
+ this.attachShadow_(input, type)
507
462
  }
508
463
  }
509
464
 
510
465
  /**
511
466
  * Populate the argument by attaching the correct argument reporter to the given
512
467
  * input.
513
- *
514
468
  * @param type One of 'b' (boolean), 's' (string) or 'n' (number).
515
469
  * @param index The index of this argument into the argument ID and
516
470
  * argument display name arrays.
@@ -524,37 +478,36 @@ function populateArgumentOnPrototype_(
524
478
  index: number,
525
479
  connectionMap: ConnectionMap,
526
480
  id: string,
527
- input: Blockly.Input
481
+ input: Blockly.Input,
528
482
  ) {
529
- let oldBlock = null;
483
+ let oldBlock: Blockly.BlockSvg | null = null
530
484
  if (connectionMap && id in connectionMap) {
531
- const saveInfo = connectionMap[id];
532
- oldBlock = saveInfo["block"];
485
+ const saveInfo = connectionMap[id]
486
+ oldBlock = saveInfo?.block ?? null
533
487
  }
534
488
 
535
- const oldTypeMatches = checkOldTypeMatches_(oldBlock, type);
536
- const displayName = this.displayNames_[index];
489
+ const oldTypeMatches = checkOldTypeMatches_(oldBlock, type)
490
+ const displayName = this.displayNames_[index]
537
491
 
538
492
  // Decide which block to attach.
539
- let argumentReporter: Blockly.BlockSvg;
493
+ let argumentReporter: Blockly.BlockSvg
540
494
  if (connectionMap && oldBlock && oldTypeMatches) {
541
495
  // Update the text if needed. The old argument reporter is the same type,
542
496
  // and on the same input, but the argument's display name may have changed.
543
- argumentReporter = oldBlock;
544
- argumentReporter.setFieldValue(displayName, "VALUE");
545
- connectionMap[input.name] = null;
497
+ argumentReporter = oldBlock
498
+ argumentReporter.setFieldValue(displayName, 'VALUE')
499
+ connectionMap[input.name] = null
546
500
  } else {
547
- argumentReporter = this.createArgumentReporter_(type, displayName);
501
+ argumentReporter = this.createArgumentReporter_(type, displayName)
548
502
  }
549
503
 
550
504
  // Attach the block.
551
- input.connection.connect(argumentReporter.outputConnection);
505
+ input.connection!.connect(argumentReporter.outputConnection)
552
506
  }
553
507
 
554
508
  /**
555
509
  * Populate the argument by attaching the correct argument editor to the given
556
510
  * input.
557
- *
558
511
  * @param type One of 'b' (boolean), 's' (string) or 'n' (number).
559
512
  * @param index The index of this argument into the argument id and argument
560
513
  * display name arrays.
@@ -568,69 +521,61 @@ function populateArgumentOnDeclaration_(
568
521
  index: number,
569
522
  connectionMap: ConnectionMap,
570
523
  id: string,
571
- input: Blockly.Input
524
+ input: Blockly.Input,
572
525
  ) {
573
- let oldBlock = null;
526
+ let oldBlock: Blockly.BlockSvg | null = null
574
527
  if (connectionMap && id in connectionMap) {
575
- const saveInfo = connectionMap[id];
576
- oldBlock = saveInfo["block"];
528
+ const saveInfo = connectionMap[id]
529
+ oldBlock = saveInfo?.block ?? null
577
530
  }
578
531
 
579
532
  // TODO: This always returns false, because it checks for argument reporter
580
533
  // blocks instead of argument editor blocks. Create a new version for argument
581
534
  // editors.
582
- const oldTypeMatches = checkOldTypeMatches_(oldBlock, type);
583
- const displayName = this.displayNames_[index];
535
+ const oldTypeMatches = checkOldTypeMatches_(oldBlock, type)
536
+ const displayName = this.displayNames_[index]
584
537
 
585
538
  // Decide which block to attach.
586
- let argumentEditor: Blockly.BlockSvg;
539
+ let argumentEditor: Blockly.BlockSvg
587
540
  if (oldBlock && oldTypeMatches) {
588
- argumentEditor = oldBlock;
589
- oldBlock.setFieldValue(displayName, "TEXT");
590
- connectionMap[input.name] = null;
541
+ argumentEditor = oldBlock
542
+ oldBlock.setFieldValue(displayName, 'TEXT')
543
+ connectionMap[input.name] = null
591
544
  } else {
592
- argumentEditor = this.createArgumentEditor_(type, displayName);
545
+ argumentEditor = this.createArgumentEditor_(type, displayName)
593
546
  }
594
547
 
595
548
  // Attach the block.
596
- input.connection.connect(argumentEditor.outputConnection);
549
+ input.connection!.connect(argumentEditor.outputConnection)
597
550
  }
598
551
 
599
552
  /**
600
553
  * Check whether the type of the old block corresponds to the given argument
601
554
  * type.
602
- *
603
555
  * @param oldBlock The old block to check.
604
556
  * @param type The argument type. One of 'n', 'n', or 's'.
605
557
  * @returns True if the type matches, false otherwise.
606
558
  */
607
- function checkOldTypeMatches_(
608
- oldBlock: Blockly.BlockSvg | null,
609
- type: string
610
- ): boolean {
559
+ function checkOldTypeMatches_(oldBlock: Blockly.BlockSvg | null, type: string): boolean {
611
560
  if (!oldBlock) {
612
- return false;
561
+ return false
613
562
  }
614
563
  if (
615
564
  (type === ArgumentType.NUMBER || type === ArgumentType.STRING) &&
616
- oldBlock.type === "argument_reporter_string_number"
565
+ oldBlock.type === 'argument_reporter_string_number'
617
566
  ) {
618
- return true;
567
+ return true
619
568
  }
620
- if (
621
- type === ArgumentType.BOOLEAN &&
622
- oldBlock.type === "argument_reporter_boolean"
623
- ) {
624
- return true;
569
+ if (type === ArgumentType.BOOLEAN && oldBlock.type === 'argument_reporter_boolean') {
570
+ return true
625
571
  }
626
- return false;
572
+ return false
627
573
  }
628
574
 
629
575
  /**
630
576
  * Create an argument editor.
631
577
  * An argument editor is a shadow block with a single text field, which is used
632
578
  * to set the display name of the argument.
633
- *
634
579
  * @param argumentType One of 'b' (boolean), 's' (string) or 'n' (number).
635
580
  * @param displayName The display name of this argument, which is the text of
636
581
  * the field on the shadow block.
@@ -639,34 +584,29 @@ function checkOldTypeMatches_(
639
584
  function createArgumentEditor_(
640
585
  this: ProcedureDeclarationBlock,
641
586
  argumentType: ArgumentType,
642
- displayName: string
587
+ displayName: string,
643
588
  ): Blockly.BlockSvg {
644
- Blockly.Events.disable();
645
- let newBlock;
589
+ Blockly.Events.disable()
590
+ let newBlock
646
591
  try {
647
- if (
648
- argumentType === ArgumentType.NUMBER ||
649
- argumentType === ArgumentType.STRING
650
- ) {
651
- newBlock = this.workspace.newBlock("argument_editor_string_number");
592
+ if (argumentType === ArgumentType.NUMBER || argumentType === ArgumentType.STRING) {
593
+ newBlock = this.workspace.newBlock('argument_editor_string_number')
652
594
  } else {
653
- newBlock = this.workspace.newBlock("argument_editor_boolean");
595
+ newBlock = this.workspace.newBlock('argument_editor_boolean')
654
596
  }
655
- newBlock.setFieldValue(displayName, "TEXT");
656
- newBlock.setShadow(true);
597
+ newBlock.setFieldValue(displayName, 'TEXT')
598
+ newBlock.setShadow(true)
657
599
  if (!this.isInsertionMarker()) {
658
- newBlock.initSvg();
659
- newBlock.queueRender();
600
+ newBlock.initSvg()
601
+ newBlock.queueRender()
660
602
  }
661
603
  } finally {
662
- Blockly.Events.enable();
604
+ Blockly.Events.enable()
663
605
  }
664
606
  if (Blockly.Events.isEnabled()) {
665
- Blockly.Events.fire(
666
- new (Blockly.Events.get(Blockly.Events.BLOCK_CREATE))(newBlock)
667
- );
607
+ Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.BLOCK_CREATE))(newBlock))
668
608
  }
669
- return newBlock;
609
+ return newBlock
670
610
  }
671
611
 
672
612
  /**
@@ -674,30 +614,28 @@ function createArgumentEditor_(
674
614
  * and their text.
675
615
  */
676
616
  function updateDeclarationProcCode_(this: ProcedureDeclarationBlock) {
677
- this.procCode_ = "";
678
- this.displayNames_ = [];
679
- this.argumentIds_ = [];
617
+ this.procCode_ = ''
618
+ this.displayNames_ = []
619
+ this.argumentIds_ = []
680
620
  for (let i = 0; i < this.inputList.length; i++) {
681
621
  if (i !== 0) {
682
- this.procCode_ += " ";
622
+ this.procCode_ += ' '
683
623
  }
684
- const input = this.inputList[i];
624
+ const input = this.inputList[i]
685
625
  if (input.type === Blockly.inputs.inputTypes.DUMMY) {
686
- this.procCode_ += input.fieldRow[0].getValue();
626
+ this.procCode_ += input.fieldRow[0].getValue()
687
627
  } else if (input.type === Blockly.inputs.inputTypes.VALUE) {
688
628
  // Inspect the argument editor.
689
- const target = input.connection.targetBlock();
690
- this.displayNames_.push(target.getFieldValue("TEXT"));
691
- this.argumentIds_.push(input.name);
692
- if (target.type === "argument_editor_boolean") {
693
- this.procCode_ += "%b";
629
+ const target = input.connection!.targetBlock()!
630
+ this.displayNames_.push(target.getFieldValue('TEXT'))
631
+ this.argumentIds_.push(input.name)
632
+ if (target.type === 'argument_editor_boolean') {
633
+ this.procCode_ += '%b'
694
634
  } else {
695
- this.procCode_ += "%s";
635
+ this.procCode_ += '%s'
696
636
  }
697
637
  } else {
698
- throw new Error(
699
- "Unexpected input type on a procedure mutator root: " + input.type
700
- );
638
+ throw new Error('Unexpected input type on a procedure mutator root: ' + input.type)
701
639
  }
702
640
  }
703
641
  }
@@ -707,13 +645,13 @@ function updateDeclarationProcCode_(this: ProcedureDeclarationBlock) {
707
645
  */
708
646
  function focusLastEditor_(this: ProcedureDeclarationBlock) {
709
647
  if (this.inputList.length > 0) {
710
- const newInput = this.inputList[this.inputList.length - 1];
648
+ const newInput = this.inputList[this.inputList.length - 1]
711
649
  if (newInput.type === Blockly.inputs.inputTypes.DUMMY) {
712
- newInput.fieldRow[0].showEditor();
650
+ newInput.fieldRow[0].showEditor()
713
651
  } else if (newInput.type === Blockly.inputs.inputTypes.VALUE) {
714
652
  // Inspect the argument editor.
715
- const target = newInput.connection.targetBlock();
716
- target.getField("TEXT").showEditor();
653
+ const target = newInput.connection!.targetBlock()!
654
+ target.getField('TEXT')!.showEditor()
717
655
  }
718
656
  }
719
657
  }
@@ -722,10 +660,10 @@ function focusLastEditor_(this: ProcedureDeclarationBlock) {
722
660
  * Externally-visible function to add a label to the procedure declaration.
723
661
  */
724
662
  function addLabelExternal(this: ProcedureDeclarationBlock) {
725
- Blockly.WidgetDiv.hide();
726
- this.procCode_ = this.procCode_ + " label text";
727
- this.updateDisplay_();
728
- this.focusLastEditor_();
663
+ Blockly.WidgetDiv.hide()
664
+ this.procCode_ = this.procCode_ + ' label text'
665
+ this.updateDisplay_()
666
+ this.focusLastEditor_()
729
667
  }
730
668
 
731
669
  /**
@@ -733,13 +671,13 @@ function addLabelExternal(this: ProcedureDeclarationBlock) {
733
671
  * declaration.
734
672
  */
735
673
  function addBooleanExternal(this: ProcedureDeclarationBlock) {
736
- Blockly.WidgetDiv.hide();
737
- this.procCode_ = this.procCode_ + " %b";
738
- this.displayNames_.push("boolean");
739
- this.argumentIds_.push(Blockly.utils.idGenerator.genUid());
740
- this.argumentDefaults_.push("false");
741
- this.updateDisplay_();
742
- this.focusLastEditor_();
674
+ Blockly.WidgetDiv.hide()
675
+ this.procCode_ = this.procCode_ + ' %b'
676
+ this.displayNames_.push('boolean')
677
+ this.argumentIds_.push(Blockly.utils.idGenerator.genUid())
678
+ this.argumentDefaults_.push('false')
679
+ this.updateDisplay_()
680
+ this.focusLastEditor_()
743
681
  }
744
682
 
745
683
  /**
@@ -747,82 +685,75 @@ function addBooleanExternal(this: ProcedureDeclarationBlock) {
747
685
  * declaration.
748
686
  */
749
687
  function addStringNumberExternal(this: ProcedureDeclarationBlock) {
750
- Blockly.WidgetDiv.hide();
751
- this.procCode_ = this.procCode_ + " %s";
752
- this.displayNames_.push("number or text");
753
- this.argumentIds_.push(Blockly.utils.idGenerator.genUid());
754
- this.argumentDefaults_.push("");
755
- this.updateDisplay_();
756
- this.focusLastEditor_();
688
+ Blockly.WidgetDiv.hide()
689
+ this.procCode_ = this.procCode_ + ' %s'
690
+ this.displayNames_.push('number or text')
691
+ this.argumentIds_.push(Blockly.utils.idGenerator.genUid())
692
+ this.argumentDefaults_.push('')
693
+ this.updateDisplay_()
694
+ this.focusLastEditor_()
757
695
  }
758
696
 
759
697
  /**
760
698
  * Externally-visible function to get the warp on procedure declaration.
761
- *
762
699
  * @returns The value of the warp_ property.
763
700
  */
764
701
  function getWarp(this: ProcedureDeclarationBlock): boolean {
765
- return this.warp_;
702
+ return this.warp_
766
703
  }
767
704
 
768
705
  /**
769
706
  * Externally-visible function to set the warp on procedure declaration.
770
- *
771
707
  * @param warp The value of the warp_ property.
772
708
  */
773
709
  function setWarp(this: ProcedureDeclarationBlock, warp: boolean) {
774
- this.warp_ = warp;
710
+ this.warp_ = warp
775
711
  }
776
712
 
777
713
  /**
778
714
  * Callback to remove a field, only for the declaration block.
779
- *
780
715
  * @param field The field being removed.
781
716
  */
782
- function removeFieldCallback(
783
- this: ProcedureDeclarationBlock,
784
- field: Blockly.Field
785
- ) {
717
+ function removeFieldCallback(this: ProcedureDeclarationBlock, field: Blockly.Field) {
786
718
  // Do not delete if there is only one input
787
719
  if (this.inputList.length === 1) {
788
- return;
720
+ return
789
721
  }
790
- var inputNameToRemove = null;
791
- for (var n = 0; n < this.inputList.length; n++) {
792
- var input = this.inputList[n];
722
+ let inputNameToRemove = null
723
+ for (let n = 0; n < this.inputList.length; n++) {
724
+ const input = this.inputList[n]
793
725
  if (input.connection) {
794
- var target = input.connection.targetBlock();
726
+ const target = input.connection.targetBlock()!
795
727
  if (field.name && target.getField(field.name) === field) {
796
- inputNameToRemove = input.name;
728
+ inputNameToRemove = input.name
797
729
  }
798
730
  } else {
799
- for (var j = 0; j < input.fieldRow.length; j++) {
731
+ for (let j = 0; j < input.fieldRow.length; j++) {
800
732
  if (input.fieldRow[j] === field) {
801
- inputNameToRemove = input.name;
733
+ inputNameToRemove = input.name
802
734
  }
803
735
  }
804
736
  }
805
737
  }
806
738
  if (inputNameToRemove) {
807
- Blockly.WidgetDiv.hide();
808
- this.removeInput(inputNameToRemove);
809
- this.onChangeFn();
810
- this.updateDisplay_();
739
+ Blockly.WidgetDiv.hide()
740
+ this.removeInput(inputNameToRemove)
741
+ this.onChangeFn()
742
+ this.updateDisplay_()
811
743
  }
812
744
  }
813
745
 
814
746
  /**
815
747
  * Callback to pass removeField up to the declaration block from arguments.
816
- *
817
748
  * @param field The field being removed.
818
749
  */
819
750
  function removeArgumentCallback_(
820
751
  this: ProcedureDeclarationBlock | ProcedureArgumentEditorBlock,
821
- field: Blockly.Field
752
+ field: Blockly.Field,
822
753
  ) {
823
- const parent = this.getParent();
754
+ const parent = this.getParent()
824
755
  if (parent && parent.removeFieldCallback) {
825
- parent.removeFieldCallback(field);
756
+ parent.removeFieldCallback(field)
826
757
  }
827
758
  }
828
759
 
@@ -835,46 +766,42 @@ function removeArgumentCallback_(
835
766
  * Until there is a more explicit way of identifying argument reporter blocks using ids,
836
767
  * be conservative and only update argument reporters that are used in the
837
768
  * stack below the prototype, ie the definition.
838
- *
839
769
  * @param prevArgIds The previous ordering of argument ids.
840
770
  * @param prevDisplayNames The previous argument names.
841
771
  */
842
772
  function updateArgumentReporterNames_(
843
773
  this: ProcedurePrototypeBlock,
844
774
  prevArgIds: string[],
845
- prevDisplayNames: string[]
775
+ prevDisplayNames: string[],
846
776
  ) {
847
- const nameChanges: { newName: string; blocks: Blockly.BlockSvg[] }[] = [];
848
- const argReporters: Blockly.BlockSvg[] = [];
849
- const definitionBlock = this.getParent();
850
- if (!definitionBlock) return;
777
+ const nameChanges: { newName: string; blocks: Blockly.BlockSvg[] }[] = []
778
+ const argReporters: Blockly.BlockSvg[] = []
779
+ const definitionBlock = this.getParent()
780
+ if (!definitionBlock) return
851
781
 
852
782
  // Create a list of argument reporters that are descendants of the definition stack (see above comment)
853
783
  definitionBlock.getDescendants(false).forEach((block: Blockly.BlockSvg) => {
854
784
  if (
855
- (block.type === "argument_reporter_string_number" ||
856
- block.type === "argument_reporter_boolean") &&
785
+ (block.type === 'argument_reporter_string_number' || block.type === 'argument_reporter_boolean') &&
857
786
  !block.isShadow()
858
787
  ) {
859
788
  // Exclude arg reporters in the prototype block, which are shadows.
860
- argReporters.push(block);
789
+ argReporters.push(block)
861
790
  }
862
- });
791
+ })
863
792
 
864
793
  // Create a list of "name changes", including the new name and blocks matching the old name
865
794
  // Only search over the current set of argument ids, ignore args that have been removed
866
795
  for (let i = 0, id; (id = this.argumentIds_[i]); i++) {
867
796
  // Find the previous index of this argument id. Could be -1 if it is newly added.
868
- const prevIndex = prevArgIds.indexOf(id);
869
- if (prevIndex === -1) continue; // Newly added argument, no corresponding previous argument to update.
870
- const prevName = prevDisplayNames[prevIndex];
797
+ const prevIndex = prevArgIds.indexOf(id)
798
+ if (prevIndex === -1) continue // Newly added argument, no corresponding previous argument to update.
799
+ const prevName = prevDisplayNames[prevIndex]
871
800
  if (prevName !== this.displayNames_[i]) {
872
801
  nameChanges.push({
873
802
  newName: this.displayNames_[i],
874
- blocks: argReporters.filter((block) => {
875
- return block.getFieldValue("VALUE") === prevName;
876
- }),
877
- });
803
+ blocks: argReporters.filter(block => block.getFieldValue('VALUE') === prevName),
804
+ })
878
805
  }
879
806
  }
880
807
 
@@ -882,12 +809,12 @@ function updateArgumentReporterNames_(
882
809
  // Do this after creating the lists to avoid cycles of renaming.
883
810
  for (const nameChange of nameChanges) {
884
811
  for (const block of nameChange.blocks) {
885
- block.setFieldValue(nameChange.newName, "VALUE");
812
+ block.setFieldValue(nameChange.newName, 'VALUE')
886
813
  }
887
814
  }
888
815
  }
889
816
 
890
- Blockly.Blocks["procedures_definition"] = {
817
+ Blockly.Blocks.procedures_definition = {
891
818
  /**
892
819
  * Block for defining a procedure with no return value.
893
820
  */
@@ -896,263 +823,246 @@ Blockly.Blocks["procedures_definition"] = {
896
823
  message0: Blockly.Msg.PROCEDURES_DEFINITION,
897
824
  args0: [
898
825
  {
899
- type: "input_statement",
900
- name: "custom_block",
826
+ type: 'input_statement',
827
+ name: 'custom_block',
901
828
  },
902
829
  ],
903
- extensions: [
904
- "colours_more",
905
- "shape_bowler_hat",
906
- "procedure_def_contextmenu",
907
- ],
908
- });
830
+ extensions: ['colours_more', 'shape_bowler_hat', 'procedure_def_contextmenu'],
831
+ })
909
832
  },
910
- };
833
+ }
911
834
 
912
- Blockly.Blocks["procedures_call"] = {
835
+ Blockly.Blocks.procedures_call = {
913
836
  /**
914
837
  * Block for calling a procedure with no return value.
915
838
  */
916
839
  init: function (this: ProcedureCallBlock) {
917
840
  this.jsonInit({
918
- extensions: [
919
- "colours_more",
920
- "shape_statement",
921
- "procedure_call_contextmenu",
922
- ],
923
- });
924
- this.procCode_ = "";
925
- this.argumentIds_ = [];
926
- this.warp_ = false;
841
+ extensions: ['colours_more', 'shape_statement', 'procedure_call_contextmenu'],
842
+ })
843
+ this.procCode_ = ''
844
+ this.argumentIds_ = []
845
+ this.warp_ = false
927
846
 
928
847
  // Shared.
929
- this.getProcCode = getProcCode.bind(this);
930
- this.removeAllInputs_ = removeAllInputs_.bind(this);
931
- this.disconnectOldBlocks_ = disconnectOldBlocks_.bind(this);
932
- this.deleteShadows_ = deleteShadows_.bind(this);
933
- this.createAllInputs_ = createAllInputs_.bind(this);
934
- this.updateDisplay_ = updateDisplay_.bind(this);
848
+ this.getProcCode = getProcCode.bind(this)
849
+ this.removeAllInputs_ = removeAllInputs_.bind(this)
850
+ this.disconnectOldBlocks_ = disconnectOldBlocks_.bind(this)
851
+ this.deleteShadows_ = deleteShadows_.bind(this)
852
+ this.createAllInputs_ = createAllInputs_.bind(this)
853
+ this.updateDisplay_ = updateDisplay_.bind(this)
935
854
 
936
855
  // Exist on all three blocks, but have different implementations.
937
- this.mutationToDom = callerMutationToDom.bind(this);
938
- this.domToMutation = callerDomToMutation.bind(this);
939
- this.populateArgument_ = populateArgumentOnCaller_.bind(this);
940
- this.addProcedureLabel_ = addLabelField_.bind(this);
856
+ this.mutationToDom = callerMutationToDom.bind(this)
857
+ this.domToMutation = callerDomToMutation.bind(this)
858
+ this.populateArgument_ = populateArgumentOnCaller_.bind(this)
859
+ this.addProcedureLabel_ = addLabelField_.bind(this)
941
860
 
942
861
  // Only exists on the external caller.
943
- this.attachShadow_ = attachShadow_.bind(this);
944
- this.buildShadowDom_ = buildShadowDom_.bind(this);
862
+ this.attachShadow_ = attachShadow_.bind(this)
863
+ this.buildShadowDom_ = buildShadowDom_.bind(this)
945
864
  },
946
- };
865
+ }
947
866
 
948
- Blockly.Blocks["procedures_prototype"] = {
867
+ Blockly.Blocks.procedures_prototype = {
949
868
  /**
950
869
  * Block for calling a procedure with no return value, for rendering inside
951
870
  * define block.
952
871
  */
953
872
  init: function (this: ProcedurePrototypeBlock) {
954
873
  this.jsonInit({
955
- extensions: ["colours_more", "shape_statement"],
956
- });
874
+ extensions: ['colours_more', 'shape_statement'],
875
+ })
957
876
 
958
877
  /* Data known about the procedure. */
959
- this.procCode_ = "";
960
- this.displayNames_ = [];
961
- this.argumentIds_ = [];
962
- this.argumentDefaults_ = [];
963
- this.warp_ = false;
878
+ this.procCode_ = ''
879
+ this.displayNames_ = []
880
+ this.argumentIds_ = []
881
+ this.argumentDefaults_ = []
882
+ this.warp_ = false
964
883
 
965
884
  // Shared.
966
- this.getProcCode = getProcCode.bind(this);
967
- this.removeAllInputs_ = removeAllInputs_.bind(this);
968
- this.disconnectOldBlocks_ = disconnectOldBlocks_.bind(this);
969
- this.deleteShadows_ = deleteShadows_.bind(this);
970
- this.createAllInputs_ = createAllInputs_.bind(this);
971
- this.updateDisplay_ = updateDisplay_.bind(this);
885
+ this.getProcCode = getProcCode.bind(this)
886
+ this.removeAllInputs_ = removeAllInputs_.bind(this)
887
+ this.disconnectOldBlocks_ = disconnectOldBlocks_.bind(this)
888
+ this.deleteShadows_ = deleteShadows_.bind(this)
889
+ this.createAllInputs_ = createAllInputs_.bind(this)
890
+ this.updateDisplay_ = updateDisplay_.bind(this)
972
891
  // Exist on all three blocks, but have different implementations.
973
- this.mutationToDom = definitionMutationToDom.bind(this);
974
- this.domToMutation = definitionDomToMutation.bind(this);
975
- this.populateArgument_ = populateArgumentOnPrototype_.bind(this);
976
- this.addProcedureLabel_ = addLabelField_.bind(this);
892
+ this.mutationToDom = definitionMutationToDom.bind(this)
893
+ this.domToMutation = definitionDomToMutation.bind(this)
894
+ this.populateArgument_ = populateArgumentOnPrototype_.bind(this)
895
+ this.addProcedureLabel_ = addLabelField_.bind(this)
977
896
 
978
897
  // Only exists on procedures_prototype.
979
- this.createArgumentReporter_ = createArgumentReporter_.bind(this);
980
- this.updateArgumentReporterNames_ = updateArgumentReporterNames_.bind(this);
898
+ this.createArgumentReporter_ = createArgumentReporter_.bind(this)
899
+ this.updateArgumentReporterNames_ = updateArgumentReporterNames_.bind(this)
981
900
  },
982
- };
901
+ }
983
902
 
984
- Blockly.Blocks["procedures_declaration"] = {
903
+ Blockly.Blocks.procedures_declaration = {
985
904
  /**
986
905
  * The root block in the procedure declaration editor.
987
906
  */
988
907
  init: function (this: ProcedureDeclarationBlock) {
989
908
  this.jsonInit({
990
- extensions: ["colours_more", "shape_statement"],
991
- });
909
+ extensions: ['colours_more', 'shape_statement'],
910
+ })
992
911
  /* Data known about the procedure. */
993
- this.procCode_ = "";
994
- this.displayNames_ = [];
995
- this.argumentIds_ = [];
996
- this.argumentDefaults_ = [];
997
- this.warp_ = false;
912
+ this.procCode_ = ''
913
+ this.displayNames_ = []
914
+ this.argumentIds_ = []
915
+ this.argumentDefaults_ = []
916
+ this.warp_ = false
998
917
 
999
918
  // Shared.
1000
- this.getProcCode = getProcCode.bind(this);
1001
- this.removeAllInputs_ = removeAllInputs_.bind(this);
1002
- this.disconnectOldBlocks_ = disconnectOldBlocks_.bind(this);
1003
- this.deleteShadows_ = deleteShadows_.bind(this);
1004
- this.createAllInputs_ = createAllInputs_.bind(this);
1005
- this.updateDisplay_ = updateDisplay_.bind(this);
919
+ this.getProcCode = getProcCode.bind(this)
920
+ this.removeAllInputs_ = removeAllInputs_.bind(this)
921
+ this.disconnectOldBlocks_ = disconnectOldBlocks_.bind(this)
922
+ this.deleteShadows_ = deleteShadows_.bind(this)
923
+ this.createAllInputs_ = createAllInputs_.bind(this)
924
+ this.updateDisplay_ = updateDisplay_.bind(this)
1006
925
 
1007
926
  // Exist on all three blocks, but have different implementations.
1008
- this.mutationToDom = definitionMutationToDom.bind(this);
1009
- this.domToMutation = definitionDomToMutation.bind(this);
1010
- this.populateArgument_ = populateArgumentOnDeclaration_.bind(this);
1011
- this.addProcedureLabel_ = addLabelEditor_.bind(this);
927
+ this.mutationToDom = definitionMutationToDom.bind(this)
928
+ this.domToMutation = definitionDomToMutation.bind(this)
929
+ this.populateArgument_ = populateArgumentOnDeclaration_.bind(this)
930
+ this.addProcedureLabel_ = addLabelEditor_.bind(this)
1012
931
 
1013
932
  // Exist on declaration and arguments editors, with different implementations.
1014
- this.removeFieldCallback = removeFieldCallback.bind(this);
933
+ this.removeFieldCallback = removeFieldCallback.bind(this)
1015
934
 
1016
935
  // Only exist on procedures_declaration.
1017
- this.createArgumentEditor_ = createArgumentEditor_.bind(this);
1018
- this.focusLastEditor_ = focusLastEditor_.bind(this);
1019
- this.getWarp = getWarp.bind(this);
1020
- this.setWarp = setWarp.bind(this);
1021
- this.addLabelExternal = addLabelExternal.bind(this);
1022
- this.addBooleanExternal = addBooleanExternal.bind(this);
1023
- this.addStringNumberExternal = addStringNumberExternal.bind(this);
1024
- this.onChangeFn = updateDeclarationProcCode_.bind(this);
936
+ this.createArgumentEditor_ = createArgumentEditor_.bind(this)
937
+ this.focusLastEditor_ = focusLastEditor_.bind(this)
938
+ this.getWarp = getWarp.bind(this)
939
+ this.setWarp = setWarp.bind(this)
940
+ this.addLabelExternal = addLabelExternal.bind(this)
941
+ this.addBooleanExternal = addBooleanExternal.bind(this)
942
+ this.addStringNumberExternal = addStringNumberExternal.bind(this)
943
+ this.onChangeFn = updateDeclarationProcCode_.bind(this)
1025
944
  },
1026
- };
945
+ }
1027
946
 
1028
- Blockly.Blocks["argument_reporter_boolean"] = {
947
+ Blockly.Blocks.argument_reporter_boolean = {
1029
948
  init: function (this: Blockly.BlockSvg) {
1030
949
  this.jsonInit({
1031
- message0: " %1",
950
+ message0: ' %1',
1032
951
  args0: [
1033
952
  {
1034
- type: "field_label_serializable",
1035
- name: "VALUE",
1036
- text: "",
953
+ type: 'field_label_serializable',
954
+ name: 'VALUE',
955
+ text: '',
1037
956
  },
1038
957
  ],
1039
- extensions: ["colours_more", "output_boolean"],
1040
- });
1041
- this.setDragStrategy(new DuplicateOnDragDraggable(this));
958
+ extensions: ['colours_more', 'output_boolean'],
959
+ })
960
+ this.setDragStrategy(new DuplicateOnDragDraggable(this))
1042
961
  },
1043
- };
962
+ }
1044
963
 
1045
- Blockly.Blocks["argument_reporter_string_number"] = {
964
+ Blockly.Blocks.argument_reporter_string_number = {
1046
965
  init: function (this: Blockly.BlockSvg) {
1047
966
  this.jsonInit({
1048
- message0: " %1",
967
+ message0: ' %1',
1049
968
  args0: [
1050
969
  {
1051
- type: "field_label_serializable",
1052
- name: "VALUE",
1053
- text: "",
970
+ type: 'field_label_serializable',
971
+ name: 'VALUE',
972
+ text: '',
1054
973
  },
1055
974
  ],
1056
- extensions: ["colours_more", "output_number", "output_string"],
1057
- });
1058
- this.setDragStrategy(new DuplicateOnDragDraggable(this));
975
+ extensions: ['colours_more', 'output_number', 'output_string'],
976
+ })
977
+ this.setDragStrategy(new DuplicateOnDragDraggable(this))
1059
978
  },
1060
- };
979
+ }
1061
980
 
1062
- Blockly.Blocks["argument_editor_boolean"] = {
981
+ Blockly.Blocks.argument_editor_boolean = {
1063
982
  init: function (this: ProcedureArgumentEditorBlock) {
1064
983
  this.jsonInit({
1065
- message0: " %1",
984
+ message0: ' %1',
1066
985
  args0: [
1067
986
  {
1068
- type: "field_input_removable",
1069
- name: "TEXT",
1070
- text: "foo",
987
+ type: 'field_input_removable',
988
+ name: 'TEXT',
989
+ text: 'foo',
1071
990
  },
1072
991
  ],
1073
- extensions: ["colours_textfield", "output_boolean"],
1074
- });
992
+ extensions: ['colours_textfield', 'output_boolean'],
993
+ })
1075
994
 
1076
995
  // Exist on declaration and arguments editors, with different implementations.
1077
- this.removeFieldCallback = removeArgumentCallback_.bind(this);
996
+ this.removeFieldCallback = removeArgumentCallback_.bind(this)
1078
997
  },
1079
- };
998
+ }
1080
999
 
1081
- Blockly.Blocks["argument_editor_string_number"] = {
1000
+ Blockly.Blocks.argument_editor_string_number = {
1082
1001
  init: function (this: ProcedureArgumentEditorBlock) {
1083
1002
  this.jsonInit({
1084
- message0: " %1",
1003
+ message0: ' %1',
1085
1004
  args0: [
1086
1005
  {
1087
- type: "field_input_removable",
1088
- name: "TEXT",
1089
- text: "foo",
1006
+ type: 'field_input_removable',
1007
+ name: 'TEXT',
1008
+ text: 'foo',
1090
1009
  },
1091
1010
  ],
1092
- extensions: ["colours_textfield", "output_number", "output_string"],
1093
- });
1011
+ extensions: ['colours_textfield', 'output_number', 'output_string'],
1012
+ })
1094
1013
 
1095
1014
  // Exist on declaration and arguments editors, with different implementations.
1096
- this.removeFieldCallback = removeArgumentCallback_.bind(this);
1015
+ this.removeFieldCallback = removeArgumentCallback_.bind(this)
1097
1016
  },
1098
- };
1017
+ }
1099
1018
 
1100
1019
  interface ProcedureBlock extends Blockly.BlockSvg {
1101
- procCode_: string;
1102
- argumentIds_: string[];
1103
- warp_: boolean;
1104
- getProcCode: () => string;
1105
- removeAllInputs_: () => void;
1106
- disconnectOldBlocks_: () => ConnectionMap;
1107
- deleteShadows_: (connectionMap: ConnectionMap) => void;
1108
- createAllInputs_: (connectionMap: ConnectionMap) => void;
1109
- updateDisplay_: () => void;
1020
+ procCode_: string
1021
+ argumentIds_: string[]
1022
+ warp_: boolean
1023
+ getProcCode: () => string
1024
+ removeAllInputs_: () => void
1025
+ disconnectOldBlocks_: () => ConnectionMap
1026
+ deleteShadows_: (connectionMap: ConnectionMap) => void
1027
+ createAllInputs_: (connectionMap: ConnectionMap) => void
1028
+ updateDisplay_: () => void
1110
1029
  populateArgument_: (
1111
1030
  type: ArgumentType,
1112
1031
  index: number,
1113
1032
  connectionMap: ConnectionMap,
1114
1033
  id: string,
1115
- input: Blockly.Input
1116
- ) => void;
1117
- addProcedureLabel_: (text: string) => void;
1034
+ input: Blockly.Input,
1035
+ ) => void
1036
+ addProcedureLabel_: (text: string) => void
1118
1037
  }
1119
1038
 
1120
1039
  export interface ProcedureDeclarationBlock extends ProcedureBlock {
1121
- displayNames_: string[];
1122
- argumentDefaults_: string[];
1123
- removeFieldCallback: (field: Blockly.Field) => void;
1124
- createArgumentEditor_: (
1125
- argumentType: ArgumentType,
1126
- displayName: string
1127
- ) => Blockly.BlockSvg;
1128
- focusLastEditor_: () => void;
1129
- getWarp: () => boolean;
1130
- setWarp: (warp: boolean) => void;
1131
- addLabelExternal: () => void;
1132
- addBooleanExternal: () => void;
1133
- addStringNumberExternal: () => void;
1134
- onChangeFn: () => void;
1040
+ displayNames_: string[]
1041
+ argumentDefaults_: string[]
1042
+ removeFieldCallback: (field: Blockly.Field) => void
1043
+ createArgumentEditor_: (argumentType: ArgumentType, displayName: string) => Blockly.BlockSvg
1044
+ focusLastEditor_: () => void
1045
+ getWarp: () => boolean
1046
+ setWarp: (warp: boolean) => void
1047
+ addLabelExternal: () => void
1048
+ addBooleanExternal: () => void
1049
+ addStringNumberExternal: () => void
1050
+ onChangeFn: () => void
1135
1051
  }
1136
1052
 
1137
1053
  interface ProcedureCallBlock extends ProcedureBlock {
1138
- generateShadows_: boolean;
1139
- attachShadow_: (input: Blockly.Input, argumentType: ArgumentType) => void;
1140
- buildShadowDom_: (type: ArgumentType) => Element;
1054
+ generateShadows_: boolean
1055
+ attachShadow_: (input: Blockly.Input, argumentType: ArgumentType) => void
1056
+ buildShadowDom_: (type: ArgumentType) => Element
1141
1057
  }
1142
1058
 
1143
1059
  interface ProcedurePrototypeBlock extends ProcedureBlock {
1144
- displayNames_: string[];
1145
- argumentDefaults_: string[];
1146
- createArgumentReporter_: (
1147
- argumentType: ArgumentType,
1148
- displayName: string
1149
- ) => Blockly.BlockSvg;
1150
- updateArgumentReporterNames_: (
1151
- prevArgIds: string[],
1152
- prevDisplayNames: string[]
1153
- ) => void;
1060
+ displayNames_: string[]
1061
+ argumentDefaults_: string[]
1062
+ createArgumentReporter_: (argumentType: ArgumentType, displayName: string) => Blockly.BlockSvg
1063
+ updateArgumentReporterNames_: (prevArgIds: string[], prevDisplayNames: string[]) => void
1154
1064
  }
1155
1065
 
1156
1066
  interface ProcedureArgumentEditorBlock extends Blockly.BlockSvg {
1157
- removeFieldCallback: (field: Blockly.Field) => void;
1067
+ removeFieldCallback: (field: Blockly.Field) => void
1158
1068
  }