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,18 +16,17 @@
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 Colour input field.
20
+ * @file Colour input field.
23
21
  * @author fraser@google.com (Neil Fraser)
24
22
  */
25
- import * as Blockly from "blockly/core";
26
- import { FieldColour, FieldColourFromJsonConfig } from "@blockly/field-colour";
23
+ import * as Blockly from 'blockly/core'
24
+ import { FieldColour, FieldColourFromJsonConfig } from '@blockly/field-colour'
27
25
 
28
26
  enum ColourChannel {
29
- HUE = "hue",
30
- SATURATION = "saturation",
31
- BRIGHTNESS = "brightness",
27
+ HUE = 'hue',
28
+ SATURATION = 'saturation',
29
+ BRIGHTNESS = 'brightness',
32
30
  }
33
31
 
34
32
  /**
@@ -41,353 +39,325 @@ export class FieldColourSlider extends FieldColour {
41
39
  * The button calls this function with a callback to update the field value.
42
40
  * BEWARE: This is not a stable API. It may change.
43
41
  */
44
- static activateEyedropper_: (
45
- callback: (colour: string) => void
46
- ) => void | null = null;
42
+ static activateEyedropper_?: (callback: (colour: string) => void) => void
47
43
 
48
44
  /**
49
45
  * Path to the eyedropper svg icon.
50
46
  */
51
- EYEDROPPER_PATH = "eyedropper.svg";
52
- SERIALIZABLE = true;
53
- EDITABLE = true;
47
+ EYEDROPPER_PATH = 'eyedropper.svg'
48
+ SERIALIZABLE = true
49
+ EDITABLE = true
54
50
 
55
- private hueChangeEventKey_?: Blockly.browserEvents.Data;
56
- private saturationChangeEventKey_?: Blockly.browserEvents.Data;
57
- private brightnessChangeEventKey_?: Blockly.browserEvents.Data;
58
- private hueSlider_?: HTMLInputElement;
59
- private saturationSlider_?: HTMLInputElement;
60
- private brightnessSlider_?: HTMLInputElement;
61
- private hueReadout_?: Element;
62
- private saturationReadout_?: Element;
63
- private brightnessReadout_?: Element;
64
- private hue_?: number;
65
- private saturation_?: number;
66
- private brightness_?: number;
67
- private eyedropperEventData_?: Blockly.browserEvents.Data;
51
+ private hueChangeEventKey_?: Blockly.browserEvents.Data
52
+ private saturationChangeEventKey_?: Blockly.browserEvents.Data
53
+ private brightnessChangeEventKey_?: Blockly.browserEvents.Data
54
+ private hueSlider_?: HTMLInputElement
55
+ private saturationSlider_?: HTMLInputElement
56
+ private brightnessSlider_?: HTMLInputElement
57
+ private hueReadout_?: Element
58
+ private saturationReadout_?: Element
59
+ private brightnessReadout_?: Element
60
+ private hue_ = 0
61
+ private saturation_ = 0
62
+ private brightness_ = 0
63
+ private eyedropperEventData_?: Blockly.browserEvents.Data
68
64
 
69
65
  /**
70
66
  * Construct a FieldColourSlider from a JSON arg object.
71
- *
72
67
  * @param options A JSON object with options (colour).
73
68
  * @returns The new field instance.
74
69
  */
75
70
  static fromJson(options: FieldColourFromJsonConfig): FieldColourSlider {
76
- return new FieldColourSlider(options["colour"]);
71
+ return new FieldColourSlider(options.colour)
77
72
  }
78
73
 
79
74
  doValueUpdate_(newValue: string) {
80
- super.doValueUpdate_(newValue);
81
- this.updateSliderHandles_();
82
- this.updateDom_();
75
+ super.doValueUpdate_(newValue)
76
+ this.updateSliderHandles_()
77
+ this.updateDom_()
83
78
  }
84
79
 
85
80
  /**
86
81
  * Create the hue, saturation or value CSS gradient for the slide backgrounds.
87
- *
88
82
  * @param channel – Either "hue", "saturation" or "value".
89
- * @return Array colour hex colour stops for the given channel
83
+ * @returns Array colour hex colour stops for the given channel
90
84
  */
91
85
  private createColourStops_(channel: ColourChannel): string[] {
92
- const stops = [];
86
+ const stops = []
93
87
  for (let n = 0; n <= 360; n += 20) {
94
88
  switch (channel) {
95
89
  case ColourChannel.HUE:
96
- stops.push(
97
- Blockly.utils.colour.hsvToHex(n, this.saturation_, this.brightness_)
98
- );
99
- break;
90
+ stops.push(Blockly.utils.colour.hsvToHex(n, this.saturation_, this.brightness_))
91
+ break
100
92
  case ColourChannel.SATURATION:
101
- stops.push(
102
- Blockly.utils.colour.hsvToHex(this.hue_, n / 360, this.brightness_)
103
- );
104
- break;
93
+ stops.push(Blockly.utils.colour.hsvToHex(this.hue_, n / 360, this.brightness_))
94
+ break
105
95
  case ColourChannel.BRIGHTNESS:
106
- stops.push(
107
- Blockly.utils.colour.hsvToHex(
108
- this.hue_,
109
- this.saturation_,
110
- (255 * n) / 360
111
- )
112
- );
113
- break;
96
+ stops.push(Blockly.utils.colour.hsvToHex(this.hue_, this.saturation_, (255 * n) / 360))
97
+ break
114
98
  default:
115
- throw new Error("Unknown channel for colour sliders: " + channel);
99
+ throw new Error('Unknown channel for colour sliders: ' + channel)
116
100
  }
117
101
  }
118
- return stops;
102
+ return stops
119
103
  }
120
104
 
121
105
  /**
122
106
  * Set the gradient CSS properties for the given node and channel
123
- *
124
107
  * @param node The DOM node the gradient will be set on.
125
108
  * @param channel Either "hue", "saturation" or "value".
126
109
  */
127
110
  private setGradient_(node: HTMLElement, channel: ColourChannel) {
128
- const gradient = this.createColourStops_(channel).join(",");
129
- node.style["background"] = `linear-gradient(to right, ${gradient})`;
111
+ const gradient = this.createColourStops_(channel).join(',')
112
+ node.style.background = `linear-gradient(to right, ${gradient})`
130
113
  }
131
114
 
132
115
  /**
133
116
  * Update the readouts and slider backgrounds after value has changed.
134
117
  */
135
118
  private updateDom_() {
136
- if (this.hueSlider_) {
137
- // Update the slider backgrounds
138
- this.setGradient_(this.hueSlider_, ColourChannel.HUE);
139
- this.setGradient_(this.saturationSlider_, ColourChannel.SATURATION);
140
- this.setGradient_(this.brightnessSlider_, ColourChannel.BRIGHTNESS);
141
-
142
- // Update the readouts
143
- this.hueReadout_.textContent = Math.floor(
144
- (100 * this.hue_) / 360
145
- ).toFixed(0);
146
- this.saturationReadout_.textContent = Math.floor(
147
- 100 * this.saturation_
148
- ).toFixed(0);
149
- this.brightnessReadout_.textContent = Math.floor(
150
- (100 * this.brightness_) / 255
151
- ).toFixed(0);
119
+ const hueSlider = this.hueSlider_
120
+ const saturationSlider = this.saturationSlider_
121
+ const brightnessSlider = this.brightnessSlider_
122
+ const hueReadout = this.hueReadout_
123
+ const saturationReadout = this.saturationReadout_
124
+ const brightnessReadout = this.brightnessReadout_
125
+ if (
126
+ !hueSlider ||
127
+ !saturationSlider ||
128
+ !brightnessSlider ||
129
+ !hueReadout ||
130
+ !saturationReadout ||
131
+ !brightnessReadout
132
+ ) {
133
+ console.warn('FieldColourSlider.updateDom_: slider/readout DOM is not fully initialized')
134
+ return
152
135
  }
136
+
137
+ this.setGradient_(hueSlider, ColourChannel.HUE)
138
+ this.setGradient_(saturationSlider, ColourChannel.SATURATION)
139
+ this.setGradient_(brightnessSlider, ColourChannel.BRIGHTNESS)
140
+
141
+ hueReadout.textContent = Math.floor((100 * this.hue_) / 360).toFixed(0)
142
+ saturationReadout.textContent = Math.floor(100 * this.saturation_).toFixed(0)
143
+ brightnessReadout.textContent = Math.floor((100 * this.brightness_) / 255).toFixed(0)
153
144
  }
154
145
 
155
146
  /**
156
147
  * Update the slider handle positions from the current field value.
157
148
  */
158
149
  private updateSliderHandles_() {
159
- if (this.hueSlider_) {
160
- this.hueSlider_.value = `${this.hue_}`;
161
- this.saturationSlider_.value = `${this.saturation_}`;
162
- this.brightnessSlider_.value = `${this.brightness_}`;
150
+ const hueSlider = this.hueSlider_
151
+ const saturationSlider = this.saturationSlider_
152
+ const brightnessSlider = this.brightnessSlider_
153
+ if (!hueSlider || !saturationSlider || !brightnessSlider) {
154
+ console.warn('FieldColourSlider.updateSliderHandles_: slider DOM is not fully initialized')
155
+ return
163
156
  }
157
+
158
+ hueSlider.value = `${this.hue_}`
159
+ saturationSlider.value = `${this.saturation_}`
160
+ brightnessSlider.value = `${this.brightness_}`
164
161
  }
165
162
 
166
163
  /**
167
164
  * Create label and readout DOM elements, returning the readout.
168
- *
169
165
  * @param labelText Text for the label
170
- * @return The container node and the readout node.
166
+ * @returns The container node and the readout node.
171
167
  */
172
168
  private createLabelDom_(labelText: string): Element[] {
173
- const labelContainer = document.createElement("div");
174
- labelContainer.setAttribute("class", "scratchColourPickerLabel");
175
- const readout = document.createElement("span");
176
- readout.setAttribute("class", "scratchColourPickerReadout");
177
- const label = document.createElement("span");
178
- label.setAttribute("class", "scratchColourPickerLabelText");
179
- label.textContent = labelText;
180
- labelContainer.appendChild(label);
181
- labelContainer.appendChild(readout);
182
- return [labelContainer, readout];
169
+ const labelContainer = document.createElement('div')
170
+ labelContainer.setAttribute('class', 'scratchColourPickerLabel')
171
+ const readout = document.createElement('span')
172
+ readout.setAttribute('class', 'scratchColourPickerReadout')
173
+ const label = document.createElement('span')
174
+ label.setAttribute('class', 'scratchColourPickerLabelText')
175
+ label.textContent = labelText
176
+ labelContainer.appendChild(label)
177
+ labelContainer.appendChild(readout)
178
+ return [labelContainer, readout]
183
179
  }
184
180
 
185
181
  /**
186
182
  * Factory for creating the different slider callbacks
187
- *
188
183
  * @param channel One of "hue", "saturation" or "brightness"
189
184
  * @returns The callback for slider update
190
185
  */
191
- private sliderCallbackFactory_(
192
- channel: ColourChannel
193
- ): (event: PointerEvent) => void {
186
+ private sliderCallbackFactory_(channel: ColourChannel): (event: PointerEvent) => void {
194
187
  return (event: PointerEvent) => {
195
- const channelValue = (event.target as HTMLInputElement).value;
188
+ const channelValue = (event.target as HTMLInputElement).value
196
189
  switch (channel) {
197
190
  case ColourChannel.HUE:
198
- this.hue_ = Number(channelValue);
199
- break;
191
+ this.hue_ = Number(channelValue)
192
+ break
200
193
  case ColourChannel.SATURATION:
201
- this.saturation_ = Number(channelValue);
202
- break;
194
+ this.saturation_ = Number(channelValue)
195
+ break
203
196
  case ColourChannel.BRIGHTNESS:
204
- this.brightness_ = Number(channelValue);
205
- break;
197
+ this.brightness_ = Number(channelValue)
198
+ break
206
199
  }
207
- const colour = Blockly.utils.colour.hsvToHex(
208
- this.hue_,
209
- this.saturation_,
210
- this.brightness_
211
- );
200
+ const colour = Blockly.utils.colour.hsvToHex(this.hue_, this.saturation_, this.brightness_)
212
201
  if (colour !== null) {
213
- this.setValue(colour, true);
202
+ this.setValue(colour, true)
214
203
  }
215
- };
204
+ }
216
205
  }
217
206
 
218
207
  /**
219
208
  * Activate the eyedropper, passing in a callback for setting the field value.
220
209
  */
221
210
  private activateEyedropperInternal_() {
222
- FieldColourSlider.activateEyedropper_((chosenColour: string) => {
211
+ FieldColourSlider.activateEyedropper_?.((chosenColour: string) => {
223
212
  // Update the internal hue/saturation/brightness values so sliders update.
224
- const components = Blockly.utils.colour.hexToRgb(chosenColour);
225
- const { hue, saturation, value } = this.rgbToHsv(
226
- components[0],
227
- components[1],
228
- components[2]
229
- );
230
- this.hue_ = hue;
231
- this.saturation_ = saturation;
232
- this.brightness_ = value;
233
- this.setValue(chosenColour);
234
- });
213
+ const components = Blockly.utils.colour.hexToRgb(chosenColour)
214
+ const { hue, saturation, value } = this.rgbToHsv(components[0], components[1], components[2])
215
+ this.hue_ = hue
216
+ this.saturation_ = saturation
217
+ this.brightness_ = value
218
+ this.setValue(chosenColour)
219
+ })
235
220
  }
236
221
 
237
222
  /**
238
223
  * Create hue, saturation and brightness sliders under the colour field.
239
224
  */
240
225
  showEditor_() {
241
- Blockly.DropDownDiv.hideWithoutAnimation();
242
- Blockly.DropDownDiv.clearContent();
243
- const div = Blockly.DropDownDiv.getContentDiv();
244
- div.className = "scratchColourPicker";
226
+ Blockly.DropDownDiv.hideWithoutAnimation()
227
+ Blockly.DropDownDiv.clearContent()
228
+ const div = Blockly.DropDownDiv.getContentDiv()
229
+ div.className = 'scratchColourPicker'
245
230
 
246
231
  // Init color component values that are used while the editor is open
247
232
  // in order to keep the slider values stable.
248
- const components = Blockly.utils.colour.hexToRgb(this.getValue());
249
- const { hue, saturation, value } = this.rgbToHsv(
250
- components[0],
251
- components[1],
252
- components[2]
253
- );
254
- this.hue_ = hue;
255
- this.saturation_ = saturation;
256
- this.brightness_ = value;
233
+ const currentValue = this.getValue() ?? '#000000'
234
+ const components = Blockly.utils.colour.hexToRgb(currentValue)
235
+ const { hue, saturation, value } = this.rgbToHsv(components[0], components[1], components[2])
236
+ this.hue_ = hue
237
+ this.saturation_ = saturation
238
+ this.brightness_ = value
257
239
 
258
- const hueElements = this.createLabelDom_(Blockly.Msg.COLOUR_HUE_LABEL);
259
- div.appendChild(hueElements[0]);
260
- this.hueReadout_ = hueElements[1];
261
- this.hueSlider_ = document.createElement("input");
262
- this.hueSlider_.type = "range";
263
- this.hueSlider_.min = "0";
264
- this.hueSlider_.max = "360";
265
- this.hueSlider_.className = "scratchColourSlider";
266
- div.appendChild(this.hueSlider_);
240
+ const hueElements = this.createLabelDom_(Blockly.Msg.COLOUR_HUE_LABEL)
241
+ div.appendChild(hueElements[0])
242
+ this.hueReadout_ = hueElements[1]
243
+ this.hueSlider_ = document.createElement('input')
244
+ this.hueSlider_.type = 'range'
245
+ this.hueSlider_.min = '0'
246
+ this.hueSlider_.max = '360'
247
+ this.hueSlider_.className = 'scratchColourSlider'
248
+ div.appendChild(this.hueSlider_)
267
249
 
268
- const saturationElements = this.createLabelDom_(
269
- Blockly.Msg.COLOUR_SATURATION_LABEL
270
- );
271
- div.appendChild(saturationElements[0]);
272
- this.saturationReadout_ = saturationElements[1];
273
- this.saturationSlider_ = document.createElement("input");
274
- this.saturationSlider_.type = "range";
275
- this.saturationSlider_.step = "0.001";
276
- this.saturationSlider_.min = "0";
277
- this.saturationSlider_.max = "1.0";
278
- this.saturationSlider_.className = "scratchColourSlider";
279
- div.appendChild(this.saturationSlider_);
250
+ const saturationElements = this.createLabelDom_(Blockly.Msg.COLOUR_SATURATION_LABEL)
251
+ div.appendChild(saturationElements[0])
252
+ this.saturationReadout_ = saturationElements[1]
253
+ this.saturationSlider_ = document.createElement('input')
254
+ this.saturationSlider_.type = 'range'
255
+ this.saturationSlider_.step = '0.001'
256
+ this.saturationSlider_.min = '0'
257
+ this.saturationSlider_.max = '1.0'
258
+ this.saturationSlider_.className = 'scratchColourSlider'
259
+ div.appendChild(this.saturationSlider_)
280
260
 
281
- const brightnessElements = this.createLabelDom_(
282
- Blockly.Msg.COLOUR_BRIGHTNESS_LABEL
283
- );
284
- div.appendChild(brightnessElements[0]);
285
- this.brightnessReadout_ = brightnessElements[1];
286
- this.brightnessSlider_ = document.createElement("input");
287
- this.brightnessSlider_.type = "range";
288
- this.brightnessSlider_.min = "0";
289
- this.brightnessSlider_.max = "255";
290
- this.brightnessSlider_.className = "scratchColourSlider";
291
- div.appendChild(this.brightnessSlider_);
261
+ const brightnessElements = this.createLabelDom_(Blockly.Msg.COLOUR_BRIGHTNESS_LABEL)
262
+ div.appendChild(brightnessElements[0])
263
+ this.brightnessReadout_ = brightnessElements[1]
264
+ this.brightnessSlider_ = document.createElement('input')
265
+ this.brightnessSlider_.type = 'range'
266
+ this.brightnessSlider_.min = '0'
267
+ this.brightnessSlider_.max = '255'
268
+ this.brightnessSlider_.className = 'scratchColourSlider'
269
+ div.appendChild(this.brightnessSlider_)
292
270
 
293
271
  if (FieldColourSlider.activateEyedropper_) {
294
- const button = document.createElement("button");
295
- button.setAttribute("class", "scratchEyedropper");
296
- const image = document.createElement("img");
297
- image.src =
298
- Blockly.getMainWorkspace().options.pathToMedia + this.EYEDROPPER_PATH;
299
- button.appendChild(image);
300
- div.appendChild(button);
272
+ const button = document.createElement('button')
273
+ button.setAttribute('class', 'scratchEyedropper')
274
+ const image = document.createElement('img')
275
+ image.src = Blockly.getMainWorkspace().options.pathToMedia + this.EYEDROPPER_PATH
276
+ button.appendChild(image)
277
+ div.appendChild(button)
301
278
  this.eyedropperEventData_ = Blockly.browserEvents.conditionalBind(
302
279
  button,
303
- "click",
280
+ 'click',
304
281
  this,
305
- this.activateEyedropperInternal_
306
- );
282
+ this.activateEyedropperInternal_,
283
+ )
307
284
  }
308
285
 
309
- Blockly.DropDownDiv.setColour("#ffffff", "#dddddd");
310
- Blockly.DropDownDiv.showPositionedByBlock(
311
- this,
312
- this.getSourceBlock() as Blockly.BlockSvg
313
- );
286
+ Blockly.DropDownDiv.setColour('#ffffff', '#dddddd')
287
+ Blockly.DropDownDiv.showPositionedByBlock(this, this.getSourceBlock() as Blockly.BlockSvg)
314
288
 
315
289
  // Set value updates the slider positions
316
290
  // Do this before attaching callbacks to avoid extra events from initial set
317
- this.setValue(this.getValue());
291
+ this.setValue(this.getValue() ?? currentValue)
318
292
 
319
293
  this.hueChangeEventKey_ = Blockly.browserEvents.bind(
320
294
  this.hueSlider_,
321
- "input",
295
+ 'input',
322
296
  this,
323
- this.sliderCallbackFactory_(ColourChannel.HUE)
324
- );
297
+ this.sliderCallbackFactory_(ColourChannel.HUE),
298
+ )
325
299
  this.saturationChangeEventKey_ = Blockly.browserEvents.bind(
326
300
  this.saturationSlider_,
327
- "input",
301
+ 'input',
328
302
  this,
329
- this.sliderCallbackFactory_(ColourChannel.SATURATION)
330
- );
303
+ this.sliderCallbackFactory_(ColourChannel.SATURATION),
304
+ )
331
305
  this.brightnessChangeEventKey_ = Blockly.browserEvents.bind(
332
306
  this.brightnessSlider_,
333
- "input",
307
+ 'input',
334
308
  this,
335
- this.sliderCallbackFactory_(ColourChannel.BRIGHTNESS)
336
- );
309
+ this.sliderCallbackFactory_(ColourChannel.BRIGHTNESS),
310
+ )
337
311
  }
338
312
 
339
313
  dispose() {
340
314
  if (this.hueChangeEventKey_) {
341
- Blockly.browserEvents.unbind(this.hueChangeEventKey_);
315
+ Blockly.browserEvents.unbind(this.hueChangeEventKey_)
342
316
  }
343
317
  if (this.saturationChangeEventKey_) {
344
- Blockly.browserEvents.unbind(this.saturationChangeEventKey_);
318
+ Blockly.browserEvents.unbind(this.saturationChangeEventKey_)
345
319
  }
346
320
  if (this.brightnessChangeEventKey_) {
347
- Blockly.browserEvents.unbind(this.brightnessChangeEventKey_);
321
+ Blockly.browserEvents.unbind(this.brightnessChangeEventKey_)
348
322
  }
349
323
  if (this.eyedropperEventData_) {
350
- Blockly.browserEvents.unbind(this.eyedropperEventData_);
324
+ Blockly.browserEvents.unbind(this.eyedropperEventData_)
351
325
  }
352
- Blockly.Events.setGroup(false);
353
- super.dispose();
326
+ Blockly.Events.setGroup(false)
327
+ super.dispose()
354
328
  }
355
329
 
356
330
  // From Closure
357
- rgbToHsv(
358
- red: number,
359
- green: number,
360
- blue: number
361
- ): { hue: number; saturation: number; value: number } {
362
- const max = Math.max(Math.max(red, green), blue);
363
- const min = Math.min(Math.min(red, green), blue);
364
- let hue;
365
- let saturation;
366
- const value = max;
331
+ rgbToHsv(red: number, green: number, blue: number): { hue: number; saturation: number; value: number } {
332
+ const max = Math.max(Math.max(red, green), blue)
333
+ const min = Math.min(Math.min(red, green), blue)
334
+ let hue
335
+ let saturation
336
+ const value = max
367
337
  if (min == max) {
368
- hue = 0;
369
- saturation = 0;
338
+ hue = 0
339
+ saturation = 0
370
340
  } else {
371
- const delta = max - min;
372
- saturation = delta / max;
341
+ const delta = max - min
342
+ saturation = delta / max
373
343
 
374
344
  if (red == max) {
375
- hue = (green - blue) / delta;
345
+ hue = (green - blue) / delta
376
346
  } else if (green == max) {
377
- hue = 2 + (blue - red) / delta;
347
+ hue = 2 + (blue - red) / delta
378
348
  } else {
379
- hue = 4 + (red - green) / delta;
349
+ hue = 4 + (red - green) / delta
380
350
  }
381
- hue *= 60;
351
+ hue *= 60
382
352
  if (hue < 0) {
383
- hue += 360;
353
+ hue += 360
384
354
  }
385
355
  if (hue > 360) {
386
- hue -= 360;
356
+ hue -= 360
387
357
  }
388
358
  }
389
359
 
390
- return { hue, saturation, value };
360
+ return { hue, saturation, value }
391
361
  }
392
362
  }
393
363
 
@@ -395,5 +365,5 @@ export class FieldColourSlider extends FieldColour {
395
365
  * Register the field and any dependencies.
396
366
  */
397
367
  export function registerFieldColourSlider() {
398
- Blockly.fieldRegistry.register("field_colour_slider", FieldColourSlider);
368
+ Blockly.fieldRegistry.register('field_colour_slider', FieldColourSlider)
399
369
  }