blockly 9.0.0-beta.0 → 9.0.0-beta.2

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 (736) hide show
  1. package/blockly.min.js +830 -810
  2. package/blockly_compressed.js +821 -801
  3. package/blockly_compressed.js.map +1 -1
  4. package/blocks.d.ts +0 -5
  5. package/blocks_compressed.js +9 -9
  6. package/blocks_compressed.js.map +1 -1
  7. package/closure/goog/base.d.ts +1 -0
  8. package/closure/goog/base_minimal.d.ts +1 -0
  9. package/closure/goog/goog.d.ts +1 -0
  10. package/core/any_aliases.d.ts +1 -0
  11. package/core/block.d.ts +156 -53
  12. package/core/block_animations.d.ts +5 -0
  13. package/core/block_drag_surface.d.ts +18 -5
  14. package/core/block_dragger.d.ts +20 -5
  15. package/core/block_svg.d.ts +92 -24
  16. package/core/blockly.d.ts +31 -10
  17. package/core/blockly_options.d.ts +2 -0
  18. package/core/blocks.d.ts +2 -0
  19. package/core/browser_events.d.ts +16 -7
  20. package/core/bubble.d.ts +42 -12
  21. package/core/bubble_dragger.d.ts +9 -2
  22. package/core/bump_objects.d.ts +6 -2
  23. package/core/clipboard.d.ts +6 -2
  24. package/core/comment.d.ts +13 -3
  25. package/core/common.d.ts +35 -9
  26. package/core/component_manager.d.ts +16 -6
  27. package/core/config.d.ts +1 -0
  28. package/core/connection.d.ts +48 -18
  29. package/core/connection_checker.d.ts +16 -7
  30. package/core/connection_db.d.ts +17 -6
  31. package/core/connection_type.d.ts +2 -0
  32. package/core/constants.d.ts +3 -0
  33. package/core/contextmenu.d.ts +15 -5
  34. package/core/contextmenu_items.d.ts +15 -0
  35. package/core/contextmenu_registry.d.ts +12 -7
  36. package/core/css.d.ts +3 -0
  37. package/core/delete_area.d.ts +5 -1
  38. package/core/dialog.d.ts +14 -7
  39. package/core/drag_target.d.ts +10 -2
  40. package/core/dropdowndiv.d.ts +42 -10
  41. package/core/events/events.d.ts +51 -24
  42. package/core/events/events_abstract.d.ts +18 -7
  43. package/core/events/events_block_base.d.ts +13 -7
  44. package/core/events/events_block_change.d.ts +24 -11
  45. package/core/events/events_block_create.d.ts +18 -7
  46. package/core/events/events_block_delete.d.ts +20 -8
  47. package/core/events/events_block_drag.d.ts +14 -4
  48. package/core/events/events_block_move.d.ts +25 -12
  49. package/core/events/events_bubble_open.d.ts +21 -6
  50. package/core/events/events_click.d.ts +20 -6
  51. package/core/events/events_comment_base.d.ts +13 -6
  52. package/core/events/events_comment_change.d.ts +17 -7
  53. package/core/events/events_comment_create.d.ts +13 -5
  54. package/core/events/events_comment_delete.d.ts +4 -11
  55. package/core/events/events_comment_move.d.ts +19 -8
  56. package/core/events/events_marker_move.d.ts +16 -5
  57. package/core/events/events_selected.d.ts +14 -5
  58. package/core/events/events_theme_change.d.ts +11 -3
  59. package/core/events/events_toolbox_item_select.d.ts +14 -5
  60. package/core/events/events_trashcan_open.d.ts +11 -3
  61. package/core/events/events_ui.d.ts +5 -1
  62. package/core/events/events_ui_base.d.ts +2 -0
  63. package/core/events/events_var_base.d.ts +13 -7
  64. package/core/events/events_var_create.d.ts +15 -6
  65. package/core/events/events_var_delete.d.ts +15 -6
  66. package/core/events/events_var_rename.d.ts +15 -6
  67. package/core/events/events_viewport.d.ts +14 -3
  68. package/core/events/utils.d.ts +50 -7
  69. package/core/events/workspace_events.d.ts +11 -6
  70. package/core/extensions.d.ts +14 -4
  71. package/core/field.d.ts +93 -36
  72. package/core/field_angle.d.ts +14 -3
  73. package/core/field_checkbox.d.ts +20 -7
  74. package/core/field_colour.d.ts +22 -6
  75. package/core/field_dropdown.d.ts +28 -8
  76. package/core/field_image.d.ts +15 -4
  77. package/core/field_label.d.ts +8 -2
  78. package/core/field_label_serializable.d.ts +4 -1
  79. package/core/field_multilineinput.d.ts +21 -6
  80. package/core/field_number.d.ts +22 -6
  81. package/core/field_registry.d.ts +8 -2
  82. package/core/field_textinput.d.ts +28 -8
  83. package/core/field_variable.d.ts +36 -13
  84. package/core/flyout_base.d.ts +70 -24
  85. package/core/flyout_button.d.ts +12 -5
  86. package/core/flyout_horizontal.d.ts +14 -6
  87. package/core/flyout_metrics_manager.d.ts +6 -3
  88. package/core/flyout_vertical.d.ts +14 -6
  89. package/core/generator.d.ts +39 -20
  90. package/core/gesture.d.ts +56 -22
  91. package/core/grid.d.ts +20 -16
  92. package/core/icon.d.ts +18 -5
  93. package/core/inject.d.ts +3 -1
  94. package/core/input.d.ts +25 -10
  95. package/core/input_types.d.ts +2 -0
  96. package/core/insertion_marker_manager.d.ts +27 -9
  97. package/core/interfaces/i_ast_node_location.d.ts +2 -0
  98. package/core/interfaces/i_ast_node_location_svg.d.ts +4 -0
  99. package/core/interfaces/i_ast_node_location_with_block.d.ts +4 -1
  100. package/core/interfaces/i_autohideable.d.ts +3 -0
  101. package/core/interfaces/i_block_dragger.d.ts +7 -1
  102. package/core/interfaces/i_bounded_element.d.ts +5 -1
  103. package/core/interfaces/i_bubble.d.ts +11 -2
  104. package/core/interfaces/i_collapsible_toolbox_item.d.ts +6 -2
  105. package/core/interfaces/i_component.d.ts +3 -1
  106. package/core/interfaces/i_connection_checker.d.ts +14 -6
  107. package/core/interfaces/i_contextmenu.d.ts +2 -0
  108. package/core/interfaces/i_copyable.d.ts +3 -1
  109. package/core/interfaces/i_deletable.d.ts +4 -1
  110. package/core/interfaces/i_delete_area.d.ts +4 -1
  111. package/core/interfaces/i_drag_target.d.ts +10 -2
  112. package/core/interfaces/i_draggable.d.ts +2 -0
  113. package/core/interfaces/i_flyout.d.ts +27 -11
  114. package/core/interfaces/i_keyboard_accessible.d.ts +4 -1
  115. package/core/interfaces/i_metrics_manager.d.ts +24 -12
  116. package/core/interfaces/i_movable.d.ts +4 -1
  117. package/core/interfaces/i_positionable.d.ts +5 -1
  118. package/core/interfaces/i_registrable.d.ts +2 -0
  119. package/core/interfaces/i_registrable_field.d.ts +2 -0
  120. package/core/interfaces/i_selectable.d.ts +2 -0
  121. package/core/interfaces/i_selectable_toolbox_item.d.ts +10 -3
  122. package/core/interfaces/i_serializer.d.ts +6 -1
  123. package/core/interfaces/i_styleable.d.ts +4 -0
  124. package/core/interfaces/i_toolbox.d.ts +17 -6
  125. package/core/interfaces/i_toolbox_item.d.ts +17 -7
  126. package/core/internal_constants.d.ts +6 -0
  127. package/core/keyboard_nav/ast_node.d.ts +55 -28
  128. package/core/keyboard_nav/basic_cursor.d.ts +20 -9
  129. package/core/keyboard_nav/cursor.d.ts +11 -5
  130. package/core/keyboard_nav/marker.d.ts +9 -2
  131. package/core/keyboard_nav/tab_navigate_cursor.d.ts +4 -1
  132. package/core/main.d.ts +1 -0
  133. package/core/marker_manager.d.ts +13 -2
  134. package/core/menu.d.ts +25 -6
  135. package/core/menuitem.d.ts +22 -7
  136. package/core/metrics_manager.d.ts +30 -15
  137. package/core/msg.d.ts +15 -0
  138. package/core/mutator.d.ts +20 -8
  139. package/core/names.d.ts +20 -8
  140. package/core/options.d.ts +12 -6
  141. package/core/positionable_helpers.d.ts +11 -3
  142. package/core/procedures.d.ts +27 -10
  143. package/core/registry.d.ts +19 -8
  144. package/core/rendered_connection.d.ts +29 -7
  145. package/core/renderers/common/block_rendering.d.ts +9 -2
  146. package/core/renderers/common/constants.d.ts +57 -18
  147. package/core/renderers/common/debug.d.ts +5 -1
  148. package/core/renderers/common/debugger.d.ts +12 -1
  149. package/core/renderers/common/drawer.d.ts +16 -3
  150. package/core/renderers/common/i_path_object.d.ts +37 -16
  151. package/core/renderers/common/info.d.ts +28 -11
  152. package/core/renderers/common/marker_svg.d.ts +42 -11
  153. package/core/renderers/common/path_object.d.ts +23 -3
  154. package/core/renderers/common/renderer.d.ts +33 -12
  155. package/core/renderers/geras/constants.d.ts +6 -2
  156. package/core/renderers/geras/drawer.d.ts +4 -1
  157. package/core/renderers/geras/geras.d.ts +3 -2
  158. package/core/renderers/geras/highlight_constants.d.ts +9 -6
  159. package/core/renderers/geras/highlighter.d.ts +12 -1
  160. package/core/renderers/geras/info.d.ts +4 -1
  161. package/core/renderers/geras/measurables/inline_input.d.ts +2 -0
  162. package/core/renderers/geras/measurables/statement_input.d.ts +2 -0
  163. package/core/renderers/geras/path_object.d.ts +4 -1
  164. package/core/renderers/geras/renderer.d.ts +16 -6
  165. package/core/renderers/measurables/base.d.ts +2 -0
  166. package/core/renderers/measurables/bottom_row.d.ts +9 -3
  167. package/core/renderers/measurables/connection.d.ts +2 -0
  168. package/core/renderers/measurables/external_value_input.d.ts +2 -1
  169. package/core/renderers/measurables/field.d.ts +2 -1
  170. package/core/renderers/measurables/hat.d.ts +2 -1
  171. package/core/renderers/measurables/icon.d.ts +4 -1
  172. package/core/renderers/measurables/in_row_spacer.d.ts +2 -1
  173. package/core/renderers/measurables/inline_input.d.ts +2 -1
  174. package/core/renderers/measurables/input_connection.d.ts +2 -0
  175. package/core/renderers/measurables/input_row.d.ts +4 -1
  176. package/core/renderers/measurables/jagged_edge.d.ts +2 -1
  177. package/core/renderers/measurables/next_connection.d.ts +2 -1
  178. package/core/renderers/measurables/output_connection.d.ts +2 -1
  179. package/core/renderers/measurables/previous_connection.d.ts +2 -1
  180. package/core/renderers/measurables/round_corner.d.ts +2 -1
  181. package/core/renderers/measurables/row.d.ts +30 -8
  182. package/core/renderers/measurables/spacer_row.d.ts +2 -1
  183. package/core/renderers/measurables/square_corner.d.ts +2 -1
  184. package/core/renderers/measurables/statement_input.d.ts +2 -1
  185. package/core/renderers/measurables/top_row.d.ts +7 -4
  186. package/core/renderers/measurables/types.d.ts +54 -25
  187. package/core/renderers/minimalist/constants.d.ts +2 -0
  188. package/core/renderers/minimalist/drawer.d.ts +2 -0
  189. package/core/renderers/minimalist/info.d.ts +5 -1
  190. package/core/renderers/minimalist/minimalist.d.ts +2 -1
  191. package/core/renderers/minimalist/renderer.d.ts +8 -3
  192. package/core/renderers/thrasos/info.d.ts +5 -4
  193. package/core/renderers/thrasos/renderer.d.ts +4 -1
  194. package/core/renderers/thrasos/thrasos.d.ts +2 -1
  195. package/core/renderers/zelos/constants.d.ts +31 -44
  196. package/core/renderers/zelos/drawer.d.ts +3 -0
  197. package/core/renderers/zelos/info.d.ts +10 -5
  198. package/core/renderers/zelos/marker_svg.d.ts +5 -0
  199. package/core/renderers/zelos/measurables/bottom_row.d.ts +2 -0
  200. package/core/renderers/zelos/measurables/inputs.d.ts +2 -1
  201. package/core/renderers/zelos/measurables/row_elements.d.ts +2 -0
  202. package/core/renderers/zelos/measurables/top_row.d.ts +2 -0
  203. package/core/renderers/zelos/path_object.d.ts +9 -2
  204. package/core/renderers/zelos/renderer.d.ts +14 -6
  205. package/core/renderers/zelos/zelos.d.ts +3 -2
  206. package/core/scrollbar.d.ts +41 -9
  207. package/core/scrollbar_pair.d.ts +20 -6
  208. package/core/serialization/blocks.d.ts +10 -4
  209. package/core/serialization/exceptions.d.ts +5 -0
  210. package/core/serialization/priorities.d.ts +3 -0
  211. package/core/serialization/registry.d.ts +3 -0
  212. package/core/serialization/variables.d.ts +2 -0
  213. package/core/serialization/workspaces.d.ts +4 -1
  214. package/core/shortcut_items.d.ts +10 -0
  215. package/core/shortcut_registry.d.ts +25 -9
  216. package/core/sprites.d.ts +2 -4
  217. package/core/theme/classic.d.ts +2 -0
  218. package/core/theme/themes.d.ts +1 -0
  219. package/core/theme/zelos.d.ts +2 -0
  220. package/core/theme.d.ts +41 -30
  221. package/core/theme_manager.d.ts +10 -1
  222. package/core/toolbox/category.d.ts +60 -32
  223. package/core/toolbox/collapsible_category.d.ts +10 -3
  224. package/core/toolbox/separator.d.ts +4 -1
  225. package/core/toolbox/toolbox.d.ts +71 -23
  226. package/core/toolbox/toolbox_item.d.ts +17 -7
  227. package/core/tooltip.d.ts +22 -1
  228. package/core/touch.d.ts +18 -6
  229. package/core/touch_gesture.d.ts +19 -4
  230. package/core/trashcan.d.ts +27 -6
  231. package/core/utils/aria.d.ts +4 -0
  232. package/core/utils/array.d.ts +4 -2
  233. package/core/utils/colour.d.ts +24 -13
  234. package/core/utils/coordinate.d.ts +19 -9
  235. package/core/utils/deprecation.d.ts +6 -4
  236. package/core/utils/dom.d.ts +37 -18
  237. package/core/utils/idgenerator.d.ts +14 -4
  238. package/core/utils/keycodes.d.ts +1 -0
  239. package/core/utils/math.d.ts +7 -3
  240. package/core/utils/metrics.d.ts +1 -0
  241. package/core/utils/object.d.ts +7 -2
  242. package/core/utils/parsing.d.ts +9 -4
  243. package/core/utils/rect.d.ts +5 -3
  244. package/core/utils/sentinel.d.ts +2 -0
  245. package/core/utils/size.d.ts +4 -2
  246. package/core/utils/string.d.ts +13 -6
  247. package/core/utils/style.d.ts +14 -33
  248. package/core/utils/svg.d.ts +5 -2
  249. package/core/utils/svg_math.d.ts +15 -7
  250. package/core/utils/svg_paths.d.ts +20 -10
  251. package/core/utils/toolbox.d.ts +26 -5
  252. package/core/utils/useragent.d.ts +1 -12
  253. package/core/utils/xml.d.ts +13 -5
  254. package/core/utils.d.ts +43 -21
  255. package/core/variable_map.d.ts +26 -9
  256. package/core/variable_model.d.ts +5 -2
  257. package/core/variables.d.ts +33 -18
  258. package/core/variables_dynamic.d.ts +25 -5
  259. package/core/warning.d.ts +8 -3
  260. package/core/widgetdiv.d.ts +15 -6
  261. package/core/workspace.d.ts +80 -30
  262. package/core/workspace_audio.d.ts +6 -0
  263. package/core/workspace_comment.d.ts +33 -11
  264. package/core/workspace_comment_svg.d.ts +52 -9
  265. package/core/workspace_drag_surface_svg.d.ts +20 -14
  266. package/core/workspace_dragger.d.ts +6 -0
  267. package/core/workspace_svg.d.ts +174 -62
  268. package/core/xml.d.ts +26 -11
  269. package/core/zoom_controls.d.ts +17 -7
  270. package/core-browser.js +0 -6
  271. package/core.d.ts +0 -5
  272. package/core.js +0 -6
  273. package/dart.d.ts +1 -7
  274. package/dart_compressed.js.map +1 -1
  275. package/index.d.ts +2 -6
  276. package/javascript.d.ts +1 -7
  277. package/javascript_compressed.js.map +1 -1
  278. package/lua.d.ts +1 -7
  279. package/lua_compressed.js.map +1 -1
  280. package/msg/ab.d.ts +8 -0
  281. package/msg/ace.d.ts +8 -0
  282. package/msg/af.d.ts +8 -0
  283. package/msg/am.d.ts +8 -0
  284. package/msg/ar.d.ts +8 -0
  285. package/msg/ast.d.ts +8 -0
  286. package/msg/az.d.ts +8 -0
  287. package/msg/ba.d.ts +8 -0
  288. package/msg/bcc.d.ts +8 -0
  289. package/msg/be-tarask.d.ts +8 -0
  290. package/msg/be.d.ts +8 -0
  291. package/msg/bg.d.ts +8 -0
  292. package/msg/bn.d.ts +8 -0
  293. package/msg/br.d.ts +8 -0
  294. package/msg/bs.d.ts +8 -0
  295. package/msg/ca.d.ts +8 -0
  296. package/msg/cdo.d.ts +8 -0
  297. package/msg/constants.d.ts +16 -0
  298. package/msg/cs.d.ts +8 -0
  299. package/msg/da.d.ts +8 -0
  300. package/msg/de.d.ts +8 -0
  301. package/msg/diq.d.ts +8 -0
  302. package/msg/dty.d.ts +8 -0
  303. package/msg/ee.d.ts +8 -0
  304. package/msg/el.d.ts +8 -0
  305. package/msg/en-gb.d.ts +8 -0
  306. package/msg/en.d.ts +8 -0
  307. package/msg/eo.d.ts +8 -0
  308. package/msg/es.d.ts +8 -0
  309. package/msg/et.d.ts +8 -0
  310. package/msg/eu.d.ts +8 -0
  311. package/msg/fa.d.ts +8 -0
  312. package/msg/fi.d.ts +8 -0
  313. package/msg/fo.d.ts +8 -0
  314. package/msg/fr.d.ts +8 -0
  315. package/msg/frr.d.ts +8 -0
  316. package/msg/gl.d.ts +8 -0
  317. package/msg/gn.d.ts +8 -0
  318. package/msg/gor.d.ts +8 -0
  319. package/msg/ha.d.ts +8 -0
  320. package/msg/hak.d.ts +8 -0
  321. package/msg/he.d.ts +8 -0
  322. package/msg/hi.d.ts +8 -0
  323. package/msg/hr.d.ts +8 -0
  324. package/msg/hrx.d.ts +8 -0
  325. package/msg/hu.d.ts +8 -0
  326. package/msg/hy.d.ts +8 -0
  327. package/msg/ia.d.ts +8 -0
  328. package/msg/id.d.ts +8 -0
  329. package/msg/ig.d.ts +8 -0
  330. package/msg/inh.d.ts +8 -0
  331. package/msg/is.d.ts +8 -0
  332. package/msg/it.d.ts +8 -0
  333. package/msg/ja.d.ts +8 -0
  334. package/msg/ka.d.ts +8 -0
  335. package/msg/kab.d.ts +8 -0
  336. package/msg/kbd-cyrl.d.ts +8 -0
  337. package/msg/km.d.ts +8 -0
  338. package/msg/kn.d.ts +8 -0
  339. package/msg/ko.d.ts +8 -0
  340. package/msg/ksh.d.ts +8 -0
  341. package/msg/ku-latn.d.ts +8 -0
  342. package/msg/ky.d.ts +8 -0
  343. package/msg/la.d.ts +8 -0
  344. package/msg/lb.d.ts +8 -0
  345. package/msg/lki.d.ts +8 -0
  346. package/msg/lo.d.ts +8 -0
  347. package/msg/lrc.d.ts +8 -0
  348. package/msg/lt.d.ts +8 -0
  349. package/msg/lv.d.ts +8 -0
  350. package/msg/mg.d.ts +8 -0
  351. package/msg/mk.d.ts +8 -0
  352. package/msg/ml.d.ts +8 -0
  353. package/msg/mnw.d.ts +8 -0
  354. package/msg/ms.d.ts +8 -0
  355. package/msg/msg.d.ts +429 -432
  356. package/msg/my.d.ts +8 -0
  357. package/msg/mzn.d.ts +8 -0
  358. package/msg/nb.d.ts +8 -0
  359. package/msg/ne.d.ts +8 -0
  360. package/msg/nl.d.ts +8 -0
  361. package/msg/oc.d.ts +8 -0
  362. package/msg/olo.d.ts +8 -0
  363. package/msg/pa.d.ts +8 -0
  364. package/msg/pl.d.ts +8 -0
  365. package/msg/pms.d.ts +8 -0
  366. package/msg/ps.d.ts +8 -0
  367. package/msg/pt-br.d.ts +8 -0
  368. package/msg/pt.d.ts +8 -0
  369. package/msg/qqq.d.ts +16 -0
  370. package/msg/ro.d.ts +8 -0
  371. package/msg/ru.d.ts +8 -0
  372. package/msg/sc.d.ts +8 -0
  373. package/msg/sco.d.ts +8 -0
  374. package/msg/sd.d.ts +8 -0
  375. package/msg/shn.d.ts +8 -0
  376. package/msg/si.d.ts +8 -0
  377. package/msg/sk.d.ts +8 -0
  378. package/msg/skr-arab.d.ts +8 -0
  379. package/msg/sl.d.ts +8 -0
  380. package/msg/smn.d.ts +8 -0
  381. package/msg/sq.d.ts +8 -0
  382. package/msg/sr-latn.d.ts +8 -0
  383. package/msg/sr.d.ts +8 -0
  384. package/msg/sv.d.ts +8 -0
  385. package/msg/sw.d.ts +8 -0
  386. package/msg/synonyms.d.ts +16 -0
  387. package/msg/ta.d.ts +8 -0
  388. package/msg/tcy.d.ts +8 -0
  389. package/msg/te.d.ts +8 -0
  390. package/msg/th.d.ts +8 -0
  391. package/msg/ti.d.ts +8 -0
  392. package/msg/tl.d.ts +8 -0
  393. package/msg/tlh.d.ts +8 -0
  394. package/msg/tr.d.ts +8 -0
  395. package/msg/ug-arab.d.ts +8 -0
  396. package/msg/uk.d.ts +8 -0
  397. package/msg/ur.d.ts +8 -0
  398. package/msg/uz.d.ts +8 -0
  399. package/msg/vi.d.ts +8 -0
  400. package/msg/xmf.d.ts +8 -0
  401. package/msg/yo.d.ts +8 -0
  402. package/msg/yue.d.ts +8 -0
  403. package/msg/zgh.d.ts +8 -0
  404. package/msg/zh-hans.d.ts +8 -0
  405. package/msg/zh-hant.d.ts +8 -0
  406. package/package.json +6 -3
  407. package/php.d.ts +1 -7
  408. package/php_compressed.js.map +1 -1
  409. package/python.d.ts +1 -7
  410. package/python_compressed.js.map +1 -1
  411. package/blocks/blocks.js +0 -48
  412. package/blocks/colour.js +0 -121
  413. package/blocks/lists.js +0 -996
  414. package/blocks/logic.js +0 -665
  415. package/blocks/loops.js +0 -375
  416. package/blocks/math.js +0 -594
  417. package/blocks/procedures.js +0 -1196
  418. package/blocks/text.js +0 -1000
  419. package/blocks/variables.js +0 -176
  420. package/blocks/variables_dynamic.js +0 -192
  421. package/core/any_aliases.ts +0 -1
  422. package/core/block.ts +0 -2102
  423. package/core/block_animations.ts +0 -202
  424. package/core/block_drag_surface.ts +0 -237
  425. package/core/block_dragger.ts +0 -447
  426. package/core/block_svg.ts +0 -1758
  427. package/core/blockly.js +0 -890
  428. package/core/blockly.ts +0 -749
  429. package/core/blockly_options.ts +0 -81
  430. package/core/blocks.ts +0 -29
  431. package/core/browser_events.ts +0 -289
  432. package/core/bubble.ts +0 -892
  433. package/core/bubble_dragger.ts +0 -229
  434. package/core/bump_objects.ts +0 -182
  435. package/core/clipboard.ts +0 -91
  436. package/core/comment.ts +0 -398
  437. package/core/common.ts +0 -288
  438. package/core/component_manager.ts +0 -211
  439. package/core/config.ts +0 -80
  440. package/core/connection.ts +0 -692
  441. package/core/connection_checker.ts +0 -301
  442. package/core/connection_db.ts +0 -289
  443. package/core/connection_type.ts +0 -32
  444. package/core/constants.ts +0 -29
  445. package/core/contextmenu.ts +0 -363
  446. package/core/contextmenu_items.ts +0 -576
  447. package/core/contextmenu_registry.ts +0 -179
  448. package/core/css.ts +0 -560
  449. package/core/delete_area.ts +0 -82
  450. package/core/dialog.ts +0 -127
  451. package/core/drag_target.ts +0 -94
  452. package/core/dropdowndiv.ts +0 -683
  453. package/core/events/events.ts +0 -123
  454. package/core/events/events_abstract.ts +0 -112
  455. package/core/events/events_block_base.ts +0 -65
  456. package/core/events/events_block_change.ts +0 -176
  457. package/core/events/events_block_create.ts +0 -114
  458. package/core/events/events_block_delete.ts +0 -126
  459. package/core/events/events_block_drag.ts +0 -82
  460. package/core/events/events_block_move.ts +0 -206
  461. package/core/events/events_bubble_open.ts +0 -82
  462. package/core/events/events_click.ts +0 -84
  463. package/core/events/events_comment_base.ts +0 -107
  464. package/core/events/events_comment_change.ts +0 -108
  465. package/core/events/events_comment_create.ts +0 -82
  466. package/core/events/events_comment_delete.ts +0 -77
  467. package/core/events/events_comment_move.ts +0 -154
  468. package/core/events/events_marker_move.ts +0 -99
  469. package/core/events/events_selected.ts +0 -78
  470. package/core/events/events_theme_change.ts +0 -67
  471. package/core/events/events_toolbox_item_select.ts +0 -79
  472. package/core/events/events_trashcan_open.ts +0 -68
  473. package/core/events/events_ui.ts +0 -89
  474. package/core/events/events_ui_base.ts +0 -54
  475. package/core/events/events_var_base.ts +0 -65
  476. package/core/events/events_var_create.ts +0 -88
  477. package/core/events/events_var_delete.ts +0 -88
  478. package/core/events/events_var_rename.ts +0 -89
  479. package/core/events/events_viewport.ts +0 -100
  480. package/core/events/utils.ts +0 -529
  481. package/core/events/workspace_events.ts +0 -86
  482. package/core/extensions.ts +0 -504
  483. package/core/field.ts +0 -1206
  484. package/core/field_angle.ts +0 -563
  485. package/core/field_checkbox.ts +0 -243
  486. package/core/field_colour.ts +0 -632
  487. package/core/field_dropdown.ts +0 -773
  488. package/core/field_image.ts +0 -282
  489. package/core/field_label.ts +0 -152
  490. package/core/field_label_serializable.ts +0 -76
  491. package/core/field_multilineinput.ts +0 -466
  492. package/core/field_number.ts +0 -327
  493. package/core/field_registry.ts +0 -87
  494. package/core/field_textinput.ts +0 -591
  495. package/core/field_variable.ts +0 -545
  496. package/core/flyout_base.ts +0 -1165
  497. package/core/flyout_button.ts +0 -292
  498. package/core/flyout_horizontal.ts +0 -381
  499. package/core/flyout_metrics_manager.ts +0 -94
  500. package/core/flyout_vertical.ts +0 -384
  501. package/core/generator.ts +0 -539
  502. package/core/gesture.ts +0 -946
  503. package/core/grid.ts +0 -192
  504. package/core/icon.ts +0 -189
  505. package/core/inject.ts +0 -390
  506. package/core/input.ts +0 -309
  507. package/core/input_types.ts +0 -32
  508. package/core/insertion_marker_manager.ts +0 -788
  509. package/core/interfaces/i_ast_node_location.ts +0 -23
  510. package/core/interfaces/i_ast_node_location_svg.ts +0 -37
  511. package/core/interfaces/i_ast_node_location_with_block.ts +0 -38
  512. package/core/interfaces/i_autohideable.ts +0 -34
  513. package/core/interfaces/i_block_dragger.ts +0 -67
  514. package/core/interfaces/i_bounded_element.ts +0 -42
  515. package/core/interfaces/i_bubble.ts +0 -88
  516. package/core/interfaces/i_collapsible_toolbox_item.ts +0 -47
  517. package/core/interfaces/i_component.ts +0 -32
  518. package/core/interfaces/i_connection_checker.ts +0 -102
  519. package/core/interfaces/i_contextmenu.ts +0 -26
  520. package/core/interfaces/i_copyable.ts +0 -40
  521. package/core/interfaces/i_deletable.ts +0 -29
  522. package/core/interfaces/i_delete_area.ts +0 -46
  523. package/core/interfaces/i_drag_target.ts +0 -84
  524. package/core/interfaces/i_draggable.ts +0 -25
  525. package/core/interfaces/i_flyout.ts +0 -186
  526. package/core/interfaces/i_keyboard_accessible.ts +0 -35
  527. package/core/interfaces/i_metrics_manager.ts +0 -151
  528. package/core/interfaces/i_movable.ts +0 -29
  529. package/core/interfaces/i_positionable.ts +0 -50
  530. package/core/interfaces/i_registrable.ts +0 -25
  531. package/core/interfaces/i_registrable_field.ts +0 -31
  532. package/core/interfaces/i_selectable.ts +0 -34
  533. package/core/interfaces/i_selectable_toolbox_item.ts +0 -64
  534. package/core/interfaces/i_serializer.ts +0 -65
  535. package/core/interfaces/i_styleable.ts +0 -35
  536. package/core/interfaces/i_toolbox.ts +0 -127
  537. package/core/interfaces/i_toolbox_item.ts +0 -84
  538. package/core/internal_constants.ts +0 -67
  539. package/core/keyboard_nav/ast_node.ts +0 -717
  540. package/core/keyboard_nav/basic_cursor.ts +0 -214
  541. package/core/keyboard_nav/cursor.ts +0 -134
  542. package/core/keyboard_nav/marker.ts +0 -115
  543. package/core/keyboard_nav/tab_navigate_cursor.ts +0 -48
  544. package/core/main.js +0 -303
  545. package/core/marker_manager.ts +0 -181
  546. package/core/menu.ts +0 -449
  547. package/core/menuitem.ts +0 -240
  548. package/core/metrics_manager.ts +0 -456
  549. package/core/msg.ts +0 -20
  550. package/core/mutator.ts +0 -560
  551. package/core/names.ts +0 -267
  552. package/core/options.ts +0 -365
  553. package/core/positionable_helpers.ts +0 -181
  554. package/core/procedures.ts +0 -443
  555. package/core/registry.ts +0 -339
  556. package/core/rendered_connection.ts +0 -568
  557. package/core/renderers/common/block_rendering.ts +0 -164
  558. package/core/renderers/common/constants.ts +0 -1124
  559. package/core/renderers/common/debug.ts +0 -61
  560. package/core/renderers/common/debugger.ts +0 -433
  561. package/core/renderers/common/drawer.ts +0 -450
  562. package/core/renderers/common/i_path_object.ts +0 -161
  563. package/core/renderers/common/info.ts +0 -718
  564. package/core/renderers/common/marker_svg.ts +0 -680
  565. package/core/renderers/common/path_object.ts +0 -272
  566. package/core/renderers/common/renderer.ts +0 -271
  567. package/core/renderers/geras/constants.ts +0 -61
  568. package/core/renderers/geras/drawer.ts +0 -176
  569. package/core/renderers/geras/geras.ts +0 -37
  570. package/core/renderers/geras/highlight_constants.ts +0 -337
  571. package/core/renderers/geras/highlighter.ts +0 -306
  572. package/core/renderers/geras/info.ts +0 -450
  573. package/core/renderers/geras/measurables/inline_input.ts +0 -51
  574. package/core/renderers/geras/measurables/statement_input.ts +0 -50
  575. package/core/renderers/geras/path_object.ts +0 -138
  576. package/core/renderers/geras/renderer.ts +0 -126
  577. package/core/renderers/measurables/base.ts +0 -53
  578. package/core/renderers/measurables/bottom_row.ts +0 -120
  579. package/core/renderers/measurables/connection.ts +0 -52
  580. package/core/renderers/measurables/external_value_input.ts +0 -65
  581. package/core/renderers/measurables/field.ts +0 -63
  582. package/core/renderers/measurables/hat.ts +0 -48
  583. package/core/renderers/measurables/icon.ts +0 -54
  584. package/core/renderers/measurables/in_row_spacer.ts +0 -44
  585. package/core/renderers/measurables/inline_input.ts +0 -76
  586. package/core/renderers/measurables/input_connection.ts +0 -66
  587. package/core/renderers/measurables/input_row.ts +0 -82
  588. package/core/renderers/measurables/jagged_edge.ts +0 -43
  589. package/core/renderers/measurables/next_connection.ts +0 -47
  590. package/core/renderers/measurables/output_connection.ts +0 -56
  591. package/core/renderers/measurables/previous_connection.ts +0 -47
  592. package/core/renderers/measurables/round_corner.ts +0 -49
  593. package/core/renderers/measurables/row.ts +0 -225
  594. package/core/renderers/measurables/spacer_row.ts +0 -55
  595. package/core/renderers/measurables/square_corner.ts +0 -47
  596. package/core/renderers/measurables/statement_input.ts +0 -55
  597. package/core/renderers/measurables/top_row.ts +0 -122
  598. package/core/renderers/measurables/types.ts +0 -332
  599. package/core/renderers/minimalist/constants.ts +0 -32
  600. package/core/renderers/minimalist/drawer.ts +0 -38
  601. package/core/renderers/minimalist/info.ts +0 -52
  602. package/core/renderers/minimalist/minimalist.ts +0 -22
  603. package/core/renderers/minimalist/renderer.ts +0 -71
  604. package/core/renderers/thrasos/info.ts +0 -338
  605. package/core/renderers/thrasos/renderer.ts +0 -48
  606. package/core/renderers/thrasos/thrasos.ts +0 -20
  607. package/core/renderers/zelos/constants.ts +0 -858
  608. package/core/renderers/zelos/drawer.ts +0 -228
  609. package/core/renderers/zelos/info.ts +0 -593
  610. package/core/renderers/zelos/marker_svg.ts +0 -151
  611. package/core/renderers/zelos/measurables/bottom_row.ts +0 -53
  612. package/core/renderers/zelos/measurables/inputs.ts +0 -56
  613. package/core/renderers/zelos/measurables/row_elements.ts +0 -45
  614. package/core/renderers/zelos/measurables/top_row.ts +0 -58
  615. package/core/renderers/zelos/path_object.ts +0 -215
  616. package/core/renderers/zelos/renderer.ts +0 -142
  617. package/core/renderers/zelos/zelos.ts +0 -39
  618. package/core/scrollbar.ts +0 -870
  619. package/core/scrollbar_pair.ts +0 -321
  620. package/core/serialization/blocks.ts +0 -706
  621. package/core/serialization/exceptions.ts +0 -98
  622. package/core/serialization/priorities.ts +0 -32
  623. package/core/serialization/registry.ts +0 -43
  624. package/core/serialization/variables.ts +0 -96
  625. package/core/serialization/workspaces.ts +0 -106
  626. package/core/shortcut_items.ts +0 -266
  627. package/core/shortcut_registry.ts +0 -355
  628. package/core/sprites.ts +0 -29
  629. package/core/theme/classic.ts +0 -54
  630. package/core/theme/themes.ts +0 -22
  631. package/core/theme/zelos.ts +0 -91
  632. package/core/theme.ts +0 -221
  633. package/core/theme_manager.ts +0 -186
  634. package/core/toolbox/category.ts +0 -679
  635. package/core/toolbox/collapsible_category.ts +0 -273
  636. package/core/toolbox/separator.ts +0 -105
  637. package/core/toolbox/toolbox.ts +0 -1044
  638. package/core/toolbox/toolbox_item.ts +0 -147
  639. package/core/tooltip.ts +0 -463
  640. package/core/touch.ts +0 -306
  641. package/core/touch_gesture.ts +0 -295
  642. package/core/trashcan.ts +0 -671
  643. package/core/utils/aria.ts +0 -160
  644. package/core/utils/array.ts +0 -32
  645. package/core/utils/colour.ts +0 -276
  646. package/core/utils/coordinate.ts +0 -124
  647. package/core/utils/deprecation.ts +0 -41
  648. package/core/utils/dom.ts +0 -408
  649. package/core/utils/idgenerator.ts +0 -80
  650. package/core/utils/keycodes.ts +0 -169
  651. package/core/utils/math.ts +0 -61
  652. package/core/utils/metrics.ts +0 -97
  653. package/core/utils/object.ts +0 -95
  654. package/core/utils/parsing.ts +0 -261
  655. package/core/utils/rect.ts +0 -62
  656. package/core/utils/sentinel.ts +0 -23
  657. package/core/utils/size.ts +0 -51
  658. package/core/utils/string.ts +0 -308
  659. package/core/utils/style.ts +0 -306
  660. package/core/utils/svg.ts +0 -88
  661. package/core/utils/svg_math.ts +0 -269
  662. package/core/utils/svg_paths.ts +0 -140
  663. package/core/utils/toolbox.ts +0 -433
  664. package/core/utils/useragent.ts +0 -135
  665. package/core/utils/xml.ts +0 -97
  666. package/core/utils.ts +0 -428
  667. package/core/variable_map.ts +0 -392
  668. package/core/variable_model.ts +0 -82
  669. package/core/variables.ts +0 -596
  670. package/core/variables_dynamic.ts +0 -133
  671. package/core/warning.ts +0 -161
  672. package/core/widgetdiv.ts +0 -257
  673. package/core/workspace.ts +0 -801
  674. package/core/workspace_audio.ts +0 -156
  675. package/core/workspace_comment.ts +0 -398
  676. package/core/workspace_comment_svg.ts +0 -1127
  677. package/core/workspace_drag_surface_svg.ts +0 -187
  678. package/core/workspace_dragger.ts +0 -104
  679. package/core/workspace_svg.ts +0 -2655
  680. package/core/xml.ts +0 -1023
  681. package/core/zoom_controls.ts +0 -441
  682. package/generators/dart/all.js +0 -27
  683. package/generators/dart/colour.js +0 -105
  684. package/generators/dart/lists.js +0 -431
  685. package/generators/dart/logic.js +0 -123
  686. package/generators/dart/loops.js +0 -161
  687. package/generators/dart/math.js +0 -446
  688. package/generators/dart/procedures.js +0 -105
  689. package/generators/dart/text.js +0 -338
  690. package/generators/dart/variables.js +0 -32
  691. package/generators/dart/variables_dynamic.js +0 -21
  692. package/generators/dart.js +0 -303
  693. package/generators/javascript/all.js +0 -27
  694. package/generators/javascript/colour.js +0 -85
  695. package/generators/javascript/lists.js +0 -405
  696. package/generators/javascript/logic.js +0 -127
  697. package/generators/javascript/loops.js +0 -180
  698. package/generators/javascript/math.js +0 -401
  699. package/generators/javascript/procedures.js +0 -110
  700. package/generators/javascript/text.js +0 -371
  701. package/generators/javascript/variables.js +0 -32
  702. package/generators/javascript/variables_dynamic.js +0 -21
  703. package/generators/javascript.js +0 -322
  704. package/generators/lua/all.js +0 -27
  705. package/generators/lua/colour.js +0 -71
  706. package/generators/lua/lists.js +0 -348
  707. package/generators/lua/logic.js +0 -112
  708. package/generators/lua/loops.js +0 -168
  709. package/generators/lua/math.js +0 -406
  710. package/generators/lua/procedures.js +0 -106
  711. package/generators/lua/text.js +0 -327
  712. package/generators/lua/variables.js +0 -31
  713. package/generators/lua/variables_dynamic.js +0 -21
  714. package/generators/lua.js +0 -206
  715. package/generators/php/all.js +0 -27
  716. package/generators/php/colour.js +0 -81
  717. package/generators/php/lists.js +0 -481
  718. package/generators/php/logic.js +0 -119
  719. package/generators/php/loops.js +0 -161
  720. package/generators/php/math.js +0 -349
  721. package/generators/php/procedures.js +0 -125
  722. package/generators/php/text.js +0 -255
  723. package/generators/php/variables.js +0 -32
  724. package/generators/php/variables_dynamic.js +0 -21
  725. package/generators/php.js +0 -303
  726. package/generators/python/all.js +0 -27
  727. package/generators/python/colour.js +0 -67
  728. package/generators/python/lists.js +0 -346
  729. package/generators/python/logic.js +0 -120
  730. package/generators/python/loops.js +0 -206
  731. package/generators/python/math.js +0 -373
  732. package/generators/python/procedures.js +0 -129
  733. package/generators/python/text.js +0 -291
  734. package/generators/python/variables.js +0 -32
  735. package/generators/python/variables_dynamic.js +0 -21
  736. package/generators/python.js +0 -333
@@ -1,2655 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2014 Google LLC
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
-
7
- /**
8
- * @fileoverview Object representing a workspace rendered as SVG.
9
- */
10
-
11
- /**
12
- * Object representing a workspace rendered as SVG.
13
- * @class
14
- */
15
- import * as goog from '../closure/goog/goog.js';
16
- goog.declareModuleId('Blockly.WorkspaceSvg');
17
-
18
- /* eslint-disable-next-line no-unused-vars */
19
- // Unused import preserved for side-effects. Remove if unneeded.
20
- // import './procedures.js';
21
- /* eslint-disable-next-line no-unused-vars */
22
- // Unused import preserved for side-effects. Remove if unneeded.
23
- // import './variables.js';
24
- /* eslint-disable-next-line no-unused-vars */
25
- // Unused import preserved for side-effects. Remove if unneeded.
26
- // import './variables_dynamic.js';
27
- /* eslint-disable-next-line no-unused-vars */
28
- // Unused import preserved for side-effects. Remove if unneeded.
29
- // import './rendered_connection.js';
30
- /* eslint-disable-next-line no-unused-vars */
31
- // Unused import preserved for side-effects. Remove if unneeded.
32
- // import './zoom_controls.js';
33
- // Unused import preserved for side-effects. Remove if unneeded.
34
- import './events/events_block_create.js';
35
- // Unused import preserved for side-effects. Remove if unneeded.
36
- import './events/events_theme_change.js';
37
- // Unused import preserved for side-effects. Remove if unneeded.
38
- import './events/events_viewport.js';
39
- // Unused import preserved for side-effects. Remove if unneeded.
40
- // import './metrics_manager.js';
41
- // Unused import preserved for side-effects. Remove if unneeded.
42
- // import './msg.js';
43
-
44
- import type {Block} from './block.js';
45
- import type {BlockDragSurfaceSvg} from './block_drag_surface.js';
46
- import type {BlockSvg} from './block_svg.js';
47
- import type {BlocklyOptions} from './blockly_options.js';
48
- import * as browserEvents from './browser_events.js';
49
- import * as common from './common.js';
50
- import {ComponentManager} from './component_manager.js';
51
- import {config} from './config.js';
52
- import {ConnectionDB} from './connection_db.js';
53
- import * as ContextMenu from './contextmenu.js';
54
- import {ContextMenuRegistry} from './contextmenu_registry.js';
55
- import * as dropDownDiv from './dropdowndiv.js';
56
- import * as eventUtils from './events/utils.js';
57
- import type {FlyoutButton} from './flyout_button.js';
58
- import {Gesture} from './gesture.js';
59
- import {Grid} from './grid.js';
60
- import type {IASTNodeLocationSvg} from './interfaces/i_ast_node_location_svg.js';
61
- import type {IBoundedElement} from './interfaces/i_bounded_element.js';
62
- import type {ICopyable} from './interfaces/i_copyable.js';
63
- import type {IDragTarget} from './interfaces/i_drag_target.js';
64
- import type {IFlyout} from './interfaces/i_flyout.js';
65
- import type {IMetricsManager} from './interfaces/i_metrics_manager.js';
66
- import type {IToolbox} from './interfaces/i_toolbox.js';
67
- import type {Cursor} from './keyboard_nav/cursor.js';
68
- import type {Marker} from './keyboard_nav/marker.js';
69
- import {MarkerManager} from './marker_manager.js';
70
- import {Options} from './options.js';
71
- import * as Procedures from './procedures.js';
72
- import * as registry from './registry.js';
73
- import * as blockRendering from './renderers/common/block_rendering.js';
74
- import type {Renderer} from './renderers/common/renderer.js';
75
- import type {ScrollbarPair} from './scrollbar_pair.js';
76
- import * as blocks from './serialization/blocks.js';
77
- import type {Theme} from './theme.js';
78
- import {Classic} from './theme/classic.js';
79
- import {ThemeManager} from './theme_manager.js';
80
- import * as Tooltip from './tooltip.js';
81
- import {TouchGesture} from './touch_gesture.js';
82
- import type {Trashcan} from './trashcan.js';
83
- import * as utils from './utils.js';
84
- import * as arrayUtils from './utils/array.js';
85
- import {Coordinate} from './utils/coordinate.js';
86
- import * as dom from './utils/dom.js';
87
- import type {Metrics} from './utils/metrics.js';
88
- import {Rect} from './utils/rect.js';
89
- import {Size} from './utils/size.js';
90
- import {Svg} from './utils/svg.js';
91
- import * as svgMath from './utils/svg_math.js';
92
- import * as toolbox from './utils/toolbox.js';
93
- import * as userAgent from './utils/useragent.js';
94
- import type {VariableModel} from './variable_model.js';
95
- import * as Variables from './variables.js';
96
- import * as VariablesDynamic from './variables_dynamic.js';
97
- import * as WidgetDiv from './widgetdiv.js';
98
- import {Workspace} from './workspace.js';
99
- import {WorkspaceAudio} from './workspace_audio.js';
100
- import {WorkspaceComment} from './workspace_comment.js';
101
- import {WorkspaceCommentSvg} from './workspace_comment_svg.js';
102
- import type {WorkspaceDragSurfaceSvg} from './workspace_drag_surface_svg.js';
103
- import * as Xml from './xml.js';
104
- import {ZoomControls} from './zoom_controls.js';
105
-
106
-
107
- /** Margin around the top/bottom/left/right after a zoomToFit call. */
108
- const ZOOM_TO_FIT_MARGIN = 20;
109
-
110
- /**
111
- * Class for a workspace. This is an onscreen area with optional trashcan,
112
- * scrollbars, bubbles, and dragging.
113
- * @alias Blockly.WorkspaceSvg
114
- */
115
- export class WorkspaceSvg extends Workspace implements IASTNodeLocationSvg {
116
- /**
117
- * A wrapper function called when a resize event occurs.
118
- * You can pass the result to `eventHandling.unbind`.
119
- */
120
- private resizeHandlerWrapper_: browserEvents.Data|null = null;
121
-
122
- /**
123
- * The render status of an SVG workspace.
124
- * Returns `false` for headless workspaces and true for instances of
125
- * `WorkspaceSvg`.
126
- */
127
- override rendered = true;
128
-
129
- /**
130
- * Whether the workspace is visible. False if the workspace has been hidden
131
- * by calling `setVisible(false)`.
132
- */
133
- private isVisible_ = true;
134
-
135
- /**
136
- * Whether this workspace has resizes enabled.
137
- * Disable during batch operations for a performance improvement.
138
- */
139
- private resizesEnabled_ = true;
140
-
141
- /**
142
- * Current horizontal scrolling offset in pixel units, relative to the
143
- * workspace origin.
144
- *
145
- * It is useful to think about a view, and a canvas moving beneath that
146
- * view. As the canvas moves right, this value becomes more positive, and
147
- * the view is now "seeing" the left side of the canvas. As the canvas moves
148
- * left, this value becomes more negative, and the view is now "seeing" the
149
- * right side of the canvas.
150
- *
151
- * The confusing thing about this value is that it does not, and must not
152
- * include the absoluteLeft offset. This is because it is used to calculate
153
- * the viewLeft value.
154
- *
155
- * The viewLeft is relative to the workspace origin (although in pixel
156
- * units). The workspace origin is the top-left corner of the workspace (at
157
- * least when it is enabled). It is shifted from the top-left of the
158
- * blocklyDiv so as not to be beneath the toolbox.
159
- *
160
- * When the workspace is enabled the viewLeft and workspace origin are at
161
- * the same X location. As the canvas slides towards the right beneath the
162
- * view this value (scrollX) becomes more positive, and the viewLeft becomes
163
- * more negative relative to the workspace origin (imagine the workspace
164
- * origin as a dot on the canvas sliding to the right as the canvas moves).
165
- *
166
- * So if the scrollX were to include the absoluteLeft this would in a way
167
- * "unshift" the workspace origin. This means that the viewLeft would be
168
- * representing the left edge of the blocklyDiv, rather than the left edge
169
- * of the workspace.
170
- */
171
- scrollX = 0;
172
-
173
- /**
174
- * Current vertical scrolling offset in pixel units, relative to the
175
- * workspace origin.
176
- *
177
- * It is useful to think about a view, and a canvas moving beneath that
178
- * view. As the canvas moves down, this value becomes more positive, and the
179
- * view is now "seeing" the upper part of the canvas. As the canvas moves
180
- * up, this value becomes more negative, and the view is "seeing" the lower
181
- * part of the canvas.
182
- *
183
- * This confusing thing about this value is that it does not, and must not
184
- * include the absoluteTop offset. This is because it is used to calculate
185
- * the viewTop value.
186
- *
187
- * The viewTop is relative to the workspace origin (although in pixel
188
- * units). The workspace origin is the top-left corner of the workspace (at
189
- * least when it is enabled). It is shifted from the top-left of the
190
- * blocklyDiv so as not to be beneath the toolbox.
191
- *
192
- * When the workspace is enabled the viewTop and workspace origin are at the
193
- * same Y location. As the canvas slides towards the bottom this value
194
- * (scrollY) becomes more positive, and the viewTop becomes more negative
195
- * relative to the workspace origin (image in the workspace origin as a dot
196
- * on the canvas sliding downwards as the canvas moves).
197
- *
198
- * So if the scrollY were to include the absoluteTop this would in a way
199
- * "unshift" the workspace origin. This means that the viewTop would be
200
- * representing the top edge of the blocklyDiv, rather than the top edge of
201
- * the workspace.
202
- */
203
- scrollY = 0;
204
-
205
- /** Horizontal scroll value when scrolling started in pixel units. */
206
- startScrollX = 0;
207
-
208
- /** Vertical scroll value when scrolling started in pixel units. */
209
- startScrollY = 0;
210
-
211
- /** Distance from mouse to object being dragged. */
212
- // AnyDuringMigration because: Type 'null' is not assignable to type
213
- // 'Coordinate'.
214
- private dragDeltaXY_: Coordinate = null as AnyDuringMigration;
215
-
216
- /** Current scale. */
217
- scale = 1;
218
-
219
- /** Cached scale value. Used to detect changes in viewport. */
220
- private oldScale_ = 1;
221
-
222
- /** Cached viewport top value. Used to detect changes in viewport. */
223
- private oldTop_ = 0;
224
-
225
- /** Cached viewport left value. Used to detect changes in viewport. */
226
- private oldLeft_ = 0;
227
-
228
- /** The workspace's trashcan (if any). */
229
- // AnyDuringMigration because: Type 'null' is not assignable to type
230
- // 'Trashcan'.
231
- trashcan: Trashcan = null as AnyDuringMigration;
232
-
233
- /** This workspace's scrollbars, if they exist. */
234
- // AnyDuringMigration because: Type 'null' is not assignable to type
235
- // 'ScrollbarPair'.
236
- scrollbar: ScrollbarPair = null as AnyDuringMigration;
237
-
238
- /**
239
- * Fixed flyout providing blocks which may be dragged into this workspace.
240
- */
241
- // AnyDuringMigration because: Type 'null' is not assignable to type
242
- // 'IFlyout'.
243
- private flyout_: IFlyout = null as AnyDuringMigration;
244
-
245
- /**
246
- * Category-based toolbox providing blocks which may be dragged into this
247
- * workspace.
248
- */
249
- // AnyDuringMigration because: Type 'null' is not assignable to type
250
- // 'IToolbox'.
251
- private toolbox_: IToolbox = null as AnyDuringMigration;
252
-
253
- /**
254
- * The current gesture in progress on this workspace, if any.
255
- * @internal
256
- */
257
- // AnyDuringMigration because: Type 'null' is not assignable to type
258
- // 'TouchGesture'.
259
- currentGesture_: TouchGesture = null as AnyDuringMigration;
260
-
261
- /** This workspace's surface for dragging blocks, if it exists. */
262
- // AnyDuringMigration because: Type 'null' is not assignable to type
263
- // 'BlockDragSurfaceSvg'.
264
- private readonly blockDragSurface_: BlockDragSurfaceSvg =
265
- null as AnyDuringMigration;
266
-
267
- /** This workspace's drag surface, if it exists. */
268
- // AnyDuringMigration because: Type 'null' is not assignable to type
269
- // 'WorkspaceDragSurfaceSvg'.
270
- private readonly workspaceDragSurface_: WorkspaceDragSurfaceSvg =
271
- null as AnyDuringMigration;
272
-
273
- /**
274
- * Whether to move workspace to the drag surface when it is dragged.
275
- * True if it should move, false if it should be translated directly.
276
- */
277
- private readonly useWorkspaceDragSurface_;
278
-
279
- /**
280
- * Whether the drag surface is actively in use. When true, calls to
281
- * translate will translate the drag surface instead of the translating the
282
- * workspace directly.
283
- * This is set to true in setupDragSurface and to false in resetDragSurface.
284
- */
285
- private isDragSurfaceActive_ = false;
286
-
287
- /**
288
- * The first parent div with 'injectionDiv' in the name, or null if not set.
289
- * Access this with getInjectionDiv.
290
- */
291
- // AnyDuringMigration because: Type 'null' is not assignable to type
292
- // 'Element'.
293
- private injectionDiv_: Element = null as AnyDuringMigration;
294
-
295
- /**
296
- * Last known position of the page scroll.
297
- * This is used to determine whether we have recalculated screen coordinate
298
- * stuff since the page scrolled.
299
- */
300
- // AnyDuringMigration because: Type 'null' is not assignable to type
301
- // 'Coordinate'.
302
- private lastRecordedPageScroll_: Coordinate = null as AnyDuringMigration;
303
-
304
- /**
305
- * Developers may define this function to add custom menu options to the
306
- * workspace's context menu or edit the workspace-created set of menu
307
- * options.
308
- * @param options List of menu options to add to.
309
- * @param e The right-click event that triggered the context menu.
310
- */
311
- configureContextMenu: AnyDuringMigration;
312
-
313
- /**
314
- * In a flyout, the target workspace where blocks should be placed after a
315
- * drag. Otherwise null.
316
- * @internal
317
- */
318
- // AnyDuringMigration because: Type 'null' is not assignable to type
319
- // 'WorkspaceSvg'.
320
- targetWorkspace: WorkspaceSvg = null as AnyDuringMigration;
321
-
322
- /** Inverted screen CTM, for use in mouseToSvg. */
323
- private inverseScreenCTM_: SVGMatrix|null = null;
324
-
325
- /** Inverted screen CTM is dirty, recalculate it. */
326
- private inverseScreenCTMDirty_ = true;
327
- private metricsManager_: IMetricsManager;
328
- /** @internal */
329
- getMetrics: () => Metrics;
330
- /** @internal */
331
- setMetrics: (p1: {x: number, y: number}) => void;
332
- private readonly componentManager_: ComponentManager;
333
-
334
- /**
335
- * List of currently highlighted blocks. Block highlighting is often used
336
- * to visually mark blocks currently being executed.
337
- */
338
- private readonly highlightedBlocks_: BlockSvg[] = [];
339
- private audioManager_: WorkspaceAudio;
340
- private grid_: Grid;
341
- private markerManager_: MarkerManager;
342
- private toolboxCategoryCallbacks_:
343
- {[key: string]: ((p1: WorkspaceSvg) => toolbox.FlyoutDefinition)|null};
344
- private flyoutButtonCallbacks_:
345
- {[key: string]: ((p1: FlyoutButton) => AnyDuringMigration)|null};
346
- protected themeManager_: ThemeManager;
347
- private readonly renderer_: Renderer;
348
-
349
- /** Cached parent SVG. */
350
- // AnyDuringMigration because: Type 'null' is not assignable to type
351
- // 'SVGElement'.
352
- private cachedParentSvg_: SVGElement = null as AnyDuringMigration;
353
-
354
- /** True if keyboard accessibility mode is on, false otherwise. */
355
- keyboardAccessibilityMode = false;
356
-
357
- /** The list of top-level bounded elements on the workspace. */
358
- private topBoundedElements_: IBoundedElement[] = [];
359
-
360
- /** The recorded drag targets. */
361
- private dragTargetAreas_: Array<{component: IDragTarget, clientRect: Rect}> =
362
- [];
363
- private readonly cachedParentSvgSize_: Size;
364
- // TODO(b/109816955): remove '!', see go/strict-prop-init-fix.
365
- svgGroup_!: SVGElement;
366
- // TODO(b/109816955): remove '!', see go/strict-prop-init-fix.
367
- svgBackground_!: SVGElement;
368
- // TODO(b/109816955): remove '!', see go/strict-prop-init-fix.
369
- svgBlockCanvas_!: SVGElement;
370
- // TODO(b/109816955): remove '!', see go/strict-prop-init-fix.
371
- svgBubbleCanvas_!: SVGElement;
372
- zoomControls_: AnyDuringMigration;
373
-
374
- /**
375
- * @param options Dictionary of options.
376
- * @param opt_blockDragSurface Drag surface for blocks.
377
- * @param opt_wsDragSurface Drag surface for the workspace.
378
- */
379
- constructor(
380
- options: Options, opt_blockDragSurface?: BlockDragSurfaceSvg,
381
- opt_wsDragSurface?: WorkspaceDragSurfaceSvg) {
382
- super(options);
383
-
384
- const MetricsManagerClass = registry.getClassFromOptions(
385
- registry.Type.METRICS_MANAGER, options, true);
386
- /** Object in charge of calculating metrics for the workspace. */
387
- this.metricsManager_ = new MetricsManagerClass!(this);
388
-
389
- /** Method to get all the metrics that have to do with a workspace. */
390
- this.getMetrics = options.getMetrics ||
391
- this.metricsManager_.getMetrics.bind(this.metricsManager_);
392
-
393
- /** Translates the workspace. */
394
- this.setMetrics =
395
- options.setMetrics || WorkspaceSvg.setTopLevelWorkspaceMetrics_;
396
-
397
- this.componentManager_ = new ComponentManager();
398
-
399
- this.connectionDBList = ConnectionDB.init(this.connectionChecker);
400
-
401
- if (opt_blockDragSurface) {
402
- this.blockDragSurface_ = opt_blockDragSurface;
403
- }
404
-
405
- if (opt_wsDragSurface) {
406
- this.workspaceDragSurface_ = opt_wsDragSurface;
407
- }
408
-
409
- this.useWorkspaceDragSurface_ =
410
- !!this.workspaceDragSurface_ && svgMath.is3dSupported();
411
-
412
- /**
413
- * Object in charge of loading, storing, and playing audio for a workspace.
414
- */
415
- this.audioManager_ =
416
- new WorkspaceAudio((options.parentWorkspace as WorkspaceSvg));
417
-
418
- /** This workspace's grid object or null. */
419
- // AnyDuringMigration because: Type 'Grid | null' is not assignable to type
420
- // 'Grid'.
421
- this.grid_ = (this.options.gridPattern ?
422
- new Grid(this.options.gridPattern, options.gridOptions) :
423
- null) as AnyDuringMigration;
424
-
425
- /** Manager in charge of markers and cursors. */
426
- this.markerManager_ = new MarkerManager(this);
427
-
428
- /**
429
- * Map from function names to callbacks, for deciding what to do when a
430
- * custom toolbox category is opened.
431
- */
432
- this.toolboxCategoryCallbacks_ = Object.create(null);
433
-
434
- /**
435
- * Map from function names to callbacks, for deciding what to do when a
436
- * button is clicked.
437
- */
438
- this.flyoutButtonCallbacks_ = Object.create(null);
439
-
440
- if (Variables && Variables.flyoutCategory) {
441
- this.registerToolboxCategoryCallback(
442
- Variables.CATEGORY_NAME, Variables.flyoutCategory);
443
- }
444
-
445
- if (VariablesDynamic && VariablesDynamic.flyoutCategory) {
446
- this.registerToolboxCategoryCallback(
447
- VariablesDynamic.CATEGORY_NAME, VariablesDynamic.flyoutCategory);
448
- }
449
-
450
- if (Procedures && Procedures.flyoutCategory) {
451
- this.registerToolboxCategoryCallback(
452
- Procedures.CATEGORY_NAME, Procedures.flyoutCategory);
453
- this.addChangeListener(Procedures.mutatorOpenListener);
454
- }
455
-
456
- /** Object in charge of storing and updating the workspace theme. */
457
- this.themeManager_ = this.options.parentWorkspace ?
458
- this.options.parentWorkspace.getThemeManager() :
459
- new ThemeManager(this, this.options.theme || Classic);
460
- // AnyDuringMigration because: Argument of type 'this' is not assignable to
461
- // parameter of type 'Workspace'.
462
- this.themeManager_.subscribeWorkspace(this as AnyDuringMigration);
463
-
464
- /** The block renderer used for rendering blocks on this workspace. */
465
- this.renderer_ = blockRendering.init(
466
- this.options.renderer || 'geras', this.getTheme(),
467
- this.options.rendererOverrides ?? undefined);
468
-
469
- /**
470
- * The cached size of the parent svg element.
471
- * Used to compute svg metrics.
472
- */
473
- this.cachedParentSvgSize_ = new Size(0, 0);
474
- }
475
-
476
- /**
477
- * Get the marker manager for this workspace.
478
- * @return The marker manager.
479
- */
480
- getMarkerManager(): MarkerManager {
481
- return this.markerManager_;
482
- }
483
-
484
- /**
485
- * Gets the metrics manager for this workspace.
486
- * @return The metrics manager.
487
- */
488
- getMetricsManager(): IMetricsManager {
489
- return this.metricsManager_;
490
- }
491
-
492
- /**
493
- * Sets the metrics manager for the workspace.
494
- * @param metricsManager The metrics manager.
495
- * @internal
496
- */
497
- setMetricsManager(metricsManager: IMetricsManager) {
498
- this.metricsManager_ = metricsManager;
499
- this.getMetrics =
500
- this.metricsManager_.getMetrics.bind(this.metricsManager_);
501
- }
502
-
503
- /**
504
- * Gets the component manager for this workspace.
505
- * @return The component manager.
506
- */
507
- getComponentManager(): ComponentManager {
508
- return this.componentManager_;
509
- }
510
-
511
- /**
512
- * Add the cursor SVG to this workspaces SVG group.
513
- * @param cursorSvg The SVG root of the cursor to be added to the workspace
514
- * SVG group.
515
- * @internal
516
- */
517
- setCursorSvg(cursorSvg: SVGElement) {
518
- this.markerManager_.setCursorSvg(cursorSvg);
519
- }
520
-
521
- /**
522
- * Add the marker SVG to this workspaces SVG group.
523
- * @param markerSvg The SVG root of the marker to be added to the workspace
524
- * SVG group.
525
- * @internal
526
- */
527
- setMarkerSvg(markerSvg: SVGElement) {
528
- this.markerManager_.setMarkerSvg(markerSvg);
529
- }
530
-
531
- /**
532
- * Get the marker with the given ID.
533
- * @param id The ID of the marker.
534
- * @return The marker with the given ID or null if no marker with the given ID
535
- * exists.
536
- * @internal
537
- */
538
- getMarker(id: string): Marker|null {
539
- if (this.markerManager_) {
540
- return this.markerManager_.getMarker(id);
541
- }
542
- return null;
543
- }
544
-
545
- /**
546
- * The cursor for this workspace.
547
- * @return The cursor for the workspace.
548
- */
549
- getCursor(): Cursor|null {
550
- if (this.markerManager_) {
551
- return this.markerManager_.getCursor();
552
- }
553
- return null;
554
- }
555
-
556
- /**
557
- * Get the block renderer attached to this workspace.
558
- * @return The renderer attached to this workspace.
559
- */
560
- getRenderer(): Renderer {
561
- return this.renderer_;
562
- }
563
-
564
- /**
565
- * Get the theme manager for this workspace.
566
- * @return The theme manager for this workspace.
567
- * @internal
568
- */
569
- getThemeManager(): ThemeManager {
570
- return this.themeManager_;
571
- }
572
-
573
- /**
574
- * Get the workspace theme object.
575
- * @return The workspace theme object.
576
- */
577
- getTheme(): Theme {
578
- return this.themeManager_.getTheme();
579
- }
580
-
581
- /**
582
- * Set the workspace theme object.
583
- * If no theme is passed, default to the `Classic` theme.
584
- * @param theme The workspace theme object.
585
- */
586
- setTheme(theme: Theme) {
587
- if (!theme) {
588
- theme = Classic as Theme;
589
- }
590
- this.themeManager_.setTheme(theme);
591
- }
592
-
593
- /**
594
- * Refresh all blocks on the workspace after a theme update.
595
- */
596
- refreshTheme() {
597
- if (this.svgGroup_) {
598
- this.renderer_.refreshDom(this.svgGroup_, this.getTheme());
599
- }
600
-
601
- // Update all blocks in workspace that have a style name.
602
- // AnyDuringMigration because: Argument of type 'BlockSvg[]' is not
603
- // assignable to parameter of type 'Block[]'.
604
- this.updateBlockStyles_(this.getAllBlocks(false).filter(function(block) {
605
- return !!block.getStyleName();
606
- }) as AnyDuringMigration);
607
-
608
- // Update current toolbox selection.
609
- this.refreshToolboxSelection();
610
- if (this.toolbox_) {
611
- this.toolbox_.refreshTheme();
612
- }
613
-
614
- // Re-render if workspace is visible
615
- if (this.isVisible()) {
616
- this.setVisible(true);
617
- }
618
-
619
- const event = new (eventUtils.get(eventUtils.THEME_CHANGE))!
620
- (this.getTheme().name, this.id);
621
- eventUtils.fire(event);
622
- }
623
-
624
- /**
625
- * Updates all the blocks with new style.
626
- * @param blocks List of blocks to update the style on.
627
- */
628
- private updateBlockStyles_(blocks: Block[]) {
629
- for (let i = 0, block; block = blocks[i]; i++) {
630
- const blockStyleName = block.getStyleName();
631
- if (blockStyleName) {
632
- const blockSvg = block as BlockSvg;
633
- blockSvg.setStyle(blockStyleName);
634
- if (blockSvg.mutator) {
635
- blockSvg.mutator.updateBlockStyle();
636
- }
637
- }
638
- }
639
- }
640
-
641
- /**
642
- * Getter for the inverted screen CTM.
643
- * @return The matrix to use in mouseToSvg
644
- */
645
- getInverseScreenCTM(): SVGMatrix|null {
646
- // Defer getting the screen CTM until we actually need it, this should
647
- // avoid forced reflows from any calls to updateInverseScreenCTM.
648
- if (this.inverseScreenCTMDirty_) {
649
- const ctm = this.getParentSvg().getScreenCTM();
650
- if (ctm) {
651
- this.inverseScreenCTM_ = (ctm).inverse();
652
- this.inverseScreenCTMDirty_ = false;
653
- }
654
- }
655
-
656
- return this.inverseScreenCTM_;
657
- }
658
-
659
- /** Mark the inverse screen CTM as dirty. */
660
- updateInverseScreenCTM() {
661
- this.inverseScreenCTMDirty_ = true;
662
- }
663
-
664
- /**
665
- * Getter for isVisible
666
- * @return Whether the workspace is visible.
667
- * False if the workspace has been hidden by calling `setVisible(false)`.
668
- */
669
- isVisible(): boolean {
670
- return this.isVisible_;
671
- }
672
-
673
- /**
674
- * Return the absolute coordinates of the top-left corner of this element,
675
- * scales that after canvas SVG element, if it's a descendant.
676
- * The origin (0,0) is the top-left corner of the Blockly SVG.
677
- * @param element SVG element to find the coordinates of.
678
- * @return Object with .x and .y properties.
679
- * @internal
680
- */
681
- getSvgXY(element: SVGElement): Coordinate {
682
- let x = 0;
683
- let y = 0;
684
- let scale = 1;
685
- if (dom.containsNode(this.getCanvas(), element) ||
686
- dom.containsNode(this.getBubbleCanvas(), element)) {
687
- // Before the SVG canvas, scale the coordinates.
688
- scale = this.scale;
689
- }
690
- do {
691
- // Loop through this block and every parent.
692
- const xy = svgMath.getRelativeXY(element);
693
- if (element === this.getCanvas() || element === this.getBubbleCanvas()) {
694
- // After the SVG canvas, don't scale the coordinates.
695
- scale = 1;
696
- }
697
- x += xy.x * scale;
698
- y += xy.y * scale;
699
- element = element.parentNode as SVGElement;
700
- } while (element && element !== this.getParentSvg());
701
- return new Coordinate(x, y);
702
- }
703
-
704
- /**
705
- * Gets the size of the workspace's parent SVG element.
706
- * @return The cached width and height of the workspace's parent SVG element.
707
- * @internal
708
- */
709
- getCachedParentSvgSize(): Size {
710
- const size = this.cachedParentSvgSize_;
711
- return new Size(size.width, size.height);
712
- }
713
-
714
- /**
715
- * Return the position of the workspace origin relative to the injection div
716
- * origin in pixels.
717
- * The workspace origin is where a block would render at position (0, 0).
718
- * It is not the upper left corner of the workspace SVG.
719
- * @return Offset in pixels.
720
- * @internal
721
- */
722
- getOriginOffsetInPixels(): Coordinate {
723
- return svgMath.getInjectionDivXY(this.getCanvas());
724
- }
725
-
726
- /**
727
- * Return the injection div that is a parent of this workspace.
728
- * Walks the DOM the first time it's called, then returns a cached value.
729
- * Note: We assume this is only called after the workspace has been injected
730
- * into the DOM.
731
- * @return The first parent div with 'injectionDiv' in the name.
732
- * @internal
733
- */
734
- getInjectionDiv(): Element {
735
- // NB: it would be better to pass this in at createDom, but is more likely
736
- // to break existing uses of Blockly.
737
- if (!this.injectionDiv_) {
738
- let element: Element = this.svgGroup_;
739
- while (element) {
740
- const classes = element.getAttribute('class') || '';
741
- if ((' ' + classes + ' ').indexOf(' injectionDiv ') !== -1) {
742
- this.injectionDiv_ = element;
743
- break;
744
- }
745
- element = element.parentNode as Element;
746
- }
747
- }
748
- return this.injectionDiv_;
749
- }
750
-
751
- /**
752
- * Get the SVG block canvas for the workspace.
753
- * @return The SVG group for the workspace.
754
- * @internal
755
- */
756
- getBlockCanvas(): SVGElement|null {
757
- return this.svgBlockCanvas_;
758
- }
759
-
760
- /**
761
- * Save resize handler data so we can delete it later in dispose.
762
- * @param handler Data that can be passed to eventHandling.unbind.
763
- */
764
- setResizeHandlerWrapper(handler: browserEvents.Data) {
765
- this.resizeHandlerWrapper_ = handler;
766
- }
767
-
768
- /**
769
- * Create the workspace DOM elements.
770
- * @param opt_backgroundClass Either 'blocklyMainBackground' or
771
- * 'blocklyMutatorBackground'.
772
- * @return The workspace's SVG group.
773
- */
774
- createDom(opt_backgroundClass?: string): Element {
775
- /**
776
- * <g class="blocklyWorkspace">
777
- * <rect class="blocklyMainBackground" height="100%" width="100%"></rect>
778
- * [Trashcan and/or flyout may go here]
779
- * <g class="blocklyBlockCanvas"></g>
780
- * <g class="blocklyBubbleCanvas"></g>
781
- * </g>
782
- */
783
- this.svgGroup_ = dom.createSvgElement(Svg.G, {'class': 'blocklyWorkspace'});
784
-
785
- // Note that a <g> alone does not receive mouse events--it must have a
786
- // valid target inside it. If no background class is specified, as in the
787
- // flyout, the workspace will not receive mouse events.
788
- if (opt_backgroundClass) {
789
- this.svgBackground_ = dom.createSvgElement(
790
- Svg.RECT,
791
- {'height': '100%', 'width': '100%', 'class': opt_backgroundClass},
792
- this.svgGroup_);
793
-
794
- if (opt_backgroundClass === 'blocklyMainBackground' && this.grid_) {
795
- this.svgBackground_.style.fill =
796
- 'url(#' + this.grid_.getPatternId() + ')';
797
- } else {
798
- this.themeManager_.subscribe(
799
- this.svgBackground_, 'workspaceBackgroundColour', 'fill');
800
- }
801
- }
802
- this.svgBlockCanvas_ = dom.createSvgElement(
803
- Svg.G, {'class': 'blocklyBlockCanvas'}, this.svgGroup_);
804
- this.svgBubbleCanvas_ = dom.createSvgElement(
805
- Svg.G, {'class': 'blocklyBubbleCanvas'}, this.svgGroup_);
806
-
807
- if (!this.isFlyout) {
808
- browserEvents.conditionalBind(
809
- this.svgGroup_, 'mousedown', this, this.onMouseDown_, false, true);
810
- // This no-op works around https://bugs.webkit.org/show_bug.cgi?id=226683,
811
- // which otherwise prevents zoom/scroll events from being observed in
812
- // Safari. Once that bug is fixed it should be removed.
813
- document.body.addEventListener('wheel', function() {});
814
- browserEvents.conditionalBind(
815
- this.svgGroup_, 'wheel', this, this.onMouseWheel_);
816
- }
817
-
818
- // Determine if there needs to be a category tree, or a simple list of
819
- // blocks. This cannot be changed later, since the UI is very different.
820
- if (this.options.hasCategories) {
821
- const ToolboxClass = registry.getClassFromOptions(
822
- registry.Type.TOOLBOX, this.options, true);
823
- this.toolbox_ = new ToolboxClass!(this);
824
- }
825
- if (this.grid_) {
826
- this.grid_.update(this.scale);
827
- }
828
- this.recordDragTargets();
829
- const CursorClass =
830
- registry.getClassFromOptions(registry.Type.CURSOR, this.options);
831
-
832
- CursorClass && this.markerManager_.setCursor(new CursorClass());
833
-
834
- this.renderer_.createDom(this.svgGroup_, this.getTheme());
835
- return this.svgGroup_;
836
- }
837
-
838
- /**
839
- * Dispose of this workspace.
840
- * Unlink from all DOM elements to prevent memory leaks.
841
- * @suppress {checkTypes}
842
- */
843
- override dispose() {
844
- // Stop rerendering.
845
- this.rendered = false;
846
- if (this.currentGesture_) {
847
- this.currentGesture_.cancel();
848
- }
849
- if (this.svgGroup_) {
850
- dom.removeNode(this.svgGroup_);
851
- // AnyDuringMigration because: Type 'null' is not assignable to type
852
- // 'SVGElement'.
853
- this.svgGroup_ = null as AnyDuringMigration;
854
- }
855
- // AnyDuringMigration because: Type 'null' is not assignable to type
856
- // 'SVGElement'.
857
- this.svgBlockCanvas_ = null as AnyDuringMigration;
858
- // AnyDuringMigration because: Type 'null' is not assignable to type
859
- // 'SVGElement'.
860
- this.svgBubbleCanvas_ = null as AnyDuringMigration;
861
- if (this.toolbox_) {
862
- this.toolbox_.dispose();
863
- // AnyDuringMigration because: Type 'null' is not assignable to type
864
- // 'IToolbox'.
865
- this.toolbox_ = null as AnyDuringMigration;
866
- }
867
- if (this.flyout_) {
868
- this.flyout_.dispose();
869
- // AnyDuringMigration because: Type 'null' is not assignable to type
870
- // 'IFlyout'.
871
- this.flyout_ = null as AnyDuringMigration;
872
- }
873
- if (this.trashcan) {
874
- this.trashcan.dispose();
875
- // AnyDuringMigration because: Type 'null' is not assignable to type
876
- // 'Trashcan'.
877
- this.trashcan = null as AnyDuringMigration;
878
- }
879
- if (this.scrollbar) {
880
- this.scrollbar.dispose();
881
- // AnyDuringMigration because: Type 'null' is not assignable to type
882
- // 'ScrollbarPair'.
883
- this.scrollbar = null as AnyDuringMigration;
884
- }
885
- if (this.zoomControls_) {
886
- this.zoomControls_.dispose();
887
- this.zoomControls_ = null;
888
- }
889
-
890
- if (this.audioManager_) {
891
- this.audioManager_.dispose();
892
- // AnyDuringMigration because: Type 'null' is not assignable to type
893
- // 'WorkspaceAudio'.
894
- this.audioManager_ = null as AnyDuringMigration;
895
- }
896
-
897
- if (this.grid_) {
898
- // AnyDuringMigration because: Type 'null' is not assignable to type
899
- // 'Grid'.
900
- this.grid_ = null as AnyDuringMigration;
901
- }
902
-
903
- this.renderer_.dispose();
904
-
905
- if (this.markerManager_) {
906
- this.markerManager_.dispose();
907
- // AnyDuringMigration because: Type 'null' is not assignable to type
908
- // 'MarkerManager'.
909
- this.markerManager_ = null as AnyDuringMigration;
910
- }
911
-
912
- super.dispose();
913
-
914
- // Dispose of theme manager after all blocks and mutators are disposed of.
915
- if (this.themeManager_) {
916
- // AnyDuringMigration because: Argument of type 'this' is not assignable
917
- // to parameter of type 'Workspace'.
918
- this.themeManager_.unsubscribeWorkspace(this as AnyDuringMigration);
919
- this.themeManager_.unsubscribe(this.svgBackground_);
920
- if (!this.options.parentWorkspace) {
921
- this.themeManager_.dispose();
922
- // AnyDuringMigration because: Type 'null' is not assignable to type
923
- // 'ThemeManager'.
924
- this.themeManager_ = null as AnyDuringMigration;
925
- }
926
- }
927
-
928
- this.connectionDBList.length = 0;
929
-
930
- // AnyDuringMigration because: Type 'null' is not assignable to type '{
931
- // [key: string]: ((p1: WorkspaceSvg) => FlyoutDefinition) | null; }'.
932
- this.toolboxCategoryCallbacks_ = null as AnyDuringMigration;
933
- // AnyDuringMigration because: Type 'null' is not assignable to type '{
934
- // [key: string]: ((p1: FlyoutButton) => any) | null; }'.
935
- this.flyoutButtonCallbacks_ = null as AnyDuringMigration;
936
-
937
- if (!this.options.parentWorkspace) {
938
- // Top-most workspace. Dispose of the div that the
939
- // SVG is injected into (i.e. injectionDiv).
940
- const parentSvg = this.getParentSvg();
941
- if (parentSvg && parentSvg.parentNode) {
942
- dom.removeNode(parentSvg.parentNode);
943
- }
944
- }
945
- if (this.resizeHandlerWrapper_) {
946
- browserEvents.unbind(this.resizeHandlerWrapper_);
947
- this.resizeHandlerWrapper_ = null;
948
- }
949
- }
950
-
951
- /**
952
- * Add a trashcan.
953
- * @internal
954
- */
955
- addTrashcan() {
956
- this.trashcan = WorkspaceSvg.newTrashcan(this);
957
- const svgTrashcan = this.trashcan.createDom();
958
- this.svgGroup_.insertBefore(svgTrashcan, this.svgBlockCanvas_);
959
- }
960
-
961
- /**
962
- * @internal
963
- */
964
- static newTrashcan(workspace: WorkspaceSvg): Trashcan {
965
- throw new Error(
966
- 'The implementation of newTrashcan should be ' +
967
- 'monkey-patched in by blockly.ts');
968
- }
969
-
970
- /**
971
- * Add zoom controls.
972
- * @internal
973
- */
974
- addZoomControls() {
975
- this.zoomControls_ = new ZoomControls(this);
976
- const svgZoomControls = this.zoomControls_.createDom();
977
- this.svgGroup_.appendChild(svgZoomControls);
978
- }
979
-
980
- /**
981
- * Add a flyout element in an element with the given tag name.
982
- * @param tagName What type of tag the flyout belongs in.
983
- * @return The element containing the flyout DOM.
984
- * @internal
985
- */
986
- addFlyout(tagName: string|Svg<SVGSVGElement>|Svg<SVGGElement>): Element {
987
- const workspaceOptions = new Options(({
988
- 'parentWorkspace': this,
989
- 'rtl': this.RTL,
990
- 'oneBasedIndex': this.options.oneBasedIndex,
991
- 'horizontalLayout': this.horizontalLayout,
992
- 'renderer': this.options.renderer,
993
- 'rendererOverrides': this.options.rendererOverrides,
994
- 'move': {
995
- 'scrollbars': true,
996
- },
997
- } as BlocklyOptions));
998
- workspaceOptions.toolboxPosition = this.options.toolboxPosition;
999
- if (this.horizontalLayout) {
1000
- const HorizontalFlyout = registry.getClassFromOptions(
1001
- registry.Type.FLYOUTS_HORIZONTAL_TOOLBOX, this.options, true);
1002
- this.flyout_ = new HorizontalFlyout!(workspaceOptions);
1003
- } else {
1004
- const VerticalFlyout = registry.getClassFromOptions(
1005
- registry.Type.FLYOUTS_VERTICAL_TOOLBOX, this.options, true);
1006
- this.flyout_ = new VerticalFlyout!(workspaceOptions);
1007
- }
1008
- this.flyout_.autoClose = false;
1009
- this.flyout_.getWorkspace().setVisible(true);
1010
-
1011
- // Return the element so that callers can place it in their desired
1012
- // spot in the DOM. For example, mutator flyouts do not go in the same
1013
- // place as main workspace flyouts.
1014
- return this.flyout_.createDom(tagName);
1015
- }
1016
-
1017
- /**
1018
- * Getter for the flyout associated with this workspace. This flyout may be
1019
- * owned by either the toolbox or the workspace, depending on toolbox
1020
- * configuration. It will be null if there is no flyout.
1021
- * @param opt_own Whether to only return the workspace's own flyout.
1022
- * @return The flyout on this workspace.
1023
- * @internal
1024
- */
1025
- getFlyout(opt_own?: boolean): IFlyout|null {
1026
- if (this.flyout_ || opt_own) {
1027
- return this.flyout_;
1028
- }
1029
- if (this.toolbox_) {
1030
- return this.toolbox_.getFlyout();
1031
- }
1032
- return null;
1033
- }
1034
-
1035
- /**
1036
- * Getter for the toolbox associated with this workspace, if one exists.
1037
- * @return The toolbox on this workspace.
1038
- * @internal
1039
- */
1040
- getToolbox(): IToolbox|null {
1041
- return this.toolbox_;
1042
- }
1043
-
1044
- /**
1045
- * Update items that use screen coordinate calculations
1046
- * because something has changed (e.g. scroll position, window size).
1047
- */
1048
- private updateScreenCalculations_() {
1049
- this.updateInverseScreenCTM();
1050
- this.recordDragTargets();
1051
- }
1052
-
1053
- /**
1054
- * If enabled, resize the parts of the workspace that change when the
1055
- * workspace contents (e.g. block positions) change. This will also scroll
1056
- * the workspace contents if needed.
1057
- * @internal
1058
- */
1059
- resizeContents() {
1060
- if (!this.resizesEnabled_ || !this.rendered) {
1061
- return;
1062
- }
1063
- if (this.scrollbar) {
1064
- this.scrollbar.resize();
1065
- }
1066
- this.updateInverseScreenCTM();
1067
- }
1068
-
1069
- /**
1070
- * Resize and reposition all of the workspace chrome (toolbox,
1071
- * trash, scrollbars etc.)
1072
- * This should be called when something changes that
1073
- * requires recalculating dimensions and positions of the
1074
- * trash, zoom, toolbox, etc. (e.g. window resize).
1075
- */
1076
- resize() {
1077
- if (this.toolbox_) {
1078
- this.toolbox_.position();
1079
- }
1080
- if (this.flyout_) {
1081
- this.flyout_.position();
1082
- }
1083
-
1084
- const positionables = this.componentManager_.getComponents(
1085
- ComponentManager.Capability.POSITIONABLE, true);
1086
- const metrics = this.getMetricsManager().getUiMetrics();
1087
- const savedPositions = [];
1088
- for (let i = 0, positionable; positionable = positionables[i]; i++) {
1089
- positionable.position(metrics, savedPositions);
1090
- const boundingRect = positionable.getBoundingRectangle();
1091
- if (boundingRect) {
1092
- savedPositions.push(boundingRect);
1093
- }
1094
- }
1095
-
1096
- if (this.scrollbar) {
1097
- this.scrollbar.resize();
1098
- }
1099
- this.updateScreenCalculations_();
1100
- }
1101
-
1102
- /**
1103
- * Resizes and repositions workspace chrome if the page has a new
1104
- * scroll position.
1105
- * @internal
1106
- */
1107
- updateScreenCalculationsIfScrolled() {
1108
- /* eslint-disable indent */
1109
- const currScroll = svgMath.getDocumentScroll();
1110
- if (!Coordinate.equals(this.lastRecordedPageScroll_, currScroll)) {
1111
- this.lastRecordedPageScroll_ = currScroll;
1112
- this.updateScreenCalculations_();
1113
- }
1114
- }
1115
- /* eslint-enable indent */
1116
-
1117
- /**
1118
- * Get the SVG element that forms the drawing surface.
1119
- * @return SVG group element.
1120
- */
1121
- getCanvas(): SVGGElement {
1122
- return this.svgBlockCanvas_ as SVGGElement;
1123
- }
1124
-
1125
- /**
1126
- * Caches the width and height of the workspace's parent SVG element for use
1127
- * with getSvgMetrics.
1128
- * @param width The width of the parent SVG element.
1129
- * @param height The height of the parent SVG element
1130
- * @internal
1131
- */
1132
- setCachedParentSvgSize(width: number|null, height: number|null) {
1133
- const svg = this.getParentSvg();
1134
- if (width != null) {
1135
- this.cachedParentSvgSize_.width = width;
1136
- // This is set to support the public (but deprecated) Blockly.svgSize
1137
- // method.
1138
- // AnyDuringMigration because: Argument of type 'number' is not
1139
- // assignable to parameter of type 'string'.
1140
- svg.setAttribute('data-cached-width', width as AnyDuringMigration);
1141
- }
1142
- if (height != null) {
1143
- this.cachedParentSvgSize_.height = height;
1144
- // This is set to support the public (but deprecated) Blockly.svgSize
1145
- // method.
1146
- // AnyDuringMigration because: Argument of type 'number' is not
1147
- // assignable to parameter of type 'string'.
1148
- svg.setAttribute('data-cached-height', height as AnyDuringMigration);
1149
- }
1150
- }
1151
-
1152
- /**
1153
- * Get the SVG element that forms the bubble surface.
1154
- * @return SVG group element.
1155
- */
1156
- getBubbleCanvas(): SVGGElement {
1157
- return this.svgBubbleCanvas_ as SVGGElement;
1158
- }
1159
-
1160
- /**
1161
- * Get the SVG element that contains this workspace.
1162
- * Note: We assume this is only called after the workspace has been injected
1163
- * into the DOM.
1164
- * @return SVG element.
1165
- */
1166
- getParentSvg(): SVGSVGElement {
1167
- if (!this.cachedParentSvg_) {
1168
- let element = this.svgGroup_;
1169
- while (element) {
1170
- if (element.tagName === 'svg') {
1171
- this.cachedParentSvg_ = element;
1172
- break;
1173
- }
1174
- element = element.parentNode as SVGSVGElement;
1175
- }
1176
- }
1177
- return this.cachedParentSvg_ as SVGSVGElement;
1178
- }
1179
-
1180
- /**
1181
- * Fires a viewport event if events are enabled and there is a change in
1182
- * viewport values.
1183
- * @internal
1184
- */
1185
- maybeFireViewportChangeEvent() {
1186
- if (!eventUtils.isEnabled()) {
1187
- return;
1188
- }
1189
- const scale = this.scale;
1190
- const top = -this.scrollY;
1191
- const left = -this.scrollX;
1192
- if (scale === this.oldScale_ && Math.abs(top - this.oldTop_) < 1 &&
1193
- Math.abs(left - this.oldLeft_) < 1) {
1194
- // Ignore sub-pixel changes in top and left. Due to #4192 there are a lot
1195
- // of negligible changes in viewport top/left.
1196
- return;
1197
- }
1198
- const event = new (eventUtils.get(eventUtils.VIEWPORT_CHANGE))!
1199
- (top, left, scale, this.id, this.oldScale_);
1200
- this.oldScale_ = scale;
1201
- this.oldTop_ = top;
1202
- this.oldLeft_ = left;
1203
- eventUtils.fire(event);
1204
- }
1205
-
1206
- /**
1207
- * Translate this workspace to new coordinates.
1208
- * @param x Horizontal translation, in pixel units relative to the top left of
1209
- * the Blockly div.
1210
- * @param y Vertical translation, in pixel units relative to the top left of
1211
- * the Blockly div.
1212
- */
1213
- translate(x: number, y: number) {
1214
- if (this.useWorkspaceDragSurface_ && this.isDragSurfaceActive_) {
1215
- this.workspaceDragSurface_.translateSurface(x, y);
1216
- } else {
1217
- const translation = 'translate(' + x + ',' + y + ') ' +
1218
- 'scale(' + this.scale + ')';
1219
- this.svgBlockCanvas_.setAttribute('transform', translation);
1220
- this.svgBubbleCanvas_.setAttribute('transform', translation);
1221
- }
1222
- // Now update the block drag surface if we're using one.
1223
- if (this.blockDragSurface_) {
1224
- this.blockDragSurface_.translateAndScaleGroup(x, y, this.scale);
1225
- }
1226
- // And update the grid if we're using one.
1227
- if (this.grid_) {
1228
- this.grid_.moveTo(x, y);
1229
- }
1230
-
1231
- this.maybeFireViewportChangeEvent();
1232
- }
1233
-
1234
- /**
1235
- * Called at the end of a workspace drag to take the contents
1236
- * out of the drag surface and put them back into the workspace SVG.
1237
- * Does nothing if the workspace drag surface is not enabled.
1238
- * @internal
1239
- */
1240
- resetDragSurface() {
1241
- // Don't do anything if we aren't using a drag surface.
1242
- if (!this.useWorkspaceDragSurface_) {
1243
- return;
1244
- }
1245
-
1246
- this.isDragSurfaceActive_ = false;
1247
-
1248
- const trans = this.workspaceDragSurface_.getSurfaceTranslation();
1249
- this.workspaceDragSurface_.clearAndHide(this.svgGroup_);
1250
- const translation = 'translate(' + trans.x + ',' + trans.y + ') ' +
1251
- 'scale(' + this.scale + ')';
1252
- this.svgBlockCanvas_.setAttribute('transform', translation);
1253
- this.svgBubbleCanvas_.setAttribute('transform', translation);
1254
- }
1255
-
1256
- /**
1257
- * Called at the beginning of a workspace drag to move contents of
1258
- * the workspace to the drag surface.
1259
- * Does nothing if the drag surface is not enabled.
1260
- * @internal
1261
- */
1262
- setupDragSurface() {
1263
- // Don't do anything if we aren't using a drag surface.
1264
- if (!this.useWorkspaceDragSurface_) {
1265
- return;
1266
- }
1267
-
1268
- // This can happen if the user starts a drag, mouses up outside of the
1269
- // document where the mouseup listener is registered (e.g. outside of an
1270
- // iframe) and then moves the mouse back in the workspace. On mobile and
1271
- // ff, we get the mouseup outside the frame. On chrome and safari desktop we
1272
- // do not.
1273
- if (this.isDragSurfaceActive_) {
1274
- return;
1275
- }
1276
-
1277
- this.isDragSurfaceActive_ = true;
1278
-
1279
- // Figure out where we want to put the canvas back. The order
1280
- // in the is important because things are layered.
1281
- const previousElement = this.svgBlockCanvas_.previousSibling as Element;
1282
- // AnyDuringMigration because: Argument of type 'string | null' is not
1283
- // assignable to parameter of type 'string'.
1284
- const width = parseInt(
1285
- this.getParentSvg().getAttribute('width') as AnyDuringMigration, 10);
1286
- // AnyDuringMigration because: Argument of type 'string | null' is not
1287
- // assignable to parameter of type 'string'.
1288
- const height = parseInt(
1289
- this.getParentSvg().getAttribute('height') as AnyDuringMigration, 10);
1290
- const coord = svgMath.getRelativeXY(this.getCanvas());
1291
- this.workspaceDragSurface_.setContentsAndShow(
1292
- this.getCanvas(), this.getBubbleCanvas(), previousElement, width,
1293
- height, this.scale);
1294
- this.workspaceDragSurface_.translateSurface(coord.x, coord.y);
1295
- }
1296
-
1297
- /**
1298
- * Gets the drag surface blocks are moved to when a drag is started.
1299
- * @return This workspace's block drag surface, if one is in use.
1300
- * @internal
1301
- */
1302
- getBlockDragSurface(): BlockDragSurfaceSvg|null {
1303
- return this.blockDragSurface_;
1304
- }
1305
-
1306
- /**
1307
- * Returns the horizontal offset of the workspace.
1308
- * Intended for LTR/RTL compatibility in XML.
1309
- * @return Width.
1310
- */
1311
- override getWidth(): number {
1312
- const metrics = this.getMetrics();
1313
- return metrics ? metrics.viewWidth / this.scale : 0;
1314
- }
1315
-
1316
- /**
1317
- * Toggles the visibility of the workspace.
1318
- * Currently only intended for main workspace.
1319
- * @param isVisible True if workspace should be visible.
1320
- */
1321
- setVisible(isVisible: boolean) {
1322
- this.isVisible_ = isVisible;
1323
- if (!this.svgGroup_) {
1324
- return;
1325
- }
1326
-
1327
- // Tell the scrollbar whether its container is visible so it can
1328
- // tell when to hide itself.
1329
- if (this.scrollbar) {
1330
- this.scrollbar.setContainerVisible(isVisible);
1331
- }
1332
-
1333
- // Tell the flyout whether its container is visible so it can
1334
- // tell when to hide itself.
1335
- if (this.getFlyout()) {
1336
- this.getFlyout()!.setContainerVisible(isVisible);
1337
- }
1338
-
1339
- this.getParentSvg().style.display = isVisible ? 'block' : 'none';
1340
- if (this.toolbox_) {
1341
- // Currently does not support toolboxes in mutators.
1342
- this.toolbox_.setVisible(isVisible);
1343
- }
1344
- if (isVisible) {
1345
- const blocks = this.getAllBlocks(false);
1346
- // Tell each block on the workspace to mark its fields as dirty.
1347
- for (let i = blocks.length - 1; i >= 0; i--) {
1348
- blocks[i].markDirty();
1349
- }
1350
-
1351
- this.render();
1352
- if (this.toolbox_) {
1353
- this.toolbox_.position();
1354
- }
1355
- } else {
1356
- this.hideChaff(true);
1357
- }
1358
- }
1359
-
1360
- /** Render all blocks in workspace. */
1361
- render() {
1362
- // Generate list of all blocks.
1363
- const blocks = this.getAllBlocks(false);
1364
- // Render each block.
1365
- for (let i = blocks.length - 1; i >= 0; i--) {
1366
- blocks[i].render(false);
1367
- }
1368
-
1369
- if (this.currentGesture_) {
1370
- const imList = this.currentGesture_.getInsertionMarkers();
1371
- for (let i = 0; i < imList.length; i++) {
1372
- imList[i].render(false);
1373
- }
1374
- }
1375
-
1376
- this.markerManager_.updateMarkers();
1377
- }
1378
-
1379
- /**
1380
- * Highlight or unhighlight a block in the workspace. Block highlighting is
1381
- * often used to visually mark blocks currently being executed.
1382
- * @param id ID of block to highlight/unhighlight, or null for no block (used
1383
- * to unhighlight all blocks).
1384
- * @param opt_state If undefined, highlight specified block and automatically
1385
- * unhighlight all others. If true or false, manually
1386
- * highlight/unhighlight the specified block.
1387
- */
1388
- highlightBlock(id: string|null, opt_state?: boolean) {
1389
- if (opt_state === undefined) {
1390
- // Unhighlight all blocks.
1391
- for (let i = 0, block; block = this.highlightedBlocks_[i]; i++) {
1392
- block.setHighlighted(false);
1393
- }
1394
- this.highlightedBlocks_.length = 0;
1395
- }
1396
- // Highlight/unhighlight the specified block.
1397
- const block = id ? this.getBlockById(id) : null;
1398
- if (block) {
1399
- const state = opt_state === undefined || opt_state;
1400
- // Using Set here would be great, but at the cost of IE10 support.
1401
- if (!state) {
1402
- arrayUtils.removeElem(this.highlightedBlocks_, block);
1403
- } else if (this.highlightedBlocks_.indexOf(block) === -1) {
1404
- this.highlightedBlocks_.push(block);
1405
- }
1406
- block.setHighlighted(state);
1407
- }
1408
- }
1409
-
1410
- /**
1411
- * Pastes the provided block or workspace comment onto the workspace.
1412
- * Does not check whether there is remaining capacity for the object, that
1413
- * should be done before calling this method.
1414
- * @param state The representation of the thing to paste.
1415
- * @return The pasted thing, or null if the paste was not successful.
1416
- */
1417
- paste(state: AnyDuringMigration|Element|DocumentFragment): ICopyable|null {
1418
- if (!this.rendered || !state['type'] && !state['tagName']) {
1419
- return null;
1420
- }
1421
- if (this.currentGesture_) { // Dragging while pasting? No.
1422
- this.currentGesture_.cancel();
1423
- }
1424
-
1425
- const existingGroup = eventUtils.getGroup();
1426
- if (!existingGroup) {
1427
- eventUtils.setGroup(true);
1428
- }
1429
-
1430
- let pastedThing;
1431
- // Checks if this is JSON. JSON has a type property, while elements don't.
1432
- if (state['type']) {
1433
- pastedThing = this.pasteBlock_(null, state as blocks.State);
1434
- } else {
1435
- const xmlBlock = state as Element;
1436
- if (xmlBlock.tagName.toLowerCase() === 'comment') {
1437
- pastedThing = this.pasteWorkspaceComment_(xmlBlock);
1438
- } else {
1439
- pastedThing = this.pasteBlock_(xmlBlock, null);
1440
- }
1441
- }
1442
-
1443
- eventUtils.setGroup(existingGroup);
1444
- return pastedThing;
1445
- }
1446
-
1447
- /**
1448
- * Paste the provided block onto the workspace.
1449
- * @param xmlBlock XML block element.
1450
- * @param jsonBlock JSON block representation.
1451
- * @return The pasted block.
1452
- */
1453
- private pasteBlock_(xmlBlock: Element|null, jsonBlock: blocks.State|null):
1454
- BlockSvg {
1455
- eventUtils.disable();
1456
- let block: BlockSvg;
1457
- try {
1458
- let blockX = 0;
1459
- let blockY = 0;
1460
- if (xmlBlock) {
1461
- // AnyDuringMigration because: Argument of type 'this' is not
1462
- // assignable to parameter of type 'Workspace'.
1463
- block =
1464
- Xml.domToBlock(xmlBlock, this as AnyDuringMigration) as BlockSvg;
1465
- // AnyDuringMigration because: Argument of type 'string | null' is not
1466
- // assignable to parameter of type 'string'.
1467
- blockX = parseInt(xmlBlock.getAttribute('x') as AnyDuringMigration, 10);
1468
- if (this.RTL) {
1469
- blockX = -blockX;
1470
- }
1471
- // AnyDuringMigration because: Argument of type 'string | null' is not
1472
- // assignable to parameter of type 'string'.
1473
- blockY = parseInt(xmlBlock.getAttribute('y') as AnyDuringMigration, 10);
1474
- } else if (jsonBlock) {
1475
- // AnyDuringMigration because: Argument of type 'this' is not
1476
- // assignable to parameter of type 'Workspace'.
1477
- block =
1478
- blocks.append(jsonBlock, this as AnyDuringMigration) as BlockSvg;
1479
- blockX = jsonBlock['x'] || 10;
1480
- if (this.RTL) {
1481
- blockX = this.getWidth() - blockX;
1482
- }
1483
- blockY = jsonBlock['y'] || 10;
1484
- }
1485
-
1486
- // Move the duplicate to original position.
1487
- if (!isNaN(blockX) && !isNaN(blockY)) {
1488
- // Offset block until not clobbering another block and not in connection
1489
- // distance with neighbouring blocks.
1490
- let collide;
1491
- do {
1492
- collide = false;
1493
- const allBlocks = this.getAllBlocks(false);
1494
- for (let i = 0, otherBlock; otherBlock = allBlocks[i]; i++) {
1495
- const otherXY = otherBlock.getRelativeToSurfaceXY();
1496
- if (Math.abs(blockX - otherXY.x) <= 1 &&
1497
- Math.abs(blockY - otherXY.y) <= 1) {
1498
- collide = true;
1499
- break;
1500
- }
1501
- }
1502
- if (!collide) {
1503
- // Check for blocks in snap range to any of its connections.
1504
- const connections = block!.getConnections_(false);
1505
- for (let i = 0, connection; connection = connections[i]; i++) {
1506
- const neighbour =
1507
- (connection)
1508
- .closest(
1509
- config.snapRadius, new Coordinate(blockX, blockY));
1510
- if (neighbour.connection) {
1511
- collide = true;
1512
- break;
1513
- }
1514
- }
1515
- }
1516
- if (collide) {
1517
- if (this.RTL) {
1518
- blockX -= config.snapRadius;
1519
- } else {
1520
- blockX += config.snapRadius;
1521
- }
1522
- blockY += config.snapRadius * 2;
1523
- }
1524
- } while (collide);
1525
- block!.moveTo(new Coordinate(blockX, blockY));
1526
- }
1527
- } finally {
1528
- eventUtils.enable();
1529
- }
1530
- if (eventUtils.isEnabled() && !block!.isShadow()) {
1531
- eventUtils.fire(new (eventUtils.get(eventUtils.BLOCK_CREATE))!(block!));
1532
- }
1533
- block!.select();
1534
- return block!;
1535
- }
1536
-
1537
- /**
1538
- * Paste the provided comment onto the workspace.
1539
- * @param xmlComment XML workspace comment element.
1540
- * @return The pasted workspace comment.
1541
- * @suppress {checkTypes} Suppress checks while workspace comments are not
1542
- * bundled in.
1543
- */
1544
- private pasteWorkspaceComment_(xmlComment: Element): WorkspaceCommentSvg {
1545
- eventUtils.disable();
1546
- let comment: WorkspaceCommentSvg;
1547
- try {
1548
- // AnyDuringMigration because: Property 'get' does not exist on type
1549
- // '(name: string) => void'.
1550
- comment =
1551
- WorkspaceCommentSvg.fromXml(xmlComment, this) as AnyDuringMigration;
1552
- // Move the duplicate to original position.
1553
- // AnyDuringMigration because: Argument of type 'string | null' is not
1554
- // assignable to parameter of type 'string'.
1555
- let commentX =
1556
- parseInt(xmlComment.getAttribute('x') as AnyDuringMigration, 10);
1557
- // AnyDuringMigration because: Argument of type 'string | null' is not
1558
- // assignable to parameter of type 'string'.
1559
- let commentY =
1560
- parseInt(xmlComment.getAttribute('y') as AnyDuringMigration, 10);
1561
- if (!isNaN(commentX) && !isNaN(commentY)) {
1562
- if (this.RTL) {
1563
- commentX = -commentX;
1564
- }
1565
- // Offset workspace comment.
1566
- // TODO (#1719): Properly offset comment such that it's not interfering
1567
- // with any blocks.
1568
- commentX += 50;
1569
- commentY += 50;
1570
- comment.moveBy(commentX, commentY);
1571
- }
1572
- } finally {
1573
- eventUtils.enable();
1574
- }
1575
- if (eventUtils.isEnabled()) {
1576
- // AnyDuringMigration because: Property 'get' does not exist on type
1577
- // '(name: string) => void'.
1578
- WorkspaceComment.fireCreateEvent(comment);
1579
- }
1580
- comment.select();
1581
- return comment;
1582
- }
1583
-
1584
- /**
1585
- * Refresh the toolbox unless there's a drag in progress.
1586
- * @internal
1587
- */
1588
- refreshToolboxSelection() {
1589
- const ws = this.isFlyout ? this.targetWorkspace : this;
1590
- if (ws && !ws.currentGesture_ && ws.toolbox_ && ws.toolbox_.getFlyout()) {
1591
- ws.toolbox_.refreshSelection();
1592
- }
1593
- }
1594
-
1595
- /**
1596
- * Rename a variable by updating its name in the variable map. Update the
1597
- * flyout to show the renamed variable immediately.
1598
- * @param id ID of the variable to rename.
1599
- * @param newName New variable name.
1600
- */
1601
- override renameVariableById(id: string, newName: string) {
1602
- super.renameVariableById(id, newName);
1603
- this.refreshToolboxSelection();
1604
- }
1605
-
1606
- /**
1607
- * Delete a variable by the passed in ID. Update the flyout to show
1608
- * immediately that the variable is deleted.
1609
- * @param id ID of variable to delete.
1610
- */
1611
- override deleteVariableById(id: string) {
1612
- super.deleteVariableById(id);
1613
- this.refreshToolboxSelection();
1614
- }
1615
-
1616
- /**
1617
- * Create a new variable with the given name. Update the flyout to show the
1618
- * new variable immediately.
1619
- * @param name The new variable's name.
1620
- * @param opt_type The type of the variable like 'int' or 'string'.
1621
- * Does not need to be unique. Field_variable can filter variables based
1622
- * on their type. This will default to '' which is a specific type.
1623
- * @param opt_id The unique ID of the variable. This will default to a UUID.
1624
- * @return The newly created variable.
1625
- */
1626
- override createVariable(
1627
- name: string, opt_type?: string|null,
1628
- opt_id?: string|null): VariableModel {
1629
- const newVar = super.createVariable(name, opt_type, opt_id);
1630
- this.refreshToolboxSelection();
1631
- return newVar;
1632
- }
1633
-
1634
- /**
1635
- * Make a list of all the delete areas for this workspace.
1636
- * @deprecated Use workspace.recordDragTargets. (2021 June)
1637
- */
1638
- recordDeleteAreas() {
1639
- // AnyDuringMigration because: Property 'warn' does not exist on type
1640
- // 'void'.
1641
- (utils.deprecation as AnyDuringMigration)
1642
- .warn(
1643
- 'WorkspaceSvg.prototype.recordDeleteAreas', 'June 2021',
1644
- 'June 2022', 'WorkspaceSvg.prototype.recordDragTargets');
1645
- this.recordDragTargets();
1646
- }
1647
-
1648
- /** Make a list of all the delete areas for this workspace. */
1649
- recordDragTargets() {
1650
- const dragTargets = this.componentManager_.getComponents(
1651
- ComponentManager.Capability.DRAG_TARGET, true);
1652
-
1653
- this.dragTargetAreas_ = [];
1654
- for (let i = 0, targetArea; targetArea = dragTargets[i]; i++) {
1655
- const rect = targetArea.getClientRect();
1656
- if (rect) {
1657
- this.dragTargetAreas_.push({
1658
- component: targetArea,
1659
- clientRect: rect,
1660
- });
1661
- }
1662
- }
1663
- }
1664
-
1665
- /**
1666
- * Obtain a newly created block.
1667
- * @param prototypeName Name of the language object containing type-specific
1668
- * functions for this block.
1669
- * @param opt_id Optional ID. Use this ID if provided, otherwise create a new
1670
- * ID.
1671
- * @return The created block.
1672
- */
1673
- override newBlock(prototypeName: string, opt_id?: string): BlockSvg {
1674
- throw new Error(
1675
- 'The implementation of newBlock should be ' +
1676
- 'monkey-patched in by blockly.ts');
1677
- }
1678
-
1679
- /**
1680
- * Returns the drag target the mouse event is over.
1681
- * @param e Mouse move event.
1682
- * @return Null if not over a drag target, or the drag target the event is
1683
- * over.
1684
- */
1685
- getDragTarget(e: Event): IDragTarget|null {
1686
- for (let i = 0, targetArea; targetArea = this.dragTargetAreas_[i]; i++) {
1687
- // AnyDuringMigration because: Property 'clientY' does not exist on
1688
- // type 'Event'. AnyDuringMigration because: Property 'clientX' does
1689
- // not exist on type 'Event'.
1690
- if (targetArea.clientRect.contains(
1691
- (e as AnyDuringMigration).clientX,
1692
- (e as AnyDuringMigration).clientY)) {
1693
- return targetArea.component;
1694
- }
1695
- }
1696
- return null;
1697
- }
1698
-
1699
- /**
1700
- * Handle a mouse-down on SVG drawing surface.
1701
- * @param e Mouse down event.
1702
- */
1703
- private onMouseDown_(e: MouseEvent) {
1704
- const gesture = this.getGesture(e);
1705
- if (gesture) {
1706
- gesture.handleWsStart(e, this);
1707
- }
1708
- }
1709
-
1710
- /**
1711
- * Start tracking a drag of an object on this workspace.
1712
- * @param e Mouse down event.
1713
- * @param xy Starting location of object.
1714
- */
1715
- startDrag(e: MouseEvent, xy: Coordinate) {
1716
- // Record the starting offset between the bubble's location and the mouse.
1717
- const point = browserEvents.mouseToSvg(
1718
- e, this.getParentSvg(), this.getInverseScreenCTM());
1719
- // Fix scale of mouse event.
1720
- point.x /= this.scale;
1721
- point.y /= this.scale;
1722
- this.dragDeltaXY_ = Coordinate.difference(xy, point);
1723
- }
1724
-
1725
- /**
1726
- * Track a drag of an object on this workspace.
1727
- * @param e Mouse move event.
1728
- * @return New location of object.
1729
- */
1730
- moveDrag(e: MouseEvent): Coordinate {
1731
- const point = browserEvents.mouseToSvg(
1732
- e, this.getParentSvg(), this.getInverseScreenCTM());
1733
- // Fix scale of mouse event.
1734
- point.x /= this.scale;
1735
- point.y /= this.scale;
1736
- return Coordinate.sum((this.dragDeltaXY_), point);
1737
- }
1738
-
1739
- /**
1740
- * Is the user currently dragging a block or scrolling the flyout/workspace?
1741
- * @return True if currently dragging or scrolling.
1742
- */
1743
- isDragging(): boolean {
1744
- return this.currentGesture_ !== null && this.currentGesture_.isDragging();
1745
- }
1746
-
1747
- /**
1748
- * Is this workspace draggable?
1749
- * @return True if this workspace may be dragged.
1750
- */
1751
- isDraggable(): boolean {
1752
- return this.options.moveOptions && this.options.moveOptions.drag;
1753
- }
1754
-
1755
- /**
1756
- * Is this workspace movable?
1757
- *
1758
- * This means the user can reposition the X Y coordinates of the workspace
1759
- * through input. This can be through scrollbars, scroll wheel, dragging, or
1760
- * through zooming with the scroll wheel or pinch (since the zoom is centered
1761
- * on the mouse position). This does not include zooming with the zoom
1762
- * controls since the X Y coordinates are decided programmatically.
1763
- * @return True if the workspace is movable, false otherwise.
1764
- */
1765
- isMovable(): boolean {
1766
- return this.options.moveOptions && !!this.options.moveOptions.scrollbars ||
1767
- this.options.moveOptions && this.options.moveOptions.wheel ||
1768
- this.options.moveOptions && this.options.moveOptions.drag ||
1769
- this.options.zoomOptions && this.options.zoomOptions.wheel ||
1770
- this.options.zoomOptions && this.options.zoomOptions.pinch;
1771
- }
1772
-
1773
- /**
1774
- * Is this workspace movable horizontally?
1775
- * @return True if the workspace is movable horizontally, false otherwise.
1776
- */
1777
- isMovableHorizontally(): boolean {
1778
- const hasScrollbars = !!this.scrollbar;
1779
- return this.isMovable() &&
1780
- (!hasScrollbars ||
1781
- hasScrollbars && this.scrollbar.canScrollHorizontally());
1782
- }
1783
-
1784
- /**
1785
- * Is this workspace movable vertically?
1786
- * @return True if the workspace is movable vertically, false otherwise.
1787
- */
1788
- isMovableVertically(): boolean {
1789
- const hasScrollbars = !!this.scrollbar;
1790
- return this.isMovable() &&
1791
- (!hasScrollbars ||
1792
- hasScrollbars && this.scrollbar.canScrollVertically());
1793
- }
1794
-
1795
- /**
1796
- * Handle a mouse-wheel on SVG drawing surface.
1797
- * @param e Mouse wheel event.
1798
- */
1799
- private onMouseWheel_(e: WheelEvent) {
1800
- // Don't scroll or zoom anything if drag is in progress.
1801
- if (Gesture.inProgress()) {
1802
- e.preventDefault();
1803
- e.stopPropagation();
1804
- return;
1805
- }
1806
- const canWheelZoom =
1807
- this.options.zoomOptions && this.options.zoomOptions.wheel;
1808
- const canWheelMove =
1809
- this.options.moveOptions && this.options.moveOptions.wheel;
1810
- if (!canWheelZoom && !canWheelMove) {
1811
- return;
1812
- }
1813
-
1814
- const scrollDelta = browserEvents.getScrollDeltaPixels(e);
1815
-
1816
- // Zoom should also be enabled by the command key on Mac devices,
1817
- // but not super on Unix.
1818
- let commandKey;
1819
- if (userAgent.MAC) {
1820
- commandKey = e.metaKey;
1821
- }
1822
-
1823
- if (canWheelZoom && (e.ctrlKey || commandKey || !canWheelMove)) {
1824
- // Zoom.
1825
- // The vertical scroll distance that corresponds to a click of a zoom
1826
- // button.
1827
- const PIXELS_PER_ZOOM_STEP = 50;
1828
- const delta = -scrollDelta.y / PIXELS_PER_ZOOM_STEP;
1829
- const position = browserEvents.mouseToSvg(
1830
- e, this.getParentSvg(), this.getInverseScreenCTM());
1831
- this.zoom(position.x, position.y, delta);
1832
- } else {
1833
- // Scroll.
1834
- let x = this.scrollX - scrollDelta.x;
1835
- let y = this.scrollY - scrollDelta.y;
1836
-
1837
- if (e.shiftKey && !scrollDelta.x) {
1838
- // Scroll horizontally (based on vertical scroll delta).
1839
- // This is needed as for some browser/system combinations which do not
1840
- // set deltaX.
1841
- x = this.scrollX - scrollDelta.y;
1842
- y = this.scrollY; // Don't scroll vertically.
1843
- }
1844
- this.scroll(x, y);
1845
- }
1846
- e.preventDefault();
1847
- }
1848
-
1849
- /**
1850
- * Calculate the bounding box for the blocks on the workspace.
1851
- * Coordinate system: workspace coordinates.
1852
- *
1853
- * @return Contains the position and size of the bounding box containing the
1854
- * blocks on the workspace.
1855
- */
1856
- getBlocksBoundingBox(): Rect {
1857
- const topElements = this.getTopBoundedElements();
1858
- // There are no blocks, return empty rectangle.
1859
- if (!topElements.length) {
1860
- return new Rect(0, 0, 0, 0);
1861
- }
1862
-
1863
- // Initialize boundary using the first block.
1864
- const boundary = topElements[0].getBoundingRectangle();
1865
-
1866
- // Start at 1 since the 0th block was used for initialization.
1867
- for (let i = 1; i < topElements.length; i++) {
1868
- const topElement = topElements[i];
1869
- if ((topElement as AnyDuringMigration).isInsertionmarker &&
1870
- (topElement as AnyDuringMigration).isInsertionMarker()) {
1871
- continue;
1872
- }
1873
- const blockBoundary = topElement.getBoundingRectangle();
1874
- if (blockBoundary.top < boundary.top) {
1875
- boundary.top = blockBoundary.top;
1876
- }
1877
- if (blockBoundary.bottom > boundary.bottom) {
1878
- boundary.bottom = blockBoundary.bottom;
1879
- }
1880
- if (blockBoundary.left < boundary.left) {
1881
- boundary.left = blockBoundary.left;
1882
- }
1883
- if (blockBoundary.right > boundary.right) {
1884
- boundary.right = blockBoundary.right;
1885
- }
1886
- }
1887
- return boundary;
1888
- }
1889
-
1890
- /** Clean up the workspace by ordering all the blocks in a column. */
1891
- cleanUp() {
1892
- this.setResizesEnabled(false);
1893
- eventUtils.setGroup(true);
1894
- const topBlocks = this.getTopBlocks(true);
1895
- let cursorY = 0;
1896
- for (let i = 0, block; block = topBlocks[i]; i++) {
1897
- if (!block.isMovable()) {
1898
- continue;
1899
- }
1900
- const xy = block.getRelativeToSurfaceXY();
1901
- block.moveBy(-xy.x, cursorY - xy.y);
1902
- block.snapToGrid();
1903
- cursorY = block.getRelativeToSurfaceXY().y +
1904
- block.getHeightWidth().height +
1905
- this.renderer_.getConstants().MIN_BLOCK_HEIGHT;
1906
- }
1907
- eventUtils.setGroup(false);
1908
- this.setResizesEnabled(true);
1909
- }
1910
-
1911
- /**
1912
- * Show the context menu for the workspace.
1913
- * @param e Mouse event.
1914
- * @internal
1915
- */
1916
- showContextMenu(e: Event) {
1917
- if (this.options.readOnly || this.isFlyout) {
1918
- return;
1919
- }
1920
- // AnyDuringMigration because: Argument of type '{ workspace: this; }' is
1921
- // not assignable to parameter of type 'Scope'.
1922
- const menuOptions = ContextMenuRegistry.registry.getContextMenuOptions(
1923
- ContextMenuRegistry.ScopeType.WORKSPACE,
1924
- {workspace: this} as AnyDuringMigration);
1925
-
1926
- // Allow the developer to add or modify menuOptions.
1927
- if (this.configureContextMenu) {
1928
- this.configureContextMenu(menuOptions, e);
1929
- }
1930
-
1931
- ContextMenu.show(e, menuOptions, this.RTL);
1932
- }
1933
-
1934
- /**
1935
- * Modify the block tree on the existing toolbox.
1936
- * @param toolboxDef DOM tree of toolbox contents, string of toolbox contents,
1937
- * or JSON representing toolbox definition.
1938
- */
1939
- updateToolbox(toolboxDef: toolbox.ToolboxDefinition|null) {
1940
- const parsedToolboxDef = toolbox.convertToolboxDefToJson(toolboxDef);
1941
-
1942
- if (!parsedToolboxDef) {
1943
- if (this.options.languageTree) {
1944
- throw Error('Can\'t nullify an existing toolbox.');
1945
- }
1946
- return; // No change (null to null).
1947
- }
1948
- if (!this.options.languageTree) {
1949
- throw Error('Existing toolbox is null. Can\'t create new toolbox.');
1950
- }
1951
-
1952
- if (toolbox.hasCategories(parsedToolboxDef)) {
1953
- if (!this.toolbox_) {
1954
- throw Error('Existing toolbox has no categories. Can\'t change mode.');
1955
- }
1956
- this.options.languageTree = parsedToolboxDef;
1957
- this.toolbox_.render(parsedToolboxDef);
1958
- } else {
1959
- if (!this.flyout_) {
1960
- throw Error('Existing toolbox has categories. Can\'t change mode.');
1961
- }
1962
- this.options.languageTree = parsedToolboxDef;
1963
- this.flyout_.show(parsedToolboxDef);
1964
- }
1965
- }
1966
-
1967
- /** Mark this workspace as the currently focused main workspace. */
1968
- markFocused() {
1969
- if (this.options.parentWorkspace) {
1970
- this.options.parentWorkspace.markFocused();
1971
- } else {
1972
- // AnyDuringMigration because: Argument of type 'this' is not assignable
1973
- // to parameter of type 'Workspace'.
1974
- common.setMainWorkspace(this as AnyDuringMigration);
1975
- // We call e.preventDefault in many event handlers which means we
1976
- // need to explicitly grab focus (e.g from a textarea) because
1977
- // the browser will not do it for us. How to do this is browser
1978
- // dependent.
1979
- this.setBrowserFocus();
1980
- }
1981
- }
1982
-
1983
- /** Set the workspace to have focus in the browser. */
1984
- private setBrowserFocus() {
1985
- // Blur whatever was focused since explicitly grabbing focus below does not
1986
- // work in Edge.
1987
- // In IE, SVGs can't be blurred or focused. Check to make sure the current
1988
- // focus can be blurred before doing so.
1989
- // See https://github.com/google/blockly/issues/4440
1990
- // AnyDuringMigration because: Property 'blur' does not exist on type
1991
- // 'Element'.
1992
- if (document.activeElement &&
1993
- (document.activeElement as AnyDuringMigration).blur) {
1994
- // AnyDuringMigration because: Property 'blur' does not exist on type
1995
- // 'Element'.
1996
- (document.activeElement as AnyDuringMigration).blur();
1997
- }
1998
- try {
1999
- // Focus the workspace SVG - this is for Chrome and Firefox.
2000
- this.getParentSvg().focus({preventScroll: true});
2001
- } catch (e) {
2002
- // IE and Edge do not support focus on SVG elements. When that fails
2003
- // above, get the injectionDiv (the workspace's parent) and focus that
2004
- // instead. This doesn't work in Chrome.
2005
- try {
2006
- // In IE11, use setActive (which is IE only) so the page doesn't scroll
2007
- // to the workspace gaining focus.
2008
- (this.getParentSvg().parentElement as AnyDuringMigration).setActive();
2009
- } catch (e) {
2010
- // setActive support was discontinued in Edge so when that fails, call
2011
- // focus instead.
2012
- this.getParentSvg().parentElement!.focus({preventScroll: true});
2013
- }
2014
- }
2015
- }
2016
-
2017
- /**
2018
- * Zooms the workspace in or out relative to/centered on the given (x, y)
2019
- * coordinate.
2020
- * @param x X coordinate of center, in pixel units relative to the top-left
2021
- * corner of the parentSVG.
2022
- * @param y Y coordinate of center, in pixel units relative to the top-left
2023
- * corner of the parentSVG.
2024
- * @param amount Amount of zooming. The formula for the new scale is newScale
2025
- * = currentScale * (scaleSpeed^amount). scaleSpeed is set in the
2026
- * workspace options. Negative amount values zoom out, and positive amount
2027
- * values zoom in.
2028
- */
2029
- zoom(x: number, y: number, amount: number) {
2030
- // Scale factor.
2031
- const speed = this.options.zoomOptions.scaleSpeed;
2032
- let scaleChange = Math.pow(speed, amount);
2033
- const newScale = this.scale * scaleChange;
2034
- if (this.scale === newScale) {
2035
- return; // No change in zoom.
2036
- }
2037
-
2038
- // Clamp scale within valid range.
2039
- if (newScale > this.options.zoomOptions.maxScale) {
2040
- scaleChange = this.options.zoomOptions.maxScale / this.scale;
2041
- } else if (newScale < this.options.zoomOptions.minScale) {
2042
- scaleChange = this.options.zoomOptions.minScale / this.scale;
2043
- }
2044
-
2045
- // Transform the x/y coordinates from the parentSVG's space into the
2046
- // canvas' space, so that they are in workspace units relative to the top
2047
- // left of the visible portion of the workspace.
2048
- let matrix = this.getCanvas().getCTM();
2049
- let center = (this.getParentSvg()).createSVGPoint();
2050
- center.x = x;
2051
- center.y = y;
2052
- center = center.matrixTransform(matrix!.inverse());
2053
- x = center.x;
2054
- y = center.y;
2055
-
2056
- // Find the new scrollX/scrollY so that the center remains in the same
2057
- // position (relative to the center) after we zoom.
2058
- // newScale and matrix.a should be identical (within a rounding error).
2059
- matrix = matrix!.translate(x * (1 - scaleChange), y * (1 - scaleChange))
2060
- .scale(scaleChange);
2061
- // scrollX and scrollY are in pixels.
2062
- // The scrollX and scrollY still need to have absoluteLeft and absoluteTop
2063
- // subtracted from them, but we'll leave that for setScale so that they're
2064
- // correctly updated for the new flyout size if we have a simple toolbox.
2065
- this.scrollX = matrix.e;
2066
- this.scrollY = matrix.f;
2067
- this.setScale(newScale);
2068
- }
2069
-
2070
- /**
2071
- * Zooming the blocks centered in the center of view with zooming in or out.
2072
- * @param type Type of zooming (-1 zooming out and 1 zooming in).
2073
- */
2074
- zoomCenter(type: number) {
2075
- const metrics = this.getMetrics();
2076
- let x;
2077
- let y;
2078
- if (this.flyout_) {
2079
- // If you want blocks in the center of the view (visible portion of the
2080
- // workspace) to stay centered when the size of the view decreases (i.e.
2081
- // when the size of the flyout increases) you need the center of the
2082
- // *blockly div* to stay in the same pixel-position.
2083
- // Note: This only works because of how scrollCenter positions blocks.
2084
- x = metrics.svgWidth ? metrics.svgWidth / 2 : 0;
2085
- y = metrics.svgHeight ? metrics.svgHeight / 2 : 0;
2086
- } else {
2087
- x = metrics.viewWidth / 2 + metrics.absoluteLeft;
2088
- y = metrics.viewHeight / 2 + metrics.absoluteTop;
2089
- }
2090
- this.zoom(x, y, type);
2091
- }
2092
-
2093
- /** Zoom the blocks to fit in the workspace if possible. */
2094
- zoomToFit() {
2095
- if (!this.isMovable()) {
2096
- console.warn(
2097
- 'Tried to move a non-movable workspace. This could result' +
2098
- ' in blocks becoming inaccessible.');
2099
- return;
2100
- }
2101
-
2102
- const metrics = this.getMetrics();
2103
- let workspaceWidth = metrics.viewWidth;
2104
- let workspaceHeight = metrics.viewHeight;
2105
- const blocksBox = this.getBlocksBoundingBox();
2106
- const doubleMargin = ZOOM_TO_FIT_MARGIN * 2;
2107
- let blocksWidth = blocksBox.right - blocksBox.left + doubleMargin;
2108
- let blocksHeight = blocksBox.bottom - blocksBox.top + doubleMargin;
2109
- if (!blocksWidth) {
2110
- return; // Prevents zooming to infinity.
2111
- }
2112
- if (this.flyout_) {
2113
- // We have to add the flyout size to both the workspace size and the
2114
- // block size because the blocks we want to resize include the blocks in
2115
- // the flyout, and the area we want to fit them includes the portion of
2116
- // the workspace that is behind the flyout.
2117
- if (this.horizontalLayout) {
2118
- workspaceHeight += this.flyout_.getHeight();
2119
- // Convert from pixels to workspace coordinates.
2120
- blocksHeight += this.flyout_.getHeight() / this.scale;
2121
- } else {
2122
- workspaceWidth += this.flyout_.getWidth();
2123
- // Convert from pixels to workspace coordinates.
2124
- blocksWidth += this.flyout_.getWidth() / this.scale;
2125
- }
2126
- }
2127
-
2128
- // Scale Units: (pixels / workspaceUnit)
2129
- const ratioX = workspaceWidth / blocksWidth;
2130
- const ratioY = workspaceHeight / blocksHeight;
2131
- eventUtils.disable();
2132
- try {
2133
- this.setScale(Math.min(ratioX, ratioY));
2134
- this.scrollCenter();
2135
- } finally {
2136
- eventUtils.enable();
2137
- }
2138
- this.maybeFireViewportChangeEvent();
2139
- }
2140
-
2141
- /**
2142
- * Add a transition class to the block and bubble canvas, to animate any
2143
- * transform changes.
2144
- * @internal
2145
- */
2146
- beginCanvasTransition() {
2147
- dom.addClass((this.svgBlockCanvas_), 'blocklyCanvasTransitioning');
2148
- dom.addClass((this.svgBubbleCanvas_), 'blocklyCanvasTransitioning');
2149
- }
2150
-
2151
- /**
2152
- * Remove transition class from the block and bubble canvas.
2153
- * @internal
2154
- */
2155
- endCanvasTransition() {
2156
- dom.removeClass((this.svgBlockCanvas_), 'blocklyCanvasTransitioning');
2157
- dom.removeClass((this.svgBubbleCanvas_), 'blocklyCanvasTransitioning');
2158
- }
2159
-
2160
- /** Center the workspace. */
2161
- scrollCenter() {
2162
- if (!this.isMovable()) {
2163
- console.warn(
2164
- 'Tried to move a non-movable workspace. This could result' +
2165
- ' in blocks becoming inaccessible.');
2166
- return;
2167
- }
2168
-
2169
- const metrics = this.getMetrics();
2170
- let x = (metrics.scrollWidth - metrics.viewWidth) / 2;
2171
- let y = (metrics.scrollHeight - metrics.viewHeight) / 2;
2172
-
2173
- // Convert from workspace directions to canvas directions.
2174
- x = -x - metrics.scrollLeft;
2175
- y = -y - metrics.scrollTop;
2176
- this.scroll(x, y);
2177
- }
2178
-
2179
- /**
2180
- * Scroll the workspace to center on the given block. If the block has other
2181
- * blocks stacked below it, the workspace will be centered on the stack.
2182
- * @param id ID of block center on.
2183
- */
2184
- centerOnBlock(id: string|null) {
2185
- if (!this.isMovable()) {
2186
- console.warn(
2187
- 'Tried to move a non-movable workspace. This could result' +
2188
- ' in blocks becoming inaccessible.');
2189
- return;
2190
- }
2191
-
2192
- const block = id ? this.getBlockById(id) : null;
2193
- if (!block) {
2194
- return;
2195
- }
2196
-
2197
- // XY is in workspace coordinates.
2198
- const xy = block.getRelativeToSurfaceXY();
2199
- // Height/width is in workspace units.
2200
- const heightWidth = block.getHeightWidth();
2201
-
2202
- // Find the enter of the block in workspace units.
2203
- const blockCenterY = xy.y + heightWidth.height / 2;
2204
-
2205
- // In RTL the block's position is the top right of the block, not top left.
2206
- const multiplier = this.RTL ? -1 : 1;
2207
- const blockCenterX = xy.x + multiplier * heightWidth.width / 2;
2208
-
2209
- // Workspace scale, used to convert from workspace coordinates to pixels.
2210
- const scale = this.scale;
2211
-
2212
- // Center of block in pixels, relative to workspace origin (center 0,0).
2213
- // Scrolling to here would put the block in the top-left corner of the
2214
- // visible workspace.
2215
- const pixelX = blockCenterX * scale;
2216
- const pixelY = blockCenterY * scale;
2217
-
2218
- const metrics = this.getMetrics();
2219
-
2220
- // viewHeight and viewWidth are in pixels.
2221
- const halfViewWidth = metrics.viewWidth / 2;
2222
- const halfViewHeight = metrics.viewHeight / 2;
2223
-
2224
- // Put the block in the center of the visible workspace instead.
2225
- const scrollToCenterX = pixelX - halfViewWidth;
2226
- const scrollToCenterY = pixelY - halfViewHeight;
2227
-
2228
- // Convert from workspace directions to canvas directions.
2229
- const x = -scrollToCenterX;
2230
- const y = -scrollToCenterY;
2231
-
2232
- this.scroll(x, y);
2233
- }
2234
-
2235
- /**
2236
- * Set the workspace's zoom factor.
2237
- * @param newScale Zoom factor. Units: (pixels / workspaceUnit).
2238
- */
2239
- setScale(newScale: number) {
2240
- if (this.options.zoomOptions.maxScale &&
2241
- newScale > this.options.zoomOptions.maxScale) {
2242
- newScale = this.options.zoomOptions.maxScale;
2243
- } else if (
2244
- this.options.zoomOptions.minScale &&
2245
- newScale < this.options.zoomOptions.minScale) {
2246
- newScale = this.options.zoomOptions.minScale;
2247
- }
2248
- this.scale = newScale;
2249
-
2250
- this.hideChaff(false);
2251
- // Get the flyout, if any, whether our own or owned by the toolbox.
2252
- const flyout = this.getFlyout(false);
2253
- if (flyout && flyout.isVisible()) {
2254
- flyout.reflow();
2255
- this.recordDragTargets();
2256
- }
2257
- if (this.grid_) {
2258
- this.grid_.update(this.scale);
2259
- }
2260
-
2261
- // We call scroll instead of scrollbar.resize() so that we can center the
2262
- // zoom correctly without scrollbars, but scroll does not resize the
2263
- // scrollbars so we have to call resizeView/resizeContent as well.
2264
- const metrics = this.getMetrics();
2265
-
2266
- this.scrollX -= metrics.absoluteLeft;
2267
- this.scrollY -= metrics.absoluteTop;
2268
- // The scroll values and the view values are additive inverses of
2269
- // each other, so when we subtract from one we have to add to the other.
2270
- metrics.viewLeft += metrics.absoluteLeft;
2271
- metrics.viewTop += metrics.absoluteTop;
2272
-
2273
- this.scroll(this.scrollX, this.scrollY);
2274
- if (this.scrollbar) {
2275
- if (this.flyout_) {
2276
- this.scrollbar.resizeView(metrics);
2277
- } else {
2278
- this.scrollbar.resizeContent(metrics);
2279
- }
2280
- }
2281
- }
2282
-
2283
- /**
2284
- * Get the workspace's zoom factor. If the workspace has a parent, we call
2285
- * into the parent to get the workspace scale.
2286
- * @return The workspace zoom factor. Units: (pixels / workspaceUnit).
2287
- */
2288
- getScale(): number {
2289
- if (this.options.parentWorkspace) {
2290
- return this.options.parentWorkspace.getScale();
2291
- }
2292
- return this.scale;
2293
- }
2294
-
2295
- /**
2296
- * Scroll the workspace to a specified offset (in pixels), keeping in the
2297
- * workspace bounds. See comment on workspaceSvg.scrollX for more detail on
2298
- * the meaning of these values.
2299
- * @param x Target X to scroll to.
2300
- * @param y Target Y to scroll to.
2301
- * @internal
2302
- */
2303
- scroll(x: number, y: number) {
2304
- this.hideChaff(/* opt_onlyClosePopups= */
2305
- true);
2306
-
2307
- // Keep scrolling within the bounds of the content.
2308
- const metrics = this.getMetrics();
2309
- // Canvas coordinates (aka scroll coordinates) have inverse directionality
2310
- // to workspace coordinates so we have to inverse them.
2311
- x = Math.min(x, -metrics.scrollLeft);
2312
- y = Math.min(y, -metrics.scrollTop);
2313
- const maxXDisplacement =
2314
- Math.max(0, metrics.scrollWidth - metrics.viewWidth);
2315
- const maxXScroll = metrics.scrollLeft + maxXDisplacement;
2316
- const maxYDisplacement =
2317
- Math.max(0, metrics.scrollHeight - metrics.viewHeight);
2318
- const maxYScroll = metrics.scrollTop + maxYDisplacement;
2319
- x = Math.max(x, -maxXScroll);
2320
- y = Math.max(y, -maxYScroll);
2321
- this.scrollX = x;
2322
- this.scrollY = y;
2323
-
2324
- if (this.scrollbar) {
2325
- // The content position (displacement from the content's top-left to the
2326
- // origin) plus the scroll position (displacement from the view's top-left
2327
- // to the origin) gives us the distance from the view's top-left to the
2328
- // content's top-left. Then we negate this so we get the displacement from
2329
- // the content's top-left to the view's top-left, matching the
2330
- // directionality of the scrollbars.
2331
- this.scrollbar.set(
2332
- -(x + metrics.scrollLeft), -(y + metrics.scrollTop), false);
2333
- }
2334
- // We have to shift the translation so that when the canvas is at 0, 0 the
2335
- // workspace origin is not underneath the toolbox.
2336
- x += metrics.absoluteLeft;
2337
- y += metrics.absoluteTop;
2338
- this.translate(x, y);
2339
- }
2340
-
2341
- /**
2342
- * Find the block on this workspace with the specified ID.
2343
- * @param id ID of block to find.
2344
- * @return The sought after block, or null if not found.
2345
- */
2346
- override getBlockById(id: string): BlockSvg|null {
2347
- return super.getBlockById(id) as BlockSvg;
2348
- }
2349
-
2350
- /**
2351
- * Find all blocks in workspace. Blocks are optionally sorted
2352
- * by position; top to bottom (with slight LTR or RTL bias).
2353
- * @param ordered Sort the list if true.
2354
- * @return Array of blocks.
2355
- */
2356
- override getAllBlocks(ordered: boolean): BlockSvg[] {
2357
- return super.getAllBlocks(ordered) as BlockSvg[];
2358
- }
2359
-
2360
- /**
2361
- * Finds the top-level blocks and returns them. Blocks are optionally sorted
2362
- * by position; top to bottom (with slight LTR or RTL bias).
2363
- * @param ordered Sort the list if true.
2364
- * @return The top-level block objects.
2365
- */
2366
- override getTopBlocks(ordered: boolean): BlockSvg[] {
2367
- return super.getTopBlocks(ordered) as BlockSvg[];
2368
- }
2369
-
2370
- /**
2371
- * Adds a block to the list of top blocks.
2372
- * @param block Block to add.
2373
- */
2374
- override addTopBlock(block: Block) {
2375
- this.addTopBoundedElement(block as BlockSvg);
2376
- super.addTopBlock(block);
2377
- }
2378
-
2379
- /**
2380
- * Removes a block from the list of top blocks.
2381
- * @param block Block to remove.
2382
- */
2383
- override removeTopBlock(block: Block) {
2384
- this.removeTopBoundedElement(block as BlockSvg);
2385
- super.removeTopBlock(block);
2386
- }
2387
-
2388
- /**
2389
- * Adds a comment to the list of top comments.
2390
- * @param comment comment to add.
2391
- */
2392
- override addTopComment(comment: WorkspaceComment) {
2393
- this.addTopBoundedElement(comment as WorkspaceCommentSvg);
2394
- super.addTopComment(comment);
2395
- }
2396
-
2397
- /**
2398
- * Removes a comment from the list of top comments.
2399
- * @param comment comment to remove.
2400
- */
2401
- override removeTopComment(comment: WorkspaceComment) {
2402
- this.removeTopBoundedElement(comment as WorkspaceCommentSvg);
2403
- super.removeTopComment(comment);
2404
- }
2405
-
2406
- /**
2407
- * Adds a bounded element to the list of top bounded elements.
2408
- * @param element Bounded element to add.
2409
- */
2410
- addTopBoundedElement(element: IBoundedElement) {
2411
- this.topBoundedElements_.push(element);
2412
- }
2413
-
2414
- /**
2415
- * Removes a bounded element from the list of top bounded elements.
2416
- * @param element Bounded element to remove.
2417
- */
2418
- removeTopBoundedElement(element: IBoundedElement) {
2419
- arrayUtils.removeElem(this.topBoundedElements_, element);
2420
- }
2421
-
2422
- /**
2423
- * Finds the top-level bounded elements and returns them.
2424
- * @return The top-level bounded elements.
2425
- */
2426
- getTopBoundedElements(): IBoundedElement[] {
2427
- return (new Array<IBoundedElement>()).concat(this.topBoundedElements_);
2428
- }
2429
-
2430
- /**
2431
- * Update whether this workspace has resizes enabled.
2432
- * If enabled, workspace will resize when appropriate.
2433
- * If disabled, workspace will not resize until re-enabled.
2434
- * Use to avoid resizing during a batch operation, for performance.
2435
- * @param enabled Whether resizes should be enabled.
2436
- */
2437
- setResizesEnabled(enabled: boolean) {
2438
- const reenabled = !this.resizesEnabled_ && enabled;
2439
- this.resizesEnabled_ = enabled;
2440
- if (reenabled) {
2441
- // Newly enabled. Trigger a resize.
2442
- this.resizeContents();
2443
- }
2444
- }
2445
-
2446
- /**
2447
- * Dispose of all blocks in workspace, with an optimization to prevent
2448
- * resizes.
2449
- */
2450
- override clear() {
2451
- this.setResizesEnabled(false);
2452
- super.clear();
2453
- this.topBoundedElements_ = [];
2454
- this.setResizesEnabled(true);
2455
- }
2456
-
2457
- /**
2458
- * Register a callback function associated with a given key, for clicks on
2459
- * buttons and labels in the flyout.
2460
- * For instance, a button specified by the XML
2461
- * <button text="create variable" callbackKey="CREATE_VARIABLE"></button>
2462
- * should be matched by a call to
2463
- * registerButtonCallback("CREATE_VARIABLE", yourCallbackFunction).
2464
- * @param key The name to use to look up this function.
2465
- * @param func The function to call when the given button is clicked.
2466
- */
2467
- registerButtonCallback(
2468
- key: string, func: (p1: FlyoutButton) => AnyDuringMigration) {
2469
- if (typeof func !== 'function') {
2470
- throw TypeError('Button callbacks must be functions.');
2471
- }
2472
- this.flyoutButtonCallbacks_[key] = func;
2473
- }
2474
-
2475
- /**
2476
- * Get the callback function associated with a given key, for clicks on
2477
- * buttons and labels in the flyout.
2478
- * @param key The name to use to look up the function.
2479
- * @return The function corresponding to the given key for this workspace;
2480
- * null if no callback is registered.
2481
- */
2482
- getButtonCallback(key: string):
2483
- ((p1: FlyoutButton) => AnyDuringMigration)|null {
2484
- const result = this.flyoutButtonCallbacks_[key];
2485
- return result ? result : null;
2486
- }
2487
-
2488
- /**
2489
- * Remove a callback for a click on a button in the flyout.
2490
- * @param key The name associated with the callback function.
2491
- */
2492
- removeButtonCallback(key: string) {
2493
- this.flyoutButtonCallbacks_[key] = null;
2494
- }
2495
-
2496
- /**
2497
- * Register a callback function associated with a given key, for populating
2498
- * custom toolbox categories in this workspace. See the variable and
2499
- * procedure categories as an example.
2500
- * @param key The name to use to look up this function.
2501
- * @param func The function to call when the given toolbox category is opened.
2502
- */
2503
- registerToolboxCategoryCallback(
2504
- key: string, func: (p1: WorkspaceSvg) => toolbox.FlyoutDefinition) {
2505
- if (typeof func !== 'function') {
2506
- throw TypeError('Toolbox category callbacks must be functions.');
2507
- }
2508
- this.toolboxCategoryCallbacks_[key] = func;
2509
- }
2510
-
2511
- /**
2512
- * Get the callback function associated with a given key, for populating
2513
- * custom toolbox categories in this workspace.
2514
- * @param key The name to use to look up the function.
2515
- * @return The function corresponding to the given key for this workspace, or
2516
- * null if no function is registered.
2517
- */
2518
- getToolboxCategoryCallback(key: string):
2519
- ((p1: WorkspaceSvg) => toolbox.FlyoutDefinition)|null {
2520
- return this.toolboxCategoryCallbacks_[key] || null;
2521
- }
2522
-
2523
- /**
2524
- * Remove a callback for a click on a custom category's name in the toolbox.
2525
- * @param key The name associated with the callback function.
2526
- */
2527
- removeToolboxCategoryCallback(key: string) {
2528
- this.toolboxCategoryCallbacks_[key] = null;
2529
- }
2530
-
2531
- /**
2532
- * Look up the gesture that is tracking this touch stream on this workspace.
2533
- * May create a new gesture.
2534
- * @param e Mouse event or touch event.
2535
- * @return The gesture that is tracking this touch stream, or null if no valid
2536
- * gesture exists.
2537
- * @internal
2538
- */
2539
- getGesture(e: Event): TouchGesture|null {
2540
- const isStart = e.type === 'mousedown' || e.type === 'touchstart' ||
2541
- e.type === 'pointerdown';
2542
-
2543
- const gesture = this.currentGesture_;
2544
- if (gesture) {
2545
- if (isStart && gesture.hasStarted()) {
2546
- console.warn('Tried to start the same gesture twice.');
2547
- // That's funny. We must have missed a mouse up.
2548
- // Cancel it, rather than try to retrieve all of the state we need.
2549
- gesture.cancel();
2550
- return null;
2551
- }
2552
- return gesture;
2553
- }
2554
-
2555
- // No gesture existed on this workspace, but this looks like the start of a
2556
- // new gesture.
2557
- if (isStart) {
2558
- this.currentGesture_ = new TouchGesture(e, this);
2559
- return this.currentGesture_;
2560
- }
2561
- // No gesture existed and this event couldn't be the start of a new gesture.
2562
- return null;
2563
- }
2564
-
2565
- /**
2566
- * Clear the reference to the current gesture.
2567
- * @internal
2568
- */
2569
- clearGesture() {
2570
- // AnyDuringMigration because: Type 'null' is not assignable to type
2571
- // 'TouchGesture'.
2572
- this.currentGesture_ = null as AnyDuringMigration;
2573
- }
2574
-
2575
- /**
2576
- * Cancel the current gesture, if one exists.
2577
- * @internal
2578
- */
2579
- cancelCurrentGesture() {
2580
- if (this.currentGesture_) {
2581
- this.currentGesture_.cancel();
2582
- }
2583
- }
2584
-
2585
- /**
2586
- * Get the audio manager for this workspace.
2587
- * @return The audio manager for this workspace.
2588
- */
2589
- getAudioManager(): WorkspaceAudio {
2590
- return this.audioManager_;
2591
- }
2592
-
2593
- /**
2594
- * Get the grid object for this workspace, or null if there is none.
2595
- * @return The grid object for this workspace.
2596
- * @internal
2597
- */
2598
- getGrid(): Grid|null {
2599
- return this.grid_;
2600
- }
2601
-
2602
- /**
2603
- * Close tooltips, context menus, dropdown selections, etc.
2604
- * @param opt_onlyClosePopups Whether only popups should be closed.
2605
- */
2606
- hideChaff(opt_onlyClosePopups?: boolean) {
2607
- Tooltip.hide();
2608
- WidgetDiv.hide();
2609
- dropDownDiv.hideWithoutAnimation();
2610
-
2611
- const onlyClosePopups = !!opt_onlyClosePopups;
2612
- const autoHideables = this.getComponentManager().getComponents(
2613
- ComponentManager.Capability.AUTOHIDEABLE, true);
2614
- autoHideables.forEach(
2615
- (autoHideable) => autoHideable.autoHide(onlyClosePopups));
2616
- }
2617
-
2618
- /**
2619
- * Sets the X/Y translations of a top level workspace.
2620
- * @param xyRatio Contains an x and/or y property which is a float between 0
2621
- * and 1 specifying the degree of scrolling.
2622
- */
2623
- private static setTopLevelWorkspaceMetrics_(
2624
- this: WorkspaceSvg, xyRatio: AnyDuringMigration) {
2625
- const metrics = this.getMetrics();
2626
-
2627
- if (typeof xyRatio.x === 'number') {
2628
- this.scrollX =
2629
- -(metrics.scrollLeft +
2630
- (metrics.scrollWidth - metrics.viewWidth) * xyRatio.x);
2631
- }
2632
- if (typeof xyRatio.y === 'number') {
2633
- this.scrollY =
2634
- -(metrics.scrollTop +
2635
- (metrics.scrollHeight - metrics.viewHeight) * xyRatio.y);
2636
- }
2637
- // We have to shift the translation so that when the canvas is at 0, 0 the
2638
- // workspace origin is not underneath the toolbox.
2639
- const x = this.scrollX + metrics.absoluteLeft;
2640
- const y = this.scrollY + metrics.absoluteTop;
2641
- // We could call scroll here, but that has extra checks we don't need to do.
2642
- this.translate(x, y);
2643
- }
2644
- }
2645
-
2646
- /**
2647
- * Size the workspace when the contents change. This also updates
2648
- * scrollbars accordingly.
2649
- * @param workspace The workspace to resize.
2650
- * @alias Blockly.WorkspaceSvg.resizeSvgContents
2651
- * @internal
2652
- */
2653
- export function resizeSvgContents(workspace: WorkspaceSvg) {
2654
- workspace.resizeContents();
2655
- }