blockly 7.20211209.2 → 8.0.0

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 (262) hide show
  1. package/blockly.d.ts +18963 -18432
  2. package/blockly.min.js +852 -844
  3. package/blockly_compressed.js +669 -664
  4. package/blockly_compressed.js.map +1 -1
  5. package/blocks/blocks.js +47 -0
  6. package/blocks/colour.js +13 -3
  7. package/blocks/lists.js +22 -13
  8. package/blocks/logic.js +13 -3
  9. package/blocks/loops.js +24 -11
  10. package/blocks/math.js +12 -3
  11. package/blocks/procedures.js +41 -27
  12. package/blocks/text.js +22 -13
  13. package/blocks/variables.js +14 -3
  14. package/blocks/variables_dynamic.js +13 -3
  15. package/blocks_compressed.js +146 -141
  16. package/blocks_compressed.js.map +1 -1
  17. package/core/block.js +1869 -1814
  18. package/core/block_drag_surface.js +201 -200
  19. package/core/block_dragger.js +377 -373
  20. package/core/block_svg.js +1593 -1479
  21. package/core/blockly.js +8 -22
  22. package/core/blocks.js +9 -2
  23. package/core/browser_events.js +22 -5
  24. package/core/bubble.js +841 -797
  25. package/core/bubble_dragger.js +213 -206
  26. package/core/bump_objects.js +2 -2
  27. package/core/clipboard.js +9 -9
  28. package/core/comment.js +353 -332
  29. package/core/common.js +46 -17
  30. package/core/component_manager.js +181 -174
  31. package/core/config.js +87 -0
  32. package/core/connection.js +595 -584
  33. package/core/connection_checker.js +242 -244
  34. package/core/connection_db.js +235 -230
  35. package/core/contextmenu.js +9 -6
  36. package/core/contextmenu_items.js +1 -2
  37. package/core/contextmenu_registry.js +93 -89
  38. package/core/css.js +474 -474
  39. package/core/delete_area.js +45 -42
  40. package/core/drag_target.js +57 -56
  41. package/core/dropdowndiv.js +153 -163
  42. package/core/events/events.js +2 -2
  43. package/core/events/events_abstract.js +89 -77
  44. package/core/events/events_block_base.js +37 -36
  45. package/core/events/events_block_change.js +130 -124
  46. package/core/events/events_block_create.js +73 -71
  47. package/core/events/events_block_delete.js +84 -82
  48. package/core/events/events_block_drag.js +50 -49
  49. package/core/events/events_block_move.js +147 -140
  50. package/core/events/events_bubble_open.js +51 -50
  51. package/core/events/events_click.js +48 -44
  52. package/core/events/events_comment_base.js +72 -69
  53. package/core/events/events_comment_change.js +63 -61
  54. package/core/events/events_comment_create.js +44 -42
  55. package/core/events/events_comment_delete.js +42 -40
  56. package/core/events/events_comment_move.js +106 -104
  57. package/core/events/events_marker_move.js +65 -64
  58. package/core/events/events_selected.js +46 -45
  59. package/core/events/events_theme_change.js +36 -35
  60. package/core/events/events_toolbox_item_select.js +46 -45
  61. package/core/events/events_trashcan_open.js +37 -36
  62. package/core/events/events_ui.js +47 -46
  63. package/core/events/events_ui_base.js +30 -29
  64. package/core/events/events_var_base.js +37 -36
  65. package/core/events/events_var_create.js +50 -48
  66. package/core/events/events_var_delete.js +50 -48
  67. package/core/events/events_var_rename.js +51 -49
  68. package/core/events/events_viewport.js +66 -65
  69. package/core/events/utils.js +29 -14
  70. package/core/events/workspace_events.js +49 -55
  71. package/core/extensions.js +4 -3
  72. package/core/field.js +1061 -997
  73. package/core/field_angle.js +462 -442
  74. package/core/field_checkbox.js +194 -182
  75. package/core/field_colour.js +519 -505
  76. package/core/field_dropdown.js +617 -598
  77. package/core/field_image.js +229 -220
  78. package/core/field_label.js +102 -91
  79. package/core/field_label_serializable.js +42 -41
  80. package/core/field_multilineinput.js +372 -358
  81. package/core/field_number.js +272 -253
  82. package/core/field_textinput.js +499 -467
  83. package/core/field_variable.js +458 -420
  84. package/core/flyout_base.js +1005 -952
  85. package/core/flyout_button.js +277 -260
  86. package/core/flyout_horizontal.js +304 -302
  87. package/core/flyout_metrics_manager.js +64 -64
  88. package/core/flyout_vertical.js +306 -300
  89. package/core/generator.js +459 -446
  90. package/core/gesture.js +829 -813
  91. package/core/grid.js +166 -163
  92. package/core/icon.js +168 -159
  93. package/core/inject.js +7 -5
  94. package/core/input.js +257 -248
  95. package/core/insertion_marker_manager.js +655 -624
  96. package/core/internal_constants.js +0 -129
  97. package/core/keyboard_nav/ast_node.js +605 -596
  98. package/core/keyboard_nav/basic_cursor.js +166 -165
  99. package/core/keyboard_nav/cursor.js +99 -97
  100. package/core/keyboard_nav/marker.js +83 -79
  101. package/core/keyboard_nav/tab_navigate_cursor.js +18 -23
  102. package/core/marker_manager.js +153 -141
  103. package/core/menu.js +377 -372
  104. package/core/menuitem.js +223 -217
  105. package/core/metrics_manager.js +403 -390
  106. package/core/mutator.js +468 -437
  107. package/core/names.js +229 -188
  108. package/core/options.js +290 -284
  109. package/core/procedures.js +29 -17
  110. package/core/registry.js +19 -16
  111. package/core/rendered_connection.js +482 -463
  112. package/core/renderers/common/block_rendering.js +9 -3
  113. package/core/renderers/common/constants.js +1119 -1112
  114. package/core/renderers/common/debug.js +14 -0
  115. package/core/renderers/common/debugger.js +338 -316
  116. package/core/renderers/common/drawer.js +380 -370
  117. package/core/renderers/common/i_path_object.js +2 -2
  118. package/core/renderers/common/info.js +626 -618
  119. package/core/renderers/common/marker_svg.js +579 -541
  120. package/core/renderers/common/path_object.js +203 -200
  121. package/core/renderers/common/renderer.js +220 -218
  122. package/core/renderers/geras/constants.js +36 -36
  123. package/core/renderers/geras/drawer.js +155 -147
  124. package/core/renderers/geras/highlight_constants.js +244 -238
  125. package/core/renderers/geras/highlighter.js +231 -179
  126. package/core/renderers/geras/info.js +392 -369
  127. package/core/renderers/geras/measurables/inline_input.js +25 -19
  128. package/core/renderers/geras/measurables/statement_input.js +23 -17
  129. package/core/renderers/geras/path_object.js +106 -121
  130. package/core/renderers/geras/renderer.js +96 -98
  131. package/core/renderers/measurables/base.js +30 -18
  132. package/core/renderers/measurables/bottom_row.js +83 -80
  133. package/core/renderers/measurables/connection.js +22 -15
  134. package/core/renderers/measurables/external_value_input.js +35 -22
  135. package/core/renderers/measurables/field.js +35 -20
  136. package/core/renderers/measurables/hat.js +18 -13
  137. package/core/renderers/measurables/icon.js +24 -17
  138. package/core/renderers/measurables/in_row_spacer.js +15 -13
  139. package/core/renderers/measurables/inline_input.js +43 -33
  140. package/core/renderers/measurables/input_connection.js +41 -28
  141. package/core/renderers/measurables/input_row.js +50 -44
  142. package/core/renderers/measurables/jagged_edge.js +14 -12
  143. package/core/renderers/measurables/next_connection.js +16 -14
  144. package/core/renderers/measurables/output_connection.js +26 -20
  145. package/core/renderers/measurables/previous_connection.js +16 -15
  146. package/core/renderers/measurables/round_corner.js +20 -18
  147. package/core/renderers/measurables/row.js +184 -168
  148. package/core/renderers/measurables/spacer_row.js +38 -23
  149. package/core/renderers/measurables/square_corner.js +18 -16
  150. package/core/renderers/measurables/statement_input.js +23 -20
  151. package/core/renderers/measurables/top_row.js +88 -85
  152. package/core/renderers/minimalist/constants.js +8 -7
  153. package/core/renderers/minimalist/drawer.js +11 -10
  154. package/core/renderers/minimalist/info.js +18 -18
  155. package/core/renderers/minimalist/renderer.js +40 -39
  156. package/core/renderers/thrasos/info.js +258 -248
  157. package/core/renderers/thrasos/renderer.js +20 -20
  158. package/core/renderers/zelos/constants.js +898 -873
  159. package/core/renderers/zelos/drawer.js +186 -169
  160. package/core/renderers/zelos/info.js +502 -479
  161. package/core/renderers/zelos/marker_svg.js +129 -115
  162. package/core/renderers/zelos/measurables/bottom_row.js +31 -30
  163. package/core/renderers/zelos/measurables/inputs.js +22 -21
  164. package/core/renderers/zelos/measurables/row_elements.js +14 -13
  165. package/core/renderers/zelos/measurables/top_row.js +34 -33
  166. package/core/renderers/zelos/path_object.js +181 -180
  167. package/core/renderers/zelos/renderer.js +91 -92
  168. package/core/scrollbar.js +759 -713
  169. package/core/scrollbar_pair.js +250 -245
  170. package/core/serialization/blocks.js +19 -9
  171. package/core/serialization/workspaces.js +3 -2
  172. package/core/shortcut_registry.js +286 -277
  173. package/core/sprites.js +31 -0
  174. package/core/theme.js +135 -141
  175. package/core/theme_manager.js +147 -143
  176. package/core/toolbox/category.js +602 -576
  177. package/core/toolbox/collapsible_category.js +226 -227
  178. package/core/toolbox/separator.js +70 -61
  179. package/core/toolbox/toolbox.js +934 -927
  180. package/core/toolbox/toolbox_item.js +115 -99
  181. package/core/tooltip.js +108 -35
  182. package/core/touch.js +8 -3
  183. package/core/touch_gesture.js +254 -251
  184. package/core/trashcan.js +606 -595
  185. package/core/utils/coordinate.js +97 -95
  186. package/core/utils/dom.js +2 -2
  187. package/core/utils/global.js +2 -0
  188. package/core/utils/rect.js +41 -37
  189. package/core/utils/sentinel.js +25 -0
  190. package/core/utils/size.js +30 -27
  191. package/core/utils/svg.js +18 -16
  192. package/core/variable_map.js +325 -341
  193. package/core/variable_model.js +55 -54
  194. package/core/variables.js +9 -2
  195. package/core/variables_dynamic.js +3 -1
  196. package/core/warning.js +126 -120
  197. package/core/widgetdiv.js +4 -4
  198. package/core/workspace.js +685 -664
  199. package/core/workspace_audio.js +124 -118
  200. package/core/workspace_comment.js +308 -298
  201. package/core/workspace_comment_svg.js +1029 -951
  202. package/core/workspace_drag_surface_svg.js +147 -140
  203. package/core/workspace_dragger.js +70 -71
  204. package/core/workspace_svg.js +2322 -2297
  205. package/core/xml.js +30 -20
  206. package/core/zoom_controls.js +431 -439
  207. package/dart_compressed.js +40 -43
  208. package/dart_compressed.js.map +1 -1
  209. package/generators/dart/colour.js +56 -64
  210. package/generators/dart/lists.js +61 -50
  211. package/generators/dart/math.js +160 -148
  212. package/generators/dart/text.js +83 -61
  213. package/generators/javascript/colour.js +37 -34
  214. package/generators/javascript/lists.js +50 -43
  215. package/generators/javascript/math.js +123 -139
  216. package/generators/javascript/text.js +67 -81
  217. package/generators/lua/colour.js +25 -23
  218. package/generators/lua/lists.js +97 -69
  219. package/generators/lua/logic.js +1 -2
  220. package/generators/lua/math.js +182 -144
  221. package/generators/lua/text.js +116 -99
  222. package/generators/php/colour.js +38 -32
  223. package/generators/php/lists.js +109 -89
  224. package/generators/php/math.js +90 -81
  225. package/generators/php/text.js +63 -61
  226. package/generators/python/colour.js +18 -18
  227. package/generators/python/lists.js +38 -30
  228. package/generators/python/loops.js +12 -8
  229. package/generators/python/math.js +104 -106
  230. package/generators/python/text.js +34 -30
  231. package/javascript_compressed.js +37 -39
  232. package/javascript_compressed.js.map +1 -1
  233. package/lua_compressed.js +39 -42
  234. package/lua_compressed.js.map +1 -1
  235. package/msg/az.js +2 -2
  236. package/msg/be.js +4 -4
  237. package/msg/cs.js +15 -15
  238. package/msg/de.js +1 -1
  239. package/msg/diq.js +1 -1
  240. package/msg/eo.js +1 -1
  241. package/msg/es.js +1 -1
  242. package/msg/fa.js +1 -1
  243. package/msg/fr.js +4 -4
  244. package/msg/he.js +1 -1
  245. package/msg/hr.js +2 -2
  246. package/msg/hy.js +2 -2
  247. package/msg/id.js +12 -12
  248. package/msg/inh.js +14 -14
  249. package/msg/ja.js +7 -7
  250. package/msg/lv.js +29 -29
  251. package/msg/pa.js +3 -3
  252. package/msg/smn.js +436 -0
  253. package/msg/te.js +1 -1
  254. package/msg/yue.js +1 -1
  255. package/msg/zh-hans.js +3 -3
  256. package/msg/zh-hant.js +3 -3
  257. package/package.json +7 -6
  258. package/php_compressed.js +38 -42
  259. package/php_compressed.js.map +1 -1
  260. package/python_compressed.js +26 -25
  261. package/python_compressed.js.map +1 -1
  262. package/blocks/all.js +0 -23
@@ -27,331 +27,340 @@ const {Workspace} = goog.requireType('Blockly.Workspace');
27
27
  * Class for the registry of keyboard shortcuts. This is intended to be a
28
28
  * singleton. You should not create a new instance, and only access this class
29
29
  * from ShortcutRegistry.registry.
30
- * @constructor
31
30
  * @alias Blockly.ShortcutRegistry
32
31
  */
33
- const ShortcutRegistry = function() {
34
- // Singleton instance should be registered once.
35
- ShortcutRegistry.registry = this;
36
-
32
+ class ShortcutRegistry {
37
33
  /**
38
- * Registry of all keyboard shortcuts, keyed by name of shortcut.
39
- * @type {!Object<string, !ShortcutRegistry.KeyboardShortcut>}
40
- * @private
34
+ * Resets the existing ShortcutRegistry singleton.
41
35
  */
42
- this.registry_ = Object.create(null);
36
+ constructor() {
37
+ this.reset();
38
+ }
43
39
 
44
40
  /**
45
- * Map of key codes to an array of shortcut names.
46
- * @type {!Object<string, !Array<string>>}
47
- * @private
41
+ * Clear and recreate the registry and keyMap.
48
42
  */
49
- this.keyMap_ = Object.create(null);
50
- };
51
-
52
- /**
53
- * Enum of valid modifiers.
54
- * @enum {!KeyCodes<number>}
55
- */
56
- ShortcutRegistry.modifierKeys = {
57
- 'Shift': KeyCodes.SHIFT,
58
- 'Control': KeyCodes.CTRL,
59
- 'Alt': KeyCodes.ALT,
60
- 'Meta': KeyCodes.META,
61
- };
62
-
63
- /**
64
- * A keyboard shortcut.
65
- * @typedef {{
66
- * callback: ((function(!Workspace, Event,
67
- * !ShortcutRegistry.KeyboardShortcut):boolean)|undefined),
68
- * name: string,
69
- * preconditionFn: ((function(!Workspace):boolean)|undefined),
70
- * metadata: (Object|undefined)
71
- * }}
72
- */
73
- ShortcutRegistry.KeyboardShortcut;
74
-
75
- /**
76
- * Registers a keyboard shortcut.
77
- * @param {!ShortcutRegistry.KeyboardShortcut} shortcut The
78
- * shortcut for this key code.
79
- * @param {boolean=} opt_allowOverrides True to prevent a warning when
80
- * overriding an already registered item.
81
- * @throws {Error} if a shortcut with the same name already exists.
82
- * @public
83
- */
84
- ShortcutRegistry.prototype.register = function(shortcut, opt_allowOverrides) {
85
- const registeredShortcut = this.registry_[shortcut.name];
86
- if (registeredShortcut && !opt_allowOverrides) {
87
- throw new Error(
88
- 'Shortcut with name "' + shortcut.name + '" already exists.');
43
+ reset() {
44
+ /**
45
+ * Registry of all keyboard shortcuts, keyed by name of shortcut.
46
+ * @type {!Object<string, !ShortcutRegistry.KeyboardShortcut>}
47
+ * @private
48
+ */
49
+ this.registry_ = Object.create(null);
50
+
51
+ /**
52
+ * Map of key codes to an array of shortcut names.
53
+ * @type {!Object<string, !Array<string>>}
54
+ * @private
55
+ */
56
+ this.keyMap_ = Object.create(null);
89
57
  }
90
- this.registry_[shortcut.name] = shortcut;
91
- };
92
58
 
93
- /**
94
- * Unregisters a keyboard shortcut registered with the given key code. This will
95
- * also remove any key mappings that reference this shortcut.
96
- * @param {string} shortcutName The name of the shortcut to unregister.
97
- * @return {boolean} True if an item was unregistered, false otherwise.
98
- * @public
99
- */
100
- ShortcutRegistry.prototype.unregister = function(shortcutName) {
101
- const shortcut = this.registry_[shortcutName];
102
-
103
- if (!shortcut) {
104
- console.warn(
105
- 'Keyboard shortcut with name "' + shortcutName + '" not found.');
106
- return false;
59
+ /**
60
+ * Registers a keyboard shortcut.
61
+ * @param {!ShortcutRegistry.KeyboardShortcut} shortcut The
62
+ * shortcut for this key code.
63
+ * @param {boolean=} opt_allowOverrides True to prevent a warning when
64
+ * overriding an already registered item.
65
+ * @throws {Error} if a shortcut with the same name already exists.
66
+ * @public
67
+ */
68
+ register(shortcut, opt_allowOverrides) {
69
+ const registeredShortcut = this.registry_[shortcut.name];
70
+ if (registeredShortcut && !opt_allowOverrides) {
71
+ throw new Error(
72
+ 'Shortcut with name "' + shortcut.name + '" already exists.');
73
+ }
74
+ this.registry_[shortcut.name] = shortcut;
107
75
  }
108
76
 
109
- this.removeAllKeyMappings(shortcutName);
110
-
111
- delete this.registry_[shortcutName];
112
- return true;
113
- };
77
+ /**
78
+ * Unregisters a keyboard shortcut registered with the given key code. This
79
+ * will also remove any key mappings that reference this shortcut.
80
+ * @param {string} shortcutName The name of the shortcut to unregister.
81
+ * @return {boolean} True if an item was unregistered, false otherwise.
82
+ * @public
83
+ */
84
+ unregister(shortcutName) {
85
+ const shortcut = this.registry_[shortcutName];
114
86
 
115
- /**
116
- * Adds a mapping between a keycode and a keyboard shortcut.
117
- * @param {string|KeyCodes} keyCode The key code for the keyboard
118
- * shortcut. If registering a key code with a modifier (ex: ctrl+c) use
119
- * ShortcutRegistry.registry.createSerializedKey;
120
- * @param {string} shortcutName The name of the shortcut to execute when the
121
- * given keycode is pressed.
122
- * @param {boolean=} opt_allowCollision True to prevent an error when adding a
123
- * shortcut to a key that is already mapped to a shortcut.
124
- * @throws {Error} if the given key code is already mapped to a shortcut.
125
- * @public
126
- */
127
- ShortcutRegistry.prototype.addKeyMapping = function(
128
- keyCode, shortcutName, opt_allowCollision) {
129
- keyCode = String(keyCode);
130
- const shortcutNames = this.keyMap_[keyCode];
131
- if (shortcutNames && !opt_allowCollision) {
132
- throw new Error(
133
- 'Shortcut with name "' + shortcutName + '" collides with shortcuts ' +
134
- shortcutNames.toString());
135
- } else if (shortcutNames && opt_allowCollision) {
136
- shortcutNames.unshift(shortcutName);
137
- } else {
138
- this.keyMap_[keyCode] = [shortcutName];
139
- }
140
- };
87
+ if (!shortcut) {
88
+ console.warn(
89
+ 'Keyboard shortcut with name "' + shortcutName + '" not found.');
90
+ return false;
91
+ }
141
92
 
142
- /**
143
- * Removes a mapping between a keycode and a keyboard shortcut.
144
- * @param {string} keyCode The key code for the keyboard shortcut. If
145
- * registering a key code with a modifier (ex: ctrl+c) use
146
- * ShortcutRegistry.registry.createSerializedKey;
147
- * @param {string} shortcutName The name of the shortcut to execute when the
148
- * given keycode is pressed.
149
- * @param {boolean=} opt_quiet True to not console warn when there is no
150
- * shortcut to remove.
151
- * @return {boolean} True if a key mapping was removed, false otherwise.
152
- * @public
153
- */
154
- ShortcutRegistry.prototype.removeKeyMapping = function(
155
- keyCode, shortcutName, opt_quiet) {
156
- const shortcutNames = this.keyMap_[keyCode];
157
-
158
- if (!shortcutNames && !opt_quiet) {
159
- console.warn(
160
- 'No keyboard shortcut with name "' + shortcutName +
161
- '" registered with key code "' + keyCode + '"');
162
- return false;
163
- }
93
+ this.removeAllKeyMappings(shortcutName);
164
94
 
165
- const shortcutIdx = shortcutNames.indexOf(shortcutName);
166
- if (shortcutIdx > -1) {
167
- shortcutNames.splice(shortcutIdx, 1);
168
- if (shortcutNames.length === 0) {
169
- delete this.keyMap_[keyCode];
170
- }
95
+ delete this.registry_[shortcutName];
171
96
  return true;
172
97
  }
173
- if (!opt_quiet) {
174
- console.warn(
175
- 'No keyboard shortcut with name "' + shortcutName +
176
- '" registered with key code "' + keyCode + '"');
177
- }
178
- return false;
179
- };
180
98
 
181
- /**
182
- * Removes all the key mappings for a shortcut with the given name.
183
- * Useful when changing the default key mappings and the key codes registered to
184
- * the shortcut are unknown.
185
- * @param {string} shortcutName The name of the shortcut to remove from the key
186
- * map.
187
- * @public
188
- */
189
- ShortcutRegistry.prototype.removeAllKeyMappings = function(shortcutName) {
190
- for (const keyCode in this.keyMap_) {
191
- this.removeKeyMapping(keyCode, shortcutName, true);
99
+ /**
100
+ * Adds a mapping between a keycode and a keyboard shortcut.
101
+ * @param {string|KeyCodes} keyCode The key code for the keyboard
102
+ * shortcut. If registering a key code with a modifier (ex: ctrl+c) use
103
+ * ShortcutRegistry.registry.createSerializedKey;
104
+ * @param {string} shortcutName The name of the shortcut to execute when the
105
+ * given keycode is pressed.
106
+ * @param {boolean=} opt_allowCollision True to prevent an error when adding a
107
+ * shortcut to a key that is already mapped to a shortcut.
108
+ * @throws {Error} if the given key code is already mapped to a shortcut.
109
+ * @public
110
+ */
111
+ addKeyMapping(keyCode, shortcutName, opt_allowCollision) {
112
+ keyCode = String(keyCode);
113
+ const shortcutNames = this.keyMap_[keyCode];
114
+ if (shortcutNames && !opt_allowCollision) {
115
+ throw new Error(
116
+ 'Shortcut with name "' + shortcutName + '" collides with shortcuts ' +
117
+ shortcutNames.toString());
118
+ } else if (shortcutNames && opt_allowCollision) {
119
+ shortcutNames.unshift(shortcutName);
120
+ } else {
121
+ this.keyMap_[keyCode] = [shortcutName];
122
+ }
192
123
  }
193
- };
194
124
 
195
- /**
196
- * Sets the key map. Setting the key map will override any default key mappings.
197
- * @param {!Object<string, !Array<string>>} keyMap The object with key code to
198
- * shortcut names.
199
- * @public
200
- */
201
- ShortcutRegistry.prototype.setKeyMap = function(keyMap) {
202
- this.keyMap_ = keyMap;
203
- };
204
-
205
- /**
206
- * Gets the current key map.
207
- * @return {!Object<string,!Array<!ShortcutRegistry.KeyboardShortcut>>}
208
- * The object holding key codes to ShortcutRegistry.KeyboardShortcut.
209
- * @public
210
- */
211
- ShortcutRegistry.prototype.getKeyMap = function() {
212
- return object.deepMerge(Object.create(null), this.keyMap_);
213
- };
214
-
215
- /**
216
- * Gets the registry of keyboard shortcuts.
217
- * @return {!Object<string, !ShortcutRegistry.KeyboardShortcut>}
218
- * The registry of keyboard shortcuts.
219
- * @public
220
- */
221
- ShortcutRegistry.prototype.getRegistry = function() {
222
- return object.deepMerge(Object.create(null), this.registry_);
223
- };
125
+ /**
126
+ * Removes a mapping between a keycode and a keyboard shortcut.
127
+ * @param {string} keyCode The key code for the keyboard shortcut. If
128
+ * registering a key code with a modifier (ex: ctrl+c) use
129
+ * ShortcutRegistry.registry.createSerializedKey;
130
+ * @param {string} shortcutName The name of the shortcut to execute when the
131
+ * given keycode is pressed.
132
+ * @param {boolean=} opt_quiet True to not console warn when there is no
133
+ * shortcut to remove.
134
+ * @return {boolean} True if a key mapping was removed, false otherwise.
135
+ * @public
136
+ */
137
+ removeKeyMapping(keyCode, shortcutName, opt_quiet) {
138
+ const shortcutNames = this.keyMap_[keyCode];
139
+
140
+ if (!shortcutNames && !opt_quiet) {
141
+ console.warn(
142
+ 'No keyboard shortcut with name "' + shortcutName +
143
+ '" registered with key code "' + keyCode + '"');
144
+ return false;
145
+ }
224
146
 
225
- /**
226
- * Handles key down events.
227
- * @param {!Workspace} workspace The main workspace where the event was
228
- * captured.
229
- * @param {!Event} e The key down event.
230
- * @return {boolean} True if the event was handled, false otherwise.
231
- * @public
232
- */
233
- ShortcutRegistry.prototype.onKeyDown = function(workspace, e) {
234
- const key = this.serializeKeyEvent_(e);
235
- const shortcutNames = this.getShortcutNamesByKeyCode(key);
236
- if (!shortcutNames) {
147
+ const shortcutIdx = shortcutNames.indexOf(shortcutName);
148
+ if (shortcutIdx > -1) {
149
+ shortcutNames.splice(shortcutIdx, 1);
150
+ if (shortcutNames.length === 0) {
151
+ delete this.keyMap_[keyCode];
152
+ }
153
+ return true;
154
+ }
155
+ if (!opt_quiet) {
156
+ console.warn(
157
+ 'No keyboard shortcut with name "' + shortcutName +
158
+ '" registered with key code "' + keyCode + '"');
159
+ }
237
160
  return false;
238
161
  }
239
- for (let i = 0, shortcutName; (shortcutName = shortcutNames[i]); i++) {
240
- const shortcut = this.registry_[shortcutName];
241
- if (!shortcut.preconditionFn || shortcut.preconditionFn(workspace)) {
242
- // If the key has been handled, stop processing shortcuts.
243
- if (shortcut.callback && shortcut.callback(workspace, e, shortcut)) {
244
- return true;
245
- }
162
+
163
+ /**
164
+ * Removes all the key mappings for a shortcut with the given name.
165
+ * Useful when changing the default key mappings and the key codes registered
166
+ * to the shortcut are unknown.
167
+ * @param {string} shortcutName The name of the shortcut to remove from the
168
+ * key map.
169
+ * @public
170
+ */
171
+ removeAllKeyMappings(shortcutName) {
172
+ for (const keyCode in this.keyMap_) {
173
+ this.removeKeyMapping(keyCode, shortcutName, true);
246
174
  }
247
175
  }
248
- return false;
249
- };
250
176
 
251
- /**
252
- * Gets the shortcuts registered to the given key code.
253
- * @param {string} keyCode The serialized key code.
254
- * @return {!Array<string>|undefined} The list of shortcuts to call when the
255
- * given keyCode is used. Undefined if no shortcuts exist.
256
- * @public
257
- */
258
- ShortcutRegistry.prototype.getShortcutNamesByKeyCode = function(keyCode) {
259
- return this.keyMap_[keyCode] || [];
260
- };
177
+ /**
178
+ * Sets the key map. Setting the key map will override any default key
179
+ * mappings.
180
+ * @param {!Object<string, !Array<string>>} keyMap The object with key code to
181
+ * shortcut names.
182
+ * @public
183
+ */
184
+ setKeyMap(keyMap) {
185
+ this.keyMap_ = keyMap;
186
+ }
261
187
 
262
- /**
263
- * Gets the serialized key codes that the shortcut with the given name is
264
- * registered under.
265
- * @param {string} shortcutName The name of the shortcut.
266
- * @return {!Array<string>} An array with all the key codes the shortcut is
267
- * registered under.
268
- * @public
269
- */
270
- ShortcutRegistry.prototype.getKeyCodesByShortcutName = function(shortcutName) {
271
- const keys = [];
272
- for (const keyCode in this.keyMap_) {
273
- const shortcuts = this.keyMap_[keyCode];
274
- const shortcutIdx = shortcuts.indexOf(shortcutName);
275
- if (shortcutIdx > -1) {
276
- keys.push(keyCode);
277
- }
188
+ /**
189
+ * Gets the current key map.
190
+ * @return {!Object<string,!Array<!ShortcutRegistry.KeyboardShortcut>>}
191
+ * The object holding key codes to ShortcutRegistry.KeyboardShortcut.
192
+ * @public
193
+ */
194
+ getKeyMap() {
195
+ return object.deepMerge(Object.create(null), this.keyMap_);
278
196
  }
279
- return keys;
280
- };
281
197
 
282
- /**
283
- * Serializes a key event.
284
- * @param {!Event} e A key down event.
285
- * @return {string} The serialized key code for the given event.
286
- * @private
287
- */
288
- ShortcutRegistry.prototype.serializeKeyEvent_ = function(e) {
289
- let serializedKey = '';
290
- for (const modifier in ShortcutRegistry.modifierKeys) {
291
- if (e.getModifierState(modifier)) {
292
- if (serializedKey !== '') {
293
- serializedKey += '+';
198
+ /**
199
+ * Gets the registry of keyboard shortcuts.
200
+ * @return {!Object<string, !ShortcutRegistry.KeyboardShortcut>}
201
+ * The registry of keyboard shortcuts.
202
+ * @public
203
+ */
204
+ getRegistry() {
205
+ return object.deepMerge(Object.create(null), this.registry_);
206
+ }
207
+
208
+ /**
209
+ * Handles key down events.
210
+ * @param {!Workspace} workspace The main workspace where the event was
211
+ * captured.
212
+ * @param {!Event} e The key down event.
213
+ * @return {boolean} True if the event was handled, false otherwise.
214
+ * @public
215
+ */
216
+ onKeyDown(workspace, e) {
217
+ const key = this.serializeKeyEvent_(e);
218
+ const shortcutNames = this.getShortcutNamesByKeyCode(key);
219
+ if (!shortcutNames) {
220
+ return false;
221
+ }
222
+ for (let i = 0, shortcutName; (shortcutName = shortcutNames[i]); i++) {
223
+ const shortcut = this.registry_[shortcutName];
224
+ if (!shortcut.preconditionFn || shortcut.preconditionFn(workspace)) {
225
+ // If the key has been handled, stop processing shortcuts.
226
+ if (shortcut.callback && shortcut.callback(workspace, e, shortcut)) {
227
+ return true;
228
+ }
294
229
  }
295
- serializedKey += modifier;
296
230
  }
231
+ return false;
297
232
  }
298
- if (serializedKey !== '' && e.keyCode) {
299
- serializedKey = serializedKey + '+' + e.keyCode;
300
- } else if (e.keyCode) {
301
- serializedKey = e.keyCode.toString();
233
+
234
+ /**
235
+ * Gets the shortcuts registered to the given key code.
236
+ * @param {string} keyCode The serialized key code.
237
+ * @return {!Array<string>|undefined} The list of shortcuts to call when the
238
+ * given keyCode is used. Undefined if no shortcuts exist.
239
+ * @public
240
+ */
241
+ getShortcutNamesByKeyCode(keyCode) {
242
+ return this.keyMap_[keyCode] || [];
302
243
  }
303
- return serializedKey;
304
- };
305
244
 
306
- /**
307
- * Checks whether any of the given modifiers are not valid.
308
- * @param {!Array<string>} modifiers List of modifiers to be used with the key.
309
- * @throws {Error} if the modifier is not in the valid modifiers list.
310
- * @private
311
- */
312
- ShortcutRegistry.prototype.checkModifiers_ = function(modifiers) {
313
- const validModifiers = object.values(ShortcutRegistry.modifierKeys);
314
- for (let i = 0, modifier; (modifier = modifiers[i]); i++) {
315
- if (validModifiers.indexOf(modifier) < 0) {
316
- throw new Error(modifier + ' is not a valid modifier key.');
245
+ /**
246
+ * Gets the serialized key codes that the shortcut with the given name is
247
+ * registered under.
248
+ * @param {string} shortcutName The name of the shortcut.
249
+ * @return {!Array<string>} An array with all the key codes the shortcut is
250
+ * registered under.
251
+ * @public
252
+ */
253
+ getKeyCodesByShortcutName(shortcutName) {
254
+ const keys = [];
255
+ for (const keyCode in this.keyMap_) {
256
+ const shortcuts = this.keyMap_[keyCode];
257
+ const shortcutIdx = shortcuts.indexOf(shortcutName);
258
+ if (shortcutIdx > -1) {
259
+ keys.push(keyCode);
260
+ }
317
261
  }
262
+ return keys;
318
263
  }
319
- };
320
264
 
321
- /**
322
- * Creates the serialized key code that will be used in the key map.
323
- * @param {number} keyCode Number code representing the key.
324
- * @param {?Array<string>} modifiers List of modifier key codes to be used with
325
- * the key. All valid modifiers can be found in the
326
- * ShortcutRegistry.modifierKeys.
327
- * @return {string} The serialized key code for the given modifiers and key.
328
- * @public
329
- */
330
- ShortcutRegistry.prototype.createSerializedKey = function(keyCode, modifiers) {
331
- let serializedKey = '';
332
-
333
- if (modifiers) {
334
- this.checkModifiers_(modifiers);
265
+ /**
266
+ * Serializes a key event.
267
+ * @param {!Event} e A key down event.
268
+ * @return {string} The serialized key code for the given event.
269
+ * @private
270
+ */
271
+ serializeKeyEvent_(e) {
272
+ let serializedKey = '';
335
273
  for (const modifier in ShortcutRegistry.modifierKeys) {
336
- const modifierKeyCode = ShortcutRegistry.modifierKeys[modifier];
337
- if (modifiers.indexOf(modifierKeyCode) > -1) {
274
+ if (e.getModifierState(modifier)) {
338
275
  if (serializedKey !== '') {
339
276
  serializedKey += '+';
340
277
  }
341
278
  serializedKey += modifier;
342
279
  }
343
280
  }
281
+ if (serializedKey !== '' && e.keyCode) {
282
+ serializedKey = serializedKey + '+' + e.keyCode;
283
+ } else if (e.keyCode) {
284
+ serializedKey = e.keyCode.toString();
285
+ }
286
+ return serializedKey;
287
+ }
288
+
289
+ /**
290
+ * Checks whether any of the given modifiers are not valid.
291
+ * @param {!Array<string>} modifiers List of modifiers to be used with the
292
+ * key.
293
+ * @throws {Error} if the modifier is not in the valid modifiers list.
294
+ * @private
295
+ */
296
+ checkModifiers_(modifiers) {
297
+ const validModifiers = object.values(ShortcutRegistry.modifierKeys);
298
+ for (let i = 0, modifier; (modifier = modifiers[i]); i++) {
299
+ if (validModifiers.indexOf(modifier) < 0) {
300
+ throw new Error(modifier + ' is not a valid modifier key.');
301
+ }
302
+ }
344
303
  }
345
304
 
346
- if (serializedKey !== '' && keyCode) {
347
- serializedKey = serializedKey + '+' + keyCode;
348
- } else if (keyCode) {
349
- serializedKey = keyCode.toString();
305
+ /**
306
+ * Creates the serialized key code that will be used in the key map.
307
+ * @param {number} keyCode Number code representing the key.
308
+ * @param {?Array<string>} modifiers List of modifier key codes to be used
309
+ * with the key. All valid modifiers can be found in the
310
+ * ShortcutRegistry.modifierKeys.
311
+ * @return {string} The serialized key code for the given modifiers and key.
312
+ * @public
313
+ */
314
+ createSerializedKey(keyCode, modifiers) {
315
+ let serializedKey = '';
316
+
317
+ if (modifiers) {
318
+ this.checkModifiers_(modifiers);
319
+ for (const modifier in ShortcutRegistry.modifierKeys) {
320
+ const modifierKeyCode = ShortcutRegistry.modifierKeys[modifier];
321
+ if (modifiers.indexOf(modifierKeyCode) > -1) {
322
+ if (serializedKey !== '') {
323
+ serializedKey += '+';
324
+ }
325
+ serializedKey += modifier;
326
+ }
327
+ }
328
+ }
329
+
330
+ if (serializedKey !== '' && keyCode) {
331
+ serializedKey = serializedKey + '+' + keyCode;
332
+ } else if (keyCode) {
333
+ serializedKey = keyCode.toString();
334
+ }
335
+ return serializedKey;
350
336
  }
351
- return serializedKey;
337
+ }
338
+
339
+ /**
340
+ * Enum of valid modifiers.
341
+ * @enum {!KeyCodes}
342
+ */
343
+ ShortcutRegistry.modifierKeys = {
344
+ 'Shift': KeyCodes.SHIFT,
345
+ 'Control': KeyCodes.CTRL,
346
+ 'Alt': KeyCodes.ALT,
347
+ 'Meta': KeyCodes.META,
352
348
  };
353
349
 
350
+ /**
351
+ * A keyboard shortcut.
352
+ * @typedef {{
353
+ * callback: ((function(!Workspace, Event,
354
+ * !ShortcutRegistry.KeyboardShortcut):boolean)|undefined),
355
+ * name: string,
356
+ * preconditionFn: ((function(!Workspace):boolean)|undefined),
357
+ * metadata: (Object|undefined)
358
+ * }}
359
+ */
360
+ ShortcutRegistry.KeyboardShortcut;
361
+
354
362
  // Creates and assigns the singleton instance.
355
- new ShortcutRegistry();
363
+ const registry = new ShortcutRegistry();
364
+ ShortcutRegistry.registry = registry;
356
365
 
357
366
  exports.ShortcutRegistry = ShortcutRegistry;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ /**
8
+ * @fileoverview Holds constants that have to do with the sprites that create
9
+ * the trashcan and zoom controls.
10
+ */
11
+ 'use strict';
12
+
13
+ /**
14
+ * Holds constants that have to do with the sprites that create the trashcan
15
+ * and zoom controls.
16
+ */
17
+ goog.module('Blockly.sprite');
18
+
19
+
20
+ /**
21
+ * Contains the path to a single png tat holds the images for the trashcan
22
+ * as well as the zoom controls.
23
+ * @const {!Object}
24
+ * @alias Blockly.sprite.SPRITE
25
+ */
26
+ const SPRITE = {
27
+ width: 96,
28
+ height: 124,
29
+ url: 'sprites.png',
30
+ };
31
+ exports.SPRITE = SPRITE;