blockly 7.20211209.2 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (262) hide show
  1. package/blockly.d.ts +18963 -18432
  2. package/blockly.min.js +852 -844
  3. package/blockly_compressed.js +669 -664
  4. package/blockly_compressed.js.map +1 -1
  5. package/blocks/blocks.js +47 -0
  6. package/blocks/colour.js +13 -3
  7. package/blocks/lists.js +22 -13
  8. package/blocks/logic.js +13 -3
  9. package/blocks/loops.js +24 -11
  10. package/blocks/math.js +12 -3
  11. package/blocks/procedures.js +41 -27
  12. package/blocks/text.js +22 -13
  13. package/blocks/variables.js +14 -3
  14. package/blocks/variables_dynamic.js +13 -3
  15. package/blocks_compressed.js +146 -141
  16. package/blocks_compressed.js.map +1 -1
  17. package/core/block.js +1869 -1814
  18. package/core/block_drag_surface.js +201 -200
  19. package/core/block_dragger.js +377 -373
  20. package/core/block_svg.js +1593 -1479
  21. package/core/blockly.js +8 -22
  22. package/core/blocks.js +9 -2
  23. package/core/browser_events.js +22 -5
  24. package/core/bubble.js +841 -797
  25. package/core/bubble_dragger.js +213 -206
  26. package/core/bump_objects.js +2 -2
  27. package/core/clipboard.js +9 -9
  28. package/core/comment.js +353 -332
  29. package/core/common.js +46 -17
  30. package/core/component_manager.js +181 -174
  31. package/core/config.js +87 -0
  32. package/core/connection.js +595 -584
  33. package/core/connection_checker.js +242 -244
  34. package/core/connection_db.js +235 -230
  35. package/core/contextmenu.js +9 -6
  36. package/core/contextmenu_items.js +1 -2
  37. package/core/contextmenu_registry.js +93 -89
  38. package/core/css.js +474 -474
  39. package/core/delete_area.js +45 -42
  40. package/core/drag_target.js +57 -56
  41. package/core/dropdowndiv.js +153 -163
  42. package/core/events/events.js +2 -2
  43. package/core/events/events_abstract.js +89 -77
  44. package/core/events/events_block_base.js +37 -36
  45. package/core/events/events_block_change.js +130 -124
  46. package/core/events/events_block_create.js +73 -71
  47. package/core/events/events_block_delete.js +84 -82
  48. package/core/events/events_block_drag.js +50 -49
  49. package/core/events/events_block_move.js +147 -140
  50. package/core/events/events_bubble_open.js +51 -50
  51. package/core/events/events_click.js +48 -44
  52. package/core/events/events_comment_base.js +72 -69
  53. package/core/events/events_comment_change.js +63 -61
  54. package/core/events/events_comment_create.js +44 -42
  55. package/core/events/events_comment_delete.js +42 -40
  56. package/core/events/events_comment_move.js +106 -104
  57. package/core/events/events_marker_move.js +65 -64
  58. package/core/events/events_selected.js +46 -45
  59. package/core/events/events_theme_change.js +36 -35
  60. package/core/events/events_toolbox_item_select.js +46 -45
  61. package/core/events/events_trashcan_open.js +37 -36
  62. package/core/events/events_ui.js +47 -46
  63. package/core/events/events_ui_base.js +30 -29
  64. package/core/events/events_var_base.js +37 -36
  65. package/core/events/events_var_create.js +50 -48
  66. package/core/events/events_var_delete.js +50 -48
  67. package/core/events/events_var_rename.js +51 -49
  68. package/core/events/events_viewport.js +66 -65
  69. package/core/events/utils.js +29 -14
  70. package/core/events/workspace_events.js +49 -55
  71. package/core/extensions.js +4 -3
  72. package/core/field.js +1061 -997
  73. package/core/field_angle.js +462 -442
  74. package/core/field_checkbox.js +194 -182
  75. package/core/field_colour.js +519 -505
  76. package/core/field_dropdown.js +617 -598
  77. package/core/field_image.js +229 -220
  78. package/core/field_label.js +102 -91
  79. package/core/field_label_serializable.js +42 -41
  80. package/core/field_multilineinput.js +372 -358
  81. package/core/field_number.js +272 -253
  82. package/core/field_textinput.js +499 -467
  83. package/core/field_variable.js +458 -420
  84. package/core/flyout_base.js +1005 -952
  85. package/core/flyout_button.js +277 -260
  86. package/core/flyout_horizontal.js +304 -302
  87. package/core/flyout_metrics_manager.js +64 -64
  88. package/core/flyout_vertical.js +306 -300
  89. package/core/generator.js +459 -446
  90. package/core/gesture.js +829 -813
  91. package/core/grid.js +166 -163
  92. package/core/icon.js +168 -159
  93. package/core/inject.js +7 -5
  94. package/core/input.js +257 -248
  95. package/core/insertion_marker_manager.js +655 -624
  96. package/core/internal_constants.js +0 -129
  97. package/core/keyboard_nav/ast_node.js +605 -596
  98. package/core/keyboard_nav/basic_cursor.js +166 -165
  99. package/core/keyboard_nav/cursor.js +99 -97
  100. package/core/keyboard_nav/marker.js +83 -79
  101. package/core/keyboard_nav/tab_navigate_cursor.js +18 -23
  102. package/core/marker_manager.js +153 -141
  103. package/core/menu.js +377 -372
  104. package/core/menuitem.js +223 -217
  105. package/core/metrics_manager.js +403 -390
  106. package/core/mutator.js +468 -437
  107. package/core/names.js +229 -188
  108. package/core/options.js +290 -284
  109. package/core/procedures.js +29 -17
  110. package/core/registry.js +19 -16
  111. package/core/rendered_connection.js +482 -463
  112. package/core/renderers/common/block_rendering.js +9 -3
  113. package/core/renderers/common/constants.js +1119 -1112
  114. package/core/renderers/common/debug.js +14 -0
  115. package/core/renderers/common/debugger.js +338 -316
  116. package/core/renderers/common/drawer.js +380 -370
  117. package/core/renderers/common/i_path_object.js +2 -2
  118. package/core/renderers/common/info.js +626 -618
  119. package/core/renderers/common/marker_svg.js +579 -541
  120. package/core/renderers/common/path_object.js +203 -200
  121. package/core/renderers/common/renderer.js +220 -218
  122. package/core/renderers/geras/constants.js +36 -36
  123. package/core/renderers/geras/drawer.js +155 -147
  124. package/core/renderers/geras/highlight_constants.js +244 -238
  125. package/core/renderers/geras/highlighter.js +231 -179
  126. package/core/renderers/geras/info.js +392 -369
  127. package/core/renderers/geras/measurables/inline_input.js +25 -19
  128. package/core/renderers/geras/measurables/statement_input.js +23 -17
  129. package/core/renderers/geras/path_object.js +106 -121
  130. package/core/renderers/geras/renderer.js +96 -98
  131. package/core/renderers/measurables/base.js +30 -18
  132. package/core/renderers/measurables/bottom_row.js +83 -80
  133. package/core/renderers/measurables/connection.js +22 -15
  134. package/core/renderers/measurables/external_value_input.js +35 -22
  135. package/core/renderers/measurables/field.js +35 -20
  136. package/core/renderers/measurables/hat.js +18 -13
  137. package/core/renderers/measurables/icon.js +24 -17
  138. package/core/renderers/measurables/in_row_spacer.js +15 -13
  139. package/core/renderers/measurables/inline_input.js +43 -33
  140. package/core/renderers/measurables/input_connection.js +41 -28
  141. package/core/renderers/measurables/input_row.js +50 -44
  142. package/core/renderers/measurables/jagged_edge.js +14 -12
  143. package/core/renderers/measurables/next_connection.js +16 -14
  144. package/core/renderers/measurables/output_connection.js +26 -20
  145. package/core/renderers/measurables/previous_connection.js +16 -15
  146. package/core/renderers/measurables/round_corner.js +20 -18
  147. package/core/renderers/measurables/row.js +184 -168
  148. package/core/renderers/measurables/spacer_row.js +38 -23
  149. package/core/renderers/measurables/square_corner.js +18 -16
  150. package/core/renderers/measurables/statement_input.js +23 -20
  151. package/core/renderers/measurables/top_row.js +88 -85
  152. package/core/renderers/minimalist/constants.js +8 -7
  153. package/core/renderers/minimalist/drawer.js +11 -10
  154. package/core/renderers/minimalist/info.js +18 -18
  155. package/core/renderers/minimalist/renderer.js +40 -39
  156. package/core/renderers/thrasos/info.js +258 -248
  157. package/core/renderers/thrasos/renderer.js +20 -20
  158. package/core/renderers/zelos/constants.js +898 -873
  159. package/core/renderers/zelos/drawer.js +186 -169
  160. package/core/renderers/zelos/info.js +502 -479
  161. package/core/renderers/zelos/marker_svg.js +129 -115
  162. package/core/renderers/zelos/measurables/bottom_row.js +31 -30
  163. package/core/renderers/zelos/measurables/inputs.js +22 -21
  164. package/core/renderers/zelos/measurables/row_elements.js +14 -13
  165. package/core/renderers/zelos/measurables/top_row.js +34 -33
  166. package/core/renderers/zelos/path_object.js +181 -180
  167. package/core/renderers/zelos/renderer.js +91 -92
  168. package/core/scrollbar.js +759 -713
  169. package/core/scrollbar_pair.js +250 -245
  170. package/core/serialization/blocks.js +19 -9
  171. package/core/serialization/workspaces.js +3 -2
  172. package/core/shortcut_registry.js +286 -277
  173. package/core/sprites.js +31 -0
  174. package/core/theme.js +135 -141
  175. package/core/theme_manager.js +147 -143
  176. package/core/toolbox/category.js +602 -576
  177. package/core/toolbox/collapsible_category.js +226 -227
  178. package/core/toolbox/separator.js +70 -61
  179. package/core/toolbox/toolbox.js +934 -927
  180. package/core/toolbox/toolbox_item.js +115 -99
  181. package/core/tooltip.js +108 -35
  182. package/core/touch.js +8 -3
  183. package/core/touch_gesture.js +254 -251
  184. package/core/trashcan.js +606 -595
  185. package/core/utils/coordinate.js +97 -95
  186. package/core/utils/dom.js +2 -2
  187. package/core/utils/global.js +2 -0
  188. package/core/utils/rect.js +41 -37
  189. package/core/utils/sentinel.js +25 -0
  190. package/core/utils/size.js +30 -27
  191. package/core/utils/svg.js +18 -16
  192. package/core/variable_map.js +325 -341
  193. package/core/variable_model.js +55 -54
  194. package/core/variables.js +9 -2
  195. package/core/variables_dynamic.js +3 -1
  196. package/core/warning.js +126 -120
  197. package/core/widgetdiv.js +4 -4
  198. package/core/workspace.js +685 -664
  199. package/core/workspace_audio.js +124 -118
  200. package/core/workspace_comment.js +308 -298
  201. package/core/workspace_comment_svg.js +1029 -951
  202. package/core/workspace_drag_surface_svg.js +147 -140
  203. package/core/workspace_dragger.js +70 -71
  204. package/core/workspace_svg.js +2322 -2297
  205. package/core/xml.js +30 -20
  206. package/core/zoom_controls.js +431 -439
  207. package/dart_compressed.js +40 -43
  208. package/dart_compressed.js.map +1 -1
  209. package/generators/dart/colour.js +56 -64
  210. package/generators/dart/lists.js +61 -50
  211. package/generators/dart/math.js +160 -148
  212. package/generators/dart/text.js +83 -61
  213. package/generators/javascript/colour.js +37 -34
  214. package/generators/javascript/lists.js +50 -43
  215. package/generators/javascript/math.js +123 -139
  216. package/generators/javascript/text.js +67 -81
  217. package/generators/lua/colour.js +25 -23
  218. package/generators/lua/lists.js +97 -69
  219. package/generators/lua/logic.js +1 -2
  220. package/generators/lua/math.js +182 -144
  221. package/generators/lua/text.js +116 -99
  222. package/generators/php/colour.js +38 -32
  223. package/generators/php/lists.js +109 -89
  224. package/generators/php/math.js +90 -81
  225. package/generators/php/text.js +63 -61
  226. package/generators/python/colour.js +18 -18
  227. package/generators/python/lists.js +38 -30
  228. package/generators/python/loops.js +12 -8
  229. package/generators/python/math.js +104 -106
  230. package/generators/python/text.js +34 -30
  231. package/javascript_compressed.js +37 -39
  232. package/javascript_compressed.js.map +1 -1
  233. package/lua_compressed.js +39 -42
  234. package/lua_compressed.js.map +1 -1
  235. package/msg/az.js +2 -2
  236. package/msg/be.js +4 -4
  237. package/msg/cs.js +15 -15
  238. package/msg/de.js +1 -1
  239. package/msg/diq.js +1 -1
  240. package/msg/eo.js +1 -1
  241. package/msg/es.js +1 -1
  242. package/msg/fa.js +1 -1
  243. package/msg/fr.js +4 -4
  244. package/msg/he.js +1 -1
  245. package/msg/hr.js +2 -2
  246. package/msg/hy.js +2 -2
  247. package/msg/id.js +12 -12
  248. package/msg/inh.js +14 -14
  249. package/msg/ja.js +7 -7
  250. package/msg/lv.js +29 -29
  251. package/msg/pa.js +3 -3
  252. package/msg/smn.js +436 -0
  253. package/msg/te.js +1 -1
  254. package/msg/yue.js +1 -1
  255. package/msg/zh-hans.js +3 -3
  256. package/msg/zh-hant.js +3 -3
  257. package/package.json +7 -6
  258. package/php_compressed.js +38 -42
  259. package/php_compressed.js.map +1 -1
  260. package/python_compressed.js +26 -25
  261. package/python_compressed.js.map +1 -1
  262. package/blocks/all.js +0 -23
@@ -27,297 +27,302 @@ const {WorkspaceSvg} = goog.requireType('Blockly.WorkspaceSvg');
27
27
 
28
28
  /**
29
29
  * Class for a pair of scrollbars. Horizontal and vertical.
30
- * @param {!WorkspaceSvg} workspace Workspace to bind the scrollbars to.
31
- * @param {boolean=} addHorizontal Whether to add a horizontal scrollbar.
32
- * Defaults to true.
33
- * @param {boolean=} addVertical Whether to add a vertical scrollbar. Defaults
34
- * to true.
35
- * @param {string=} opt_class A class to be applied to these scrollbars.
36
- * @param {number=} opt_margin The margin to apply to these scrollbars.
37
- * @constructor
38
30
  * @alias Blockly.ScrollbarPair
39
31
  */
40
- const ScrollbarPair = function(
41
- workspace, addHorizontal, addVertical, opt_class, opt_margin) {
32
+ const ScrollbarPair = class {
42
33
  /**
43
- * The workspace this scrollbar pair is bound to.
44
- * @type {!WorkspaceSvg}
45
- * @private
34
+ * @param {!WorkspaceSvg} workspace Workspace to bind the scrollbars to.
35
+ * @param {boolean=} addHorizontal Whether to add a horizontal scrollbar.
36
+ * Defaults to true.
37
+ * @param {boolean=} addVertical Whether to add a vertical scrollbar. Defaults
38
+ * to true.
39
+ * @param {string=} opt_class A class to be applied to these scrollbars.
40
+ * @param {number=} opt_margin The margin to apply to these scrollbars.
46
41
  */
47
- this.workspace_ = workspace;
42
+ constructor(workspace, addHorizontal, addVertical, opt_class, opt_margin) {
43
+ /**
44
+ * The workspace this scrollbar pair is bound to.
45
+ * @type {!WorkspaceSvg}
46
+ * @private
47
+ */
48
+ this.workspace_ = workspace;
48
49
 
49
- addHorizontal = addHorizontal === undefined ? true : addHorizontal;
50
- addVertical = addVertical === undefined ? true : addVertical;
51
- const isPair = addHorizontal && addVertical;
50
+ addHorizontal = addHorizontal === undefined ? true : addHorizontal;
51
+ addVertical = addVertical === undefined ? true : addVertical;
52
+ const isPair = addHorizontal && addVertical;
52
53
 
53
- if (addHorizontal) {
54
- this.hScroll =
55
- new Scrollbar(workspace, true, isPair, opt_class, opt_margin);
56
- }
57
- if (addVertical) {
58
- this.vScroll =
59
- new Scrollbar(workspace, false, isPair, opt_class, opt_margin);
60
- }
54
+ if (addHorizontal) {
55
+ this.hScroll =
56
+ new Scrollbar(workspace, true, isPair, opt_class, opt_margin);
57
+ }
58
+ if (addVertical) {
59
+ this.vScroll =
60
+ new Scrollbar(workspace, false, isPair, opt_class, opt_margin);
61
+ }
61
62
 
62
- if (isPair) {
63
- this.corner_ = dom.createSvgElement(
64
- Svg.RECT, {
65
- 'height': Scrollbar.scrollbarThickness,
66
- 'width': Scrollbar.scrollbarThickness,
67
- 'class': 'blocklyScrollbarBackground',
68
- },
69
- null);
70
- dom.insertAfter(this.corner_, workspace.getBubbleCanvas());
63
+ if (isPair) {
64
+ this.corner_ = dom.createSvgElement(
65
+ Svg.RECT, {
66
+ 'height': Scrollbar.scrollbarThickness,
67
+ 'width': Scrollbar.scrollbarThickness,
68
+ 'class': 'blocklyScrollbarBackground',
69
+ },
70
+ null);
71
+ dom.insertAfter(this.corner_, workspace.getBubbleCanvas());
72
+ }
73
+
74
+ /**
75
+ * Previously recorded metrics from the workspace.
76
+ * @type {?Metrics}
77
+ * @private
78
+ */
79
+ this.oldHostMetrics_ = null;
71
80
  }
72
81
 
73
82
  /**
74
- * Previously recorded metrics from the workspace.
75
- * @type {?Metrics}
76
- * @private
83
+ * Dispose of this pair of scrollbars.
84
+ * Unlink from all DOM elements to prevent memory leaks.
85
+ * @suppress {checkTypes}
77
86
  */
78
- this.oldHostMetrics_ = null;
79
- };
80
-
81
- /**
82
- * Dispose of this pair of scrollbars.
83
- * Unlink from all DOM elements to prevent memory leaks.
84
- * @suppress {checkTypes}
85
- */
86
- ScrollbarPair.prototype.dispose = function() {
87
- dom.removeNode(this.corner_);
88
- this.corner_ = null;
89
- this.workspace_ = null;
90
- this.oldHostMetrics_ = null;
91
- if (this.hScroll) {
92
- this.hScroll.dispose();
93
- this.hScroll = null;
94
- }
95
- if (this.vScroll) {
96
- this.vScroll.dispose();
97
- this.vScroll = null;
98
- }
99
- };
100
-
101
- /**
102
- * Recalculate both of the scrollbars' locations and lengths.
103
- * Also reposition the corner rectangle.
104
- */
105
- ScrollbarPair.prototype.resize = function() {
106
- // Look up the host metrics once, and use for both scrollbars.
107
- const hostMetrics = this.workspace_.getMetrics();
108
- if (!hostMetrics) {
109
- // Host element is likely not visible.
110
- return;
111
- }
112
-
113
- // Only change the scrollbars if there has been a change in metrics.
114
- let resizeH = false;
115
- let resizeV = false;
116
- if (!this.oldHostMetrics_ ||
117
- this.oldHostMetrics_.viewWidth !== hostMetrics.viewWidth ||
118
- this.oldHostMetrics_.viewHeight !== hostMetrics.viewHeight ||
119
- this.oldHostMetrics_.absoluteTop !== hostMetrics.absoluteTop ||
120
- this.oldHostMetrics_.absoluteLeft !== hostMetrics.absoluteLeft) {
121
- // The window has been resized or repositioned.
122
- resizeH = true;
123
- resizeV = true;
124
- } else {
125
- // Has the content been resized or moved?
126
- if (!this.oldHostMetrics_ ||
127
- this.oldHostMetrics_.scrollWidth !== hostMetrics.scrollWidth ||
128
- this.oldHostMetrics_.viewLeft !== hostMetrics.viewLeft ||
129
- this.oldHostMetrics_.scrollLeft !== hostMetrics.scrollLeft) {
130
- resizeH = true;
87
+ dispose() {
88
+ dom.removeNode(this.corner_);
89
+ this.corner_ = null;
90
+ this.workspace_ = null;
91
+ this.oldHostMetrics_ = null;
92
+ if (this.hScroll) {
93
+ this.hScroll.dispose();
94
+ this.hScroll = null;
131
95
  }
132
- if (!this.oldHostMetrics_ ||
133
- this.oldHostMetrics_.scrollHeight !== hostMetrics.scrollHeight ||
134
- this.oldHostMetrics_.viewTop !== hostMetrics.viewTop ||
135
- this.oldHostMetrics_.scrollTop !== hostMetrics.scrollTop) {
136
- resizeV = true;
96
+ if (this.vScroll) {
97
+ this.vScroll.dispose();
98
+ this.vScroll = null;
137
99
  }
138
100
  }
139
101
 
140
- if (resizeH || resizeV) {
141
- try {
142
- eventUtils.disable();
143
- if (this.hScroll && resizeH) {
144
- this.hScroll.resize(hostMetrics);
145
- }
146
- if (this.vScroll && resizeV) {
147
- this.vScroll.resize(hostMetrics);
148
- }
149
- } finally {
150
- eventUtils.enable();
102
+ /**
103
+ * Recalculate both of the scrollbars' locations and lengths.
104
+ * Also reposition the corner rectangle.
105
+ */
106
+ resize() {
107
+ // Look up the host metrics once, and use for both scrollbars.
108
+ const hostMetrics = this.workspace_.getMetrics();
109
+ if (!hostMetrics) {
110
+ // Host element is likely not visible.
111
+ return;
151
112
  }
152
- this.workspace_.maybeFireViewportChangeEvent();
153
- }
154
113
 
155
- if (this.hScroll && this.vScroll) {
156
- // Reposition the corner square.
114
+ // Only change the scrollbars if there has been a change in metrics.
115
+ let resizeH = false;
116
+ let resizeV = false;
157
117
  if (!this.oldHostMetrics_ ||
158
118
  this.oldHostMetrics_.viewWidth !== hostMetrics.viewWidth ||
159
- this.oldHostMetrics_.absoluteLeft !== hostMetrics.absoluteLeft) {
160
- this.corner_.setAttribute('x', this.vScroll.position.x);
161
- }
162
- if (!this.oldHostMetrics_ ||
163
119
  this.oldHostMetrics_.viewHeight !== hostMetrics.viewHeight ||
164
- this.oldHostMetrics_.absoluteTop !== hostMetrics.absoluteTop) {
165
- this.corner_.setAttribute('y', this.hScroll.position.y);
120
+ this.oldHostMetrics_.absoluteTop !== hostMetrics.absoluteTop ||
121
+ this.oldHostMetrics_.absoluteLeft !== hostMetrics.absoluteLeft) {
122
+ // The window has been resized or repositioned.
123
+ resizeH = true;
124
+ resizeV = true;
125
+ } else {
126
+ // Has the content been resized or moved?
127
+ if (!this.oldHostMetrics_ ||
128
+ this.oldHostMetrics_.scrollWidth !== hostMetrics.scrollWidth ||
129
+ this.oldHostMetrics_.viewLeft !== hostMetrics.viewLeft ||
130
+ this.oldHostMetrics_.scrollLeft !== hostMetrics.scrollLeft) {
131
+ resizeH = true;
132
+ }
133
+ if (!this.oldHostMetrics_ ||
134
+ this.oldHostMetrics_.scrollHeight !== hostMetrics.scrollHeight ||
135
+ this.oldHostMetrics_.viewTop !== hostMetrics.viewTop ||
136
+ this.oldHostMetrics_.scrollTop !== hostMetrics.scrollTop) {
137
+ resizeV = true;
138
+ }
166
139
  }
167
- }
168
-
169
- // Cache the current metrics to potentially short-cut the next resize event.
170
- this.oldHostMetrics_ = hostMetrics;
171
- };
172
140
 
173
- /**
174
- * Returns whether scrolling horizontally is enabled.
175
- * @return {boolean} True if horizontal scroll is enabled.
176
- */
177
- ScrollbarPair.prototype.canScrollHorizontally = function() {
178
- return !!this.hScroll;
179
- };
141
+ if (resizeH || resizeV) {
142
+ try {
143
+ eventUtils.disable();
144
+ if (this.hScroll && resizeH) {
145
+ this.hScroll.resize(hostMetrics);
146
+ }
147
+ if (this.vScroll && resizeV) {
148
+ this.vScroll.resize(hostMetrics);
149
+ }
150
+ } finally {
151
+ eventUtils.enable();
152
+ }
153
+ this.workspace_.maybeFireViewportChangeEvent();
154
+ }
180
155
 
181
- /**
182
- * Returns whether scrolling vertically is enabled.
183
- * @return {boolean} True if vertical scroll is enabled.
184
- */
185
- ScrollbarPair.prototype.canScrollVertically = function() {
186
- return !!this.vScroll;
187
- };
156
+ if (this.hScroll && this.vScroll) {
157
+ // Reposition the corner square.
158
+ if (!this.oldHostMetrics_ ||
159
+ this.oldHostMetrics_.viewWidth !== hostMetrics.viewWidth ||
160
+ this.oldHostMetrics_.absoluteLeft !== hostMetrics.absoluteLeft) {
161
+ this.corner_.setAttribute('x', this.vScroll.position.x);
162
+ }
163
+ if (!this.oldHostMetrics_ ||
164
+ this.oldHostMetrics_.viewHeight !== hostMetrics.viewHeight ||
165
+ this.oldHostMetrics_.absoluteTop !== hostMetrics.absoluteTop) {
166
+ this.corner_.setAttribute('y', this.hScroll.position.y);
167
+ }
168
+ }
188
169
 
189
- /**
190
- * Record the origin of the workspace that the scrollbar is in, in pixels
191
- * relative to the injection div origin. This is for times when the scrollbar is
192
- * used in an object whose origin isn't the same as the main workspace
193
- * (e.g. in a flyout.)
194
- * @param {number} x The x coordinate of the scrollbar's origin, in CSS pixels.
195
- * @param {number} y The y coordinate of the scrollbar's origin, in CSS pixels.
196
- * @package
197
- */
198
- ScrollbarPair.prototype.setOrigin = function(x, y) {
199
- if (this.hScroll) {
200
- this.hScroll.setOrigin(x, y);
201
- }
202
- if (this.vScroll) {
203
- this.vScroll.setOrigin(x, y);
170
+ // Cache the current metrics to potentially short-cut the next resize event.
171
+ this.oldHostMetrics_ = hostMetrics;
204
172
  }
205
- };
206
173
 
207
- /**
208
- * Set the handles of both scrollbars.
209
- * @param {number} x The horizontal content displacement, relative to the view
210
- * in pixels.
211
- * @param {number} y The vertical content displacement, relative to the view in
212
- * pixels.
213
- * @param {boolean} updateMetrics Whether to update metrics on this set call.
214
- * Defaults to true.
215
- */
216
- ScrollbarPair.prototype.set = function(x, y, updateMetrics) {
217
- // This function is equivalent to:
218
- // this.hScroll.set(x);
219
- // this.vScroll.set(y);
220
- // However, that calls setMetrics twice which causes a chain of
221
- // getAttribute->setAttribute->getAttribute resulting in an extra layout pass.
222
- // Combining them speeds up rendering.
223
- if (this.hScroll) {
224
- this.hScroll.set(x, false);
174
+ /**
175
+ * Returns whether scrolling horizontally is enabled.
176
+ * @return {boolean} True if horizontal scroll is enabled.
177
+ */
178
+ canScrollHorizontally() {
179
+ return !!this.hScroll;
225
180
  }
226
- if (this.vScroll) {
227
- this.vScroll.set(y, false);
181
+
182
+ /**
183
+ * Returns whether scrolling vertically is enabled.
184
+ * @return {boolean} True if vertical scroll is enabled.
185
+ */
186
+ canScrollVertically() {
187
+ return !!this.vScroll;
228
188
  }
229
189
 
230
- if (updateMetrics || updateMetrics === undefined) {
231
- // Update metrics.
232
- const xyRatio = {};
190
+ /**
191
+ * Record the origin of the workspace that the scrollbar is in, in pixels
192
+ * relative to the injection div origin. This is for times when the scrollbar
193
+ * is used in an object whose origin isn't the same as the main workspace
194
+ * (e.g. in a flyout.)
195
+ * @param {number} x The x coordinate of the scrollbar's origin, in CSS
196
+ * pixels.
197
+ * @param {number} y The y coordinate of the scrollbar's origin, in CSS
198
+ * pixels.
199
+ * @package
200
+ */
201
+ setOrigin(x, y) {
233
202
  if (this.hScroll) {
234
- xyRatio.x = this.hScroll.getRatio_();
203
+ this.hScroll.setOrigin(x, y);
235
204
  }
236
205
  if (this.vScroll) {
237
- xyRatio.y = this.vScroll.getRatio_();
206
+ this.vScroll.setOrigin(x, y);
238
207
  }
239
- this.workspace_.setMetrics(xyRatio);
240
208
  }
241
- };
242
209
 
243
- /**
244
- * Set the handle of the horizontal scrollbar to be at a certain position in
245
- * CSS pixels relative to its parents.
246
- * @param {number} x Horizontal scroll value.
247
- */
248
- ScrollbarPair.prototype.setX = function(x) {
249
- if (this.hScroll) {
250
- this.hScroll.set(x, true);
251
- }
252
- };
210
+ /**
211
+ * Set the handles of both scrollbars.
212
+ * @param {number} x The horizontal content displacement, relative to the view
213
+ * in pixels.
214
+ * @param {number} y The vertical content displacement, relative to the view
215
+ * in
216
+ * pixels.
217
+ * @param {boolean} updateMetrics Whether to update metrics on this set call.
218
+ * Defaults to true.
219
+ */
220
+ set(x, y, updateMetrics) {
221
+ // This function is equivalent to:
222
+ // this.hScroll.set(x);
223
+ // this.vScroll.set(y);
224
+ // However, that calls setMetrics twice which causes a chain of
225
+ // getAttribute->setAttribute->getAttribute resulting in an extra layout
226
+ // pass. Combining them speeds up rendering.
227
+ if (this.hScroll) {
228
+ this.hScroll.set(x, false);
229
+ }
230
+ if (this.vScroll) {
231
+ this.vScroll.set(y, false);
232
+ }
253
233
 
254
- /**
255
- * Set the handle of the vertical scrollbar to be at a certain position in
256
- * CSS pixels relative to its parents.
257
- * @param {number} y Vertical scroll value.
258
- */
259
- ScrollbarPair.prototype.setY = function(y) {
260
- if (this.vScroll) {
261
- this.vScroll.set(y, true);
234
+ if (updateMetrics || updateMetrics === undefined) {
235
+ // Update metrics.
236
+ const xyRatio = {};
237
+ if (this.hScroll) {
238
+ xyRatio.x = this.hScroll.getRatio_();
239
+ }
240
+ if (this.vScroll) {
241
+ xyRatio.y = this.vScroll.getRatio_();
242
+ }
243
+ this.workspace_.setMetrics(xyRatio);
244
+ }
262
245
  }
263
- };
264
246
 
265
- /**
266
- * Set whether this scrollbar's container is visible.
267
- * @param {boolean} visible Whether the container is visible.
268
- */
269
- ScrollbarPair.prototype.setContainerVisible = function(visible) {
270
- if (this.hScroll) {
271
- this.hScroll.setContainerVisible(visible);
272
- }
273
- if (this.vScroll) {
274
- this.vScroll.setContainerVisible(visible);
247
+ /**
248
+ * Set the handle of the horizontal scrollbar to be at a certain position in
249
+ * CSS pixels relative to its parents.
250
+ * @param {number} x Horizontal scroll value.
251
+ */
252
+ setX(x) {
253
+ if (this.hScroll) {
254
+ this.hScroll.set(x, true);
255
+ }
275
256
  }
276
- };
277
257
 
278
- /**
279
- * If any of the scrollbars are visible. Non-paired scrollbars may disappear
280
- * when they aren't needed.
281
- * @return {boolean} True if visible.
282
- */
283
- ScrollbarPair.prototype.isVisible = function() {
284
- let isVisible = false;
285
- if (this.hScroll) {
286
- isVisible = this.hScroll.isVisible();
287
- }
288
- if (this.vScroll) {
289
- isVisible = isVisible || this.vScroll.isVisible();
258
+ /**
259
+ * Set the handle of the vertical scrollbar to be at a certain position in
260
+ * CSS pixels relative to its parents.
261
+ * @param {number} y Vertical scroll value.
262
+ */
263
+ setY(y) {
264
+ if (this.vScroll) {
265
+ this.vScroll.set(y, true);
266
+ }
290
267
  }
291
- return isVisible;
292
- };
293
268
 
294
- /**
295
- * Recalculates the scrollbars' locations within their path and length.
296
- * This should be called when the contents of the workspace have changed.
297
- * @param {!Metrics} hostMetrics A data structure describing all
298
- * the required dimensions, possibly fetched from the host object.
299
- */
300
- ScrollbarPair.prototype.resizeContent = function(hostMetrics) {
301
- if (this.hScroll) {
302
- this.hScroll.resizeContentHorizontal(hostMetrics);
269
+ /**
270
+ * Set whether this scrollbar's container is visible.
271
+ * @param {boolean} visible Whether the container is visible.
272
+ */
273
+ setContainerVisible(visible) {
274
+ if (this.hScroll) {
275
+ this.hScroll.setContainerVisible(visible);
276
+ }
277
+ if (this.vScroll) {
278
+ this.vScroll.setContainerVisible(visible);
279
+ }
303
280
  }
304
- if (this.vScroll) {
305
- this.vScroll.resizeContentVertical(hostMetrics);
281
+
282
+ /**
283
+ * If any of the scrollbars are visible. Non-paired scrollbars may disappear
284
+ * when they aren't needed.
285
+ * @return {boolean} True if visible.
286
+ */
287
+ isVisible() {
288
+ let isVisible = false;
289
+ if (this.hScroll) {
290
+ isVisible = this.hScroll.isVisible();
291
+ }
292
+ if (this.vScroll) {
293
+ isVisible = isVisible || this.vScroll.isVisible();
294
+ }
295
+ return isVisible;
306
296
  }
307
- };
308
297
 
309
- /**
310
- * Recalculates the scrollbars' locations on the screen and path length.
311
- * This should be called when the layout or size of the window has changed.
312
- * @param {!Metrics} hostMetrics A data structure describing all
313
- * the required dimensions, possibly fetched from the host object.
314
- */
315
- ScrollbarPair.prototype.resizeView = function(hostMetrics) {
316
- if (this.hScroll) {
317
- this.hScroll.resizeViewHorizontal(hostMetrics);
298
+ /**
299
+ * Recalculates the scrollbars' locations within their path and length.
300
+ * This should be called when the contents of the workspace have changed.
301
+ * @param {!Metrics} hostMetrics A data structure describing all
302
+ * the required dimensions, possibly fetched from the host object.
303
+ */
304
+ resizeContent(hostMetrics) {
305
+ if (this.hScroll) {
306
+ this.hScroll.resizeContentHorizontal(hostMetrics);
307
+ }
308
+ if (this.vScroll) {
309
+ this.vScroll.resizeContentVertical(hostMetrics);
310
+ }
318
311
  }
319
- if (this.vScroll) {
320
- this.vScroll.resizeViewVertical(hostMetrics);
312
+
313
+ /**
314
+ * Recalculates the scrollbars' locations on the screen and path length.
315
+ * This should be called when the layout or size of the window has changed.
316
+ * @param {!Metrics} hostMetrics A data structure describing all
317
+ * the required dimensions, possibly fetched from the host object.
318
+ */
319
+ resizeView(hostMetrics) {
320
+ if (this.hScroll) {
321
+ this.hScroll.resizeViewHorizontal(hostMetrics);
322
+ }
323
+ if (this.vScroll) {
324
+ this.vScroll.resizeViewVertical(hostMetrics);
325
+ }
321
326
  }
322
327
  };
323
328
 
@@ -23,6 +23,8 @@ const serializationRegistry = goog.require('Blockly.serialization.registry');
23
23
  const {BadConnectionCheck, MissingBlockType, MissingConnection, RealChildOfShadow} = goog.require('Blockly.serialization.exceptions');
24
24
  /* eslint-disable-next-line no-unused-vars */
25
25
  const {Block} = goog.requireType('Blockly.Block');
26
+ /* eslint-disable-next-line no-unused-vars */
27
+ const {BlockSvg} = goog.requireType('Blockly.BlockSvg');
26
28
  // eslint-disable-next-line no-unused-vars
27
29
  const {Connection} = goog.requireType('Blockly.Connection');
28
30
  // eslint-disable-next-line no-unused-vars
@@ -350,9 +352,10 @@ const appendInternal = function(state, workspace, {
350
352
  // Adding connections to the connection db is expensive. This defers that
351
353
  // operation to decrease load time.
352
354
  if (workspace.rendered) {
355
+ const blockSvg = /** @type {!BlockSvg} */ (block);
353
356
  setTimeout(() => {
354
- if (!block.disposed) {
355
- block.setConnectionTracking(true);
357
+ if (!blockSvg.disposed) {
358
+ blockSvg.setConnectionTracking(true);
356
359
  }
357
360
  }, 1);
358
361
  }
@@ -511,11 +514,17 @@ const loadIcons = function(block, state) {
511
514
  const comment = state['icons']['comment'];
512
515
  if (comment) {
513
516
  block.setCommentText(comment['text']);
514
- block.commentModel.pinned = comment['pinned'];
515
- block.commentModel.size = new Size(comment['width'], comment['height']);
516
- if (comment['pinned'] && block.getCommentIcon && !block.isInFlyout) {
517
+ // Load if saved. (Cleaned unnecessary attributes when in the trashcan.)
518
+ if ('pinned' in comment) {
519
+ block.commentModel.pinned = comment['pinned'];
520
+ }
521
+ if ('width' in comment && 'height' in comment) {
522
+ block.commentModel.size = new Size(comment['width'], comment['height']);
523
+ }
524
+ if (comment['pinned'] && block.rendered && !block.isInFlyout) {
517
525
  // Give the block a chance to be positioned and rendered before showing.
518
- setTimeout(() => block.getCommentIcon().setVisible(true), 1);
526
+ const blockSvg = /** @type {!BlockSvg} */ (block);
527
+ setTimeout(() => blockSvg.getCommentIcon().setVisible(true), 1);
519
528
  }
520
529
  }
521
530
  };
@@ -607,12 +616,13 @@ const loadConnection = function(connection, connectionState) {
607
616
  */
608
617
  const initBlock = function(block, rendered) {
609
618
  if (rendered) {
619
+ const blockSvg = /** @type {!BlockSvg} */ (block);
610
620
  // Adding connections to the connection db is expensive. This defers that
611
621
  // operation to decrease load time.
612
- block.setConnectionTracking(false);
622
+ blockSvg.setConnectionTracking(false);
613
623
 
614
- block.initSvg();
615
- block.render(false);
624
+ blockSvg.initSvg();
625
+ blockSvg.render(false);
616
626
  } else {
617
627
  block.initModel();
618
628
  }
@@ -22,6 +22,7 @@ const eventUtils = goog.require('Blockly.Events.utils');
22
22
  const registry = goog.require('Blockly.registry');
23
23
  // eslint-disable-next-line no-unused-vars
24
24
  const {Workspace} = goog.require('Blockly.Workspace');
25
+ const {WorkspaceSvg} = goog.require('Blockly.WorkspaceSvg');
25
26
 
26
27
 
27
28
  /**
@@ -70,7 +71,7 @@ const load = function(state, workspace, {recordUndo = false} = {}) {
70
71
  }
71
72
 
72
73
  dom.startTextWidthCache();
73
- if (workspace.setResizesEnabled) {
74
+ if (workspace instanceof WorkspaceSvg) {
74
75
  workspace.setResizesEnabled(false);
75
76
  }
76
77
 
@@ -89,7 +90,7 @@ const load = function(state, workspace, {recordUndo = false} = {}) {
89
90
  }
90
91
  }
91
92
 
92
- if (workspace.setResizesEnabled) {
93
+ if (workspace instanceof WorkspaceSvg) {
93
94
  workspace.setResizesEnabled(true);
94
95
  }
95
96
  dom.stopTextWidthCache();