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
@@ -17,12 +17,11 @@ goog.module('Blockly.VerticalFlyout');
17
17
 
18
18
  const WidgetDiv = goog.require('Blockly.WidgetDiv');
19
19
  const browserEvents = goog.require('Blockly.browserEvents');
20
- const object = goog.require('Blockly.utils.object');
20
+ const dropDownDiv = goog.require('Blockly.dropDownDiv');
21
21
  const registry = goog.require('Blockly.registry');
22
22
  const toolbox = goog.require('Blockly.utils.toolbox');
23
23
  /* eslint-disable-next-line no-unused-vars */
24
24
  const {Coordinate} = goog.requireType('Blockly.utils.Coordinate');
25
- const {DropDownDiv} = goog.require('Blockly.DropDownDiv');
26
25
  const {Flyout} = goog.require('Blockly.Flyout');
27
26
  /* eslint-disable-next-line no-unused-vars */
28
27
  const {Options} = goog.requireType('Blockly.Options');
@@ -36,352 +35,359 @@ goog.require('Blockly.constants');
36
35
 
37
36
  /**
38
37
  * Class for a flyout.
39
- * @param {!Options} workspaceOptions Dictionary of options for the
40
- * workspace.
41
38
  * @extends {Flyout}
42
- * @constructor
43
39
  * @alias Blockly.VerticalFlyout
44
40
  */
45
- const VerticalFlyout = function(workspaceOptions) {
46
- VerticalFlyout.superClass_.constructor.call(this, workspaceOptions);
47
- };
48
- object.inherits(VerticalFlyout, Flyout);
41
+ class VerticalFlyout extends Flyout {
42
+ /**
43
+ * @param {!Options} workspaceOptions Dictionary of options for the
44
+ * workspace.
45
+ */
46
+ constructor(workspaceOptions) {
47
+ super(workspaceOptions);
48
+ }
49
49
 
50
- /**
51
- * The name of the vertical flyout in the registry.
52
- * @type {string}
53
- */
54
- VerticalFlyout.registryName = 'verticalFlyout';
50
+ /**
51
+ * Sets the translation of the flyout to match the scrollbars.
52
+ * @param {!{x:number,y:number}} xyRatio Contains a y property which is a
53
+ * float between 0 and 1 specifying the degree of scrolling and a similar
54
+ * x property.
55
+ * @protected
56
+ */
57
+ setMetrics_(xyRatio) {
58
+ if (!this.isVisible()) {
59
+ return;
60
+ }
61
+ const metricsManager = this.workspace_.getMetricsManager();
62
+ const scrollMetrics = metricsManager.getScrollMetrics();
63
+ const viewMetrics = metricsManager.getViewMetrics();
64
+ const absoluteMetrics = metricsManager.getAbsoluteMetrics();
55
65
 
56
- /**
57
- * Sets the translation of the flyout to match the scrollbars.
58
- * @param {!{x:number,y:number}} xyRatio Contains a y property which is a float
59
- * between 0 and 1 specifying the degree of scrolling and a
60
- * similar x property.
61
- * @protected
62
- */
63
- VerticalFlyout.prototype.setMetrics_ = function(xyRatio) {
64
- if (!this.isVisible()) {
65
- return;
66
- }
67
- const metricsManager = this.workspace_.getMetricsManager();
68
- const scrollMetrics = metricsManager.getScrollMetrics();
69
- const viewMetrics = metricsManager.getViewMetrics();
70
- const absoluteMetrics = metricsManager.getAbsoluteMetrics();
71
-
72
- if (typeof xyRatio.y === 'number') {
73
- this.workspace_.scrollY =
74
- -(scrollMetrics.top +
75
- (scrollMetrics.height - viewMetrics.height) * xyRatio.y);
66
+ if (typeof xyRatio.y === 'number') {
67
+ this.workspace_.scrollY =
68
+ -(scrollMetrics.top +
69
+ (scrollMetrics.height - viewMetrics.height) * xyRatio.y);
70
+ }
71
+ this.workspace_.translate(
72
+ this.workspace_.scrollX + absoluteMetrics.left,
73
+ this.workspace_.scrollY + absoluteMetrics.top);
76
74
  }
77
- this.workspace_.translate(
78
- this.workspace_.scrollX + absoluteMetrics.left,
79
- this.workspace_.scrollY + absoluteMetrics.top);
80
- };
81
75
 
82
- /**
83
- * Calculates the x coordinate for the flyout position.
84
- * @return {number} X coordinate.
85
- */
86
- VerticalFlyout.prototype.getX = function() {
87
- if (!this.isVisible()) {
88
- return 0;
89
- }
90
- const metricsManager = this.targetWorkspace.getMetricsManager();
91
- const absoluteMetrics = metricsManager.getAbsoluteMetrics();
92
- const viewMetrics = metricsManager.getViewMetrics();
93
- const toolboxMetrics = metricsManager.getToolboxMetrics();
94
- let x = 0;
95
-
96
- // If this flyout is not the trashcan flyout (e.g. toolbox or mutator).
97
- if (this.targetWorkspace.toolboxPosition === this.toolboxPosition_) {
98
- // If there is a category toolbox.
99
- if (this.targetWorkspace.getToolbox()) {
100
- if (this.toolboxPosition_ === toolbox.Position.LEFT) {
101
- x = toolboxMetrics.width;
76
+ /**
77
+ * Calculates the x coordinate for the flyout position.
78
+ * @return {number} X coordinate.
79
+ */
80
+ getX() {
81
+ if (!this.isVisible()) {
82
+ return 0;
83
+ }
84
+ const metricsManager = this.targetWorkspace.getMetricsManager();
85
+ const absoluteMetrics = metricsManager.getAbsoluteMetrics();
86
+ const viewMetrics = metricsManager.getViewMetrics();
87
+ const toolboxMetrics = metricsManager.getToolboxMetrics();
88
+ let x = 0;
89
+
90
+ // If this flyout is not the trashcan flyout (e.g. toolbox or mutator).
91
+ if (this.targetWorkspace.toolboxPosition === this.toolboxPosition_) {
92
+ // If there is a category toolbox.
93
+ if (this.targetWorkspace.getToolbox()) {
94
+ if (this.toolboxPosition_ === toolbox.Position.LEFT) {
95
+ x = toolboxMetrics.width;
96
+ } else {
97
+ x = viewMetrics.width - this.width_;
98
+ }
99
+ // Simple (flyout-only) toolbox.
102
100
  } else {
103
- x = viewMetrics.width - this.width_;
101
+ if (this.toolboxPosition_ === toolbox.Position.LEFT) {
102
+ x = 0;
103
+ } else {
104
+ // The simple flyout does not cover the workspace.
105
+ x = viewMetrics.width;
106
+ }
104
107
  }
105
- // Simple (flyout-only) toolbox.
108
+ // Trashcan flyout is opposite the main flyout.
106
109
  } else {
107
110
  if (this.toolboxPosition_ === toolbox.Position.LEFT) {
108
111
  x = 0;
109
112
  } else {
110
- // The simple flyout does not cover the workspace.
111
- x = viewMetrics.width;
113
+ // Because the anchor point of the flyout is on the left, but we want
114
+ // to align the right edge of the flyout with the right edge of the
115
+ // blocklyDiv, we calculate the full width of the div minus the width
116
+ // of the flyout.
117
+ x = viewMetrics.width + absoluteMetrics.left - this.width_;
112
118
  }
113
119
  }
114
- // Trashcan flyout is opposite the main flyout.
115
- } else {
116
- if (this.toolboxPosition_ === toolbox.Position.LEFT) {
117
- x = 0;
118
- } else {
119
- // Because the anchor point of the flyout is on the left, but we want
120
- // to align the right edge of the flyout with the right edge of the
121
- // blocklyDiv, we calculate the full width of the div minus the width
122
- // of the flyout.
123
- x = viewMetrics.width + absoluteMetrics.left - this.width_;
124
- }
125
- }
126
120
 
127
- return x;
128
- };
129
-
130
- /**
131
- * Calculates the y coordinate for the flyout position.
132
- * @return {number} Y coordinate.
133
- */
134
- VerticalFlyout.prototype.getY = function() {
135
- // Y is always 0 since this is a vertical flyout.
136
- return 0;
137
- };
121
+ return x;
122
+ }
138
123
 
139
- /**
140
- * Move the flyout to the edge of the workspace.
141
- */
142
- VerticalFlyout.prototype.position = function() {
143
- if (!this.isVisible() || !this.targetWorkspace.isVisible()) {
144
- return;
124
+ /**
125
+ * Calculates the y coordinate for the flyout position.
126
+ * @return {number} Y coordinate.
127
+ */
128
+ getY() {
129
+ // Y is always 0 since this is a vertical flyout.
130
+ return 0;
145
131
  }
146
- const metricsManager = this.targetWorkspace.getMetricsManager();
147
- const targetWorkspaceViewMetrics = metricsManager.getViewMetrics();
148
132
 
149
- // Record the height for workspace metrics.
150
- this.height_ = targetWorkspaceViewMetrics.height;
133
+ /**
134
+ * Move the flyout to the edge of the workspace.
135
+ */
136
+ position() {
137
+ if (!this.isVisible() || !this.targetWorkspace.isVisible()) {
138
+ return;
139
+ }
140
+ const metricsManager = this.targetWorkspace.getMetricsManager();
141
+ const targetWorkspaceViewMetrics = metricsManager.getViewMetrics();
151
142
 
152
- const edgeWidth = this.width_ - this.CORNER_RADIUS;
153
- const edgeHeight = targetWorkspaceViewMetrics.height - 2 * this.CORNER_RADIUS;
154
- this.setBackgroundPath_(edgeWidth, edgeHeight);
143
+ // Record the height for workspace metrics.
144
+ this.height_ = targetWorkspaceViewMetrics.height;
155
145
 
156
- const x = this.getX();
157
- const y = this.getY();
146
+ const edgeWidth = this.width_ - this.CORNER_RADIUS;
147
+ const edgeHeight =
148
+ targetWorkspaceViewMetrics.height - 2 * this.CORNER_RADIUS;
149
+ this.setBackgroundPath_(edgeWidth, edgeHeight);
158
150
 
159
- this.positionAt_(this.width_, this.height_, x, y);
160
- };
151
+ const x = this.getX();
152
+ const y = this.getY();
161
153
 
162
- /**
163
- * Create and set the path for the visible boundaries of the flyout.
164
- * @param {number} width The width of the flyout, not including the
165
- * rounded corners.
166
- * @param {number} height The height of the flyout, not including
167
- * rounded corners.
168
- * @private
169
- */
170
- VerticalFlyout.prototype.setBackgroundPath_ = function(width, height) {
171
- const atRight = this.toolboxPosition_ === toolbox.Position.RIGHT;
172
- const totalWidth = width + this.CORNER_RADIUS;
173
-
174
- // Decide whether to start on the left or right.
175
- const path = ['M ' + (atRight ? totalWidth : 0) + ',0'];
176
- // Top.
177
- path.push('h', atRight ? -width : width);
178
- // Rounded corner.
179
- path.push(
180
- 'a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0, atRight ? 0 : 1,
181
- atRight ? -this.CORNER_RADIUS : this.CORNER_RADIUS, this.CORNER_RADIUS);
182
- // Side closest to workspace.
183
- path.push('v', Math.max(0, height));
184
- // Rounded corner.
185
- path.push(
186
- 'a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0, atRight ? 0 : 1,
187
- atRight ? this.CORNER_RADIUS : -this.CORNER_RADIUS, this.CORNER_RADIUS);
188
- // Bottom.
189
- path.push('h', atRight ? width : -width);
190
- path.push('z');
191
- this.svgBackground_.setAttribute('d', path.join(' '));
192
- };
154
+ this.positionAt_(this.width_, this.height_, x, y);
155
+ }
193
156
 
194
- /**
195
- * Scroll the flyout to the top.
196
- */
197
- VerticalFlyout.prototype.scrollToStart = function() {
198
- this.workspace_.scrollbar.setY(0);
199
- };
157
+ /**
158
+ * Create and set the path for the visible boundaries of the flyout.
159
+ * @param {number} width The width of the flyout, not including the
160
+ * rounded corners.
161
+ * @param {number} height The height of the flyout, not including
162
+ * rounded corners.
163
+ * @private
164
+ */
165
+ setBackgroundPath_(width, height) {
166
+ const atRight = this.toolboxPosition_ === toolbox.Position.RIGHT;
167
+ const totalWidth = width + this.CORNER_RADIUS;
168
+
169
+ // Decide whether to start on the left or right.
170
+ const path = ['M ' + (atRight ? totalWidth : 0) + ',0'];
171
+ // Top.
172
+ path.push('h', atRight ? -width : width);
173
+ // Rounded corner.
174
+ path.push(
175
+ 'a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0, atRight ? 0 : 1,
176
+ atRight ? -this.CORNER_RADIUS : this.CORNER_RADIUS, this.CORNER_RADIUS);
177
+ // Side closest to workspace.
178
+ path.push('v', Math.max(0, height));
179
+ // Rounded corner.
180
+ path.push(
181
+ 'a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0, atRight ? 0 : 1,
182
+ atRight ? this.CORNER_RADIUS : -this.CORNER_RADIUS, this.CORNER_RADIUS);
183
+ // Bottom.
184
+ path.push('h', atRight ? width : -width);
185
+ path.push('z');
186
+ this.svgBackground_.setAttribute('d', path.join(' '));
187
+ }
200
188
 
201
- /**
202
- * Scroll the flyout.
203
- * @param {!Event} e Mouse wheel scroll event.
204
- * @protected
205
- */
206
- VerticalFlyout.prototype.wheel_ = function(e) {
207
- const scrollDelta = browserEvents.getScrollDeltaPixels(e);
189
+ /**
190
+ * Scroll the flyout to the top.
191
+ */
192
+ scrollToStart() {
193
+ this.workspace_.scrollbar.setY(0);
194
+ }
208
195
 
209
- if (scrollDelta.y) {
210
- const metricsManager = this.workspace_.getMetricsManager();
211
- const scrollMetrics = metricsManager.getScrollMetrics();
212
- const viewMetrics = metricsManager.getViewMetrics();
213
- const pos = (viewMetrics.top - scrollMetrics.top) + scrollDelta.y;
196
+ /**
197
+ * Scroll the flyout.
198
+ * @param {!Event} e Mouse wheel scroll event.
199
+ * @protected
200
+ */
201
+ wheel_(e) {
202
+ const scrollDelta = browserEvents.getScrollDeltaPixels(e);
203
+
204
+ if (scrollDelta.y) {
205
+ const metricsManager = this.workspace_.getMetricsManager();
206
+ const scrollMetrics = metricsManager.getScrollMetrics();
207
+ const viewMetrics = metricsManager.getViewMetrics();
208
+ const pos = (viewMetrics.top - scrollMetrics.top) + scrollDelta.y;
209
+
210
+ this.workspace_.scrollbar.setY(pos);
211
+ // When the flyout moves from a wheel event, hide WidgetDiv and
212
+ // dropDownDiv.
213
+ WidgetDiv.hide();
214
+ dropDownDiv.hideWithoutAnimation();
215
+ }
214
216
 
215
- this.workspace_.scrollbar.setY(pos);
216
- // When the flyout moves from a wheel event, hide WidgetDiv and DropDownDiv.
217
- WidgetDiv.hide();
218
- DropDownDiv.hideWithoutAnimation();
217
+ // Don't scroll the page.
218
+ e.preventDefault();
219
+ // Don't propagate mousewheel event (zooming).
220
+ e.stopPropagation();
219
221
  }
220
222
 
221
- // Don't scroll the page.
222
- e.preventDefault();
223
- // Don't propagate mousewheel event (zooming).
224
- e.stopPropagation();
225
- };
226
-
227
- /**
228
- * Lay out the blocks in the flyout.
229
- * @param {!Array<!Object>} contents The blocks and buttons to lay out.
230
- * @param {!Array<number>} gaps The visible gaps between blocks.
231
- * @protected
232
- */
233
- VerticalFlyout.prototype.layout_ = function(contents, gaps) {
234
- this.workspace_.scale = this.targetWorkspace.scale;
235
- const margin = this.MARGIN;
236
- const cursorX = this.RTL ? margin : margin + this.tabWidth_;
237
- let cursorY = margin;
238
-
239
- for (let i = 0, item; (item = contents[i]); i++) {
240
- if (item.type === 'block') {
241
- const block = item.block;
242
- const allBlocks = block.getDescendants(false);
243
- for (let j = 0, child; (child = allBlocks[j]); j++) {
244
- // Mark blocks as being inside a flyout. This is used to detect and
245
- // prevent the closure of the flyout if the user right-clicks on such a
246
- // block.
247
- child.isInFlyout = true;
223
+ /**
224
+ * Lay out the blocks in the flyout.
225
+ * @param {!Array<!Object>} contents The blocks and buttons to lay out.
226
+ * @param {!Array<number>} gaps The visible gaps between blocks.
227
+ * @protected
228
+ */
229
+ layout_(contents, gaps) {
230
+ this.workspace_.scale = this.targetWorkspace.scale;
231
+ const margin = this.MARGIN;
232
+ const cursorX = this.RTL ? margin : margin + this.tabWidth_;
233
+ let cursorY = margin;
234
+
235
+ for (let i = 0, item; (item = contents[i]); i++) {
236
+ if (item.type === 'block') {
237
+ const block = item.block;
238
+ const allBlocks = block.getDescendants(false);
239
+ for (let j = 0, child; (child = allBlocks[j]); j++) {
240
+ // Mark blocks as being inside a flyout. This is used to detect and
241
+ // prevent the closure of the flyout if the user right-clicks on such
242
+ // a block.
243
+ child.isInFlyout = true;
244
+ }
245
+ block.render();
246
+ const root = block.getSvgRoot();
247
+ const blockHW = block.getHeightWidth();
248
+ const moveX =
249
+ block.outputConnection ? cursorX - this.tabWidth_ : cursorX;
250
+ block.moveBy(moveX, cursorY);
251
+
252
+ const rect = this.createRect_(
253
+ block, this.RTL ? moveX - blockHW.width : moveX, cursorY, blockHW,
254
+ i);
255
+
256
+ this.addBlockListeners_(root, block, rect);
257
+
258
+ cursorY += blockHW.height + gaps[i];
259
+ } else if (item.type === 'button') {
260
+ this.initFlyoutButton_(item.button, cursorX, cursorY);
261
+ cursorY += item.button.height + gaps[i];
248
262
  }
249
- block.render();
250
- const root = block.getSvgRoot();
251
- const blockHW = block.getHeightWidth();
252
- const moveX = block.outputConnection ? cursorX - this.tabWidth_ : cursorX;
253
- block.moveBy(moveX, cursorY);
254
-
255
- const rect = this.createRect_(
256
- block, this.RTL ? moveX - blockHW.width : moveX, cursorY, blockHW, i);
257
-
258
- this.addBlockListeners_(root, block, rect);
259
-
260
- cursorY += blockHW.height + gaps[i];
261
- } else if (item.type === 'button') {
262
- this.initFlyoutButton_(item.button, cursorX, cursorY);
263
- cursorY += item.button.height + gaps[i];
264
263
  }
265
264
  }
266
- };
267
265
 
268
- /**
269
- * Determine if a drag delta is toward the workspace, based on the position
270
- * and orientation of the flyout. This is used in determineDragIntention_ to
271
- * determine if a new block should be created or if the flyout should scroll.
272
- * @param {!Coordinate} currentDragDeltaXY How far the pointer has
273
- * moved from the position at mouse down, in pixel units.
274
- * @return {boolean} True if the drag is toward the workspace.
275
- * @package
276
- */
277
- VerticalFlyout.prototype.isDragTowardWorkspace = function(currentDragDeltaXY) {
278
- const dx = currentDragDeltaXY.x;
279
- const dy = currentDragDeltaXY.y;
280
- // Direction goes from -180 to 180, with 0 toward the right and 90 on top.
281
- const dragDirection = Math.atan2(dy, dx) / Math.PI * 180;
282
-
283
- const range = this.dragAngleRange_;
284
- // Check for left or right dragging.
285
- if ((dragDirection < range && dragDirection > -range) ||
286
- (dragDirection < -180 + range || dragDirection > 180 - range)) {
287
- return true;
266
+ /**
267
+ * Determine if a drag delta is toward the workspace, based on the position
268
+ * and orientation of the flyout. This is used in determineDragIntention_ to
269
+ * determine if a new block should be created or if the flyout should scroll.
270
+ * @param {!Coordinate} currentDragDeltaXY How far the pointer has
271
+ * moved from the position at mouse down, in pixel units.
272
+ * @return {boolean} True if the drag is toward the workspace.
273
+ * @package
274
+ */
275
+ isDragTowardWorkspace(currentDragDeltaXY) {
276
+ const dx = currentDragDeltaXY.x;
277
+ const dy = currentDragDeltaXY.y;
278
+ // Direction goes from -180 to 180, with 0 toward the right and 90 on top.
279
+ const dragDirection = Math.atan2(dy, dx) / Math.PI * 180;
280
+
281
+ const range = this.dragAngleRange_;
282
+ // Check for left or right dragging.
283
+ if ((dragDirection < range && dragDirection > -range) ||
284
+ (dragDirection < -180 + range || dragDirection > 180 - range)) {
285
+ return true;
286
+ }
287
+ return false;
288
288
  }
289
- return false;
290
- };
291
289
 
292
- /**
293
- * Returns the bounding rectangle of the drag target area in pixel units
294
- * relative to viewport.
295
- * @return {?Rect} The component's bounding box. Null if drag
296
- * target area should be ignored.
297
- */
298
- VerticalFlyout.prototype.getClientRect = function() {
299
- if (!this.svgGroup_ || this.autoClose || !this.isVisible()) {
300
- // The bounding rectangle won't compute correctly if the flyout is closed
301
- // and auto-close flyouts aren't valid drag targets (or delete areas).
302
- return null;
303
- }
290
+ /**
291
+ * Returns the bounding rectangle of the drag target area in pixel units
292
+ * relative to viewport.
293
+ * @return {?Rect} The component's bounding box. Null if drag
294
+ * target area should be ignored.
295
+ */
296
+ getClientRect() {
297
+ if (!this.svgGroup_ || this.autoClose || !this.isVisible()) {
298
+ // The bounding rectangle won't compute correctly if the flyout is closed
299
+ // and auto-close flyouts aren't valid drag targets (or delete areas).
300
+ return null;
301
+ }
304
302
 
305
- const flyoutRect = this.svgGroup_.getBoundingClientRect();
306
- // BIG_NUM is offscreen padding so that blocks dragged beyond the shown flyout
307
- // area are still deleted. Must be larger than the largest screen size,
308
- // but be smaller than half Number.MAX_SAFE_INTEGER (not available on IE).
309
- const BIG_NUM = 1000000000;
310
- const left = flyoutRect.left;
311
-
312
- if (this.toolboxPosition_ === toolbox.Position.LEFT) {
313
- const width = flyoutRect.width;
314
- return new Rect(-BIG_NUM, BIG_NUM, -BIG_NUM, left + width);
315
- } else { // Right
316
- return new Rect(-BIG_NUM, BIG_NUM, left, BIG_NUM);
317
- }
318
- };
303
+ const flyoutRect = this.svgGroup_.getBoundingClientRect();
304
+ // BIG_NUM is offscreen padding so that blocks dragged beyond the shown
305
+ // flyout area are still deleted. Must be larger than the largest screen
306
+ // size, but be smaller than half Number.MAX_SAFE_INTEGER (not available on
307
+ // IE).
308
+ const BIG_NUM = 1000000000;
309
+ const left = flyoutRect.left;
319
310
 
320
- /**
321
- * Compute width of flyout. toolbox.Position mat under each block.
322
- * For RTL: Lay out the blocks and buttons to be right-aligned.
323
- * @protected
324
- */
325
- VerticalFlyout.prototype.reflowInternal_ = function() {
326
- this.workspace_.scale = this.getFlyoutScale();
327
- let flyoutWidth = 0;
328
- const blocks = this.workspace_.getTopBlocks(false);
329
- for (let i = 0, block; (block = blocks[i]); i++) {
330
- let width = block.getHeightWidth().width;
331
- if (block.outputConnection) {
332
- width -= this.tabWidth_;
311
+ if (this.toolboxPosition_ === toolbox.Position.LEFT) {
312
+ const width = flyoutRect.width;
313
+ return new Rect(-BIG_NUM, BIG_NUM, -BIG_NUM, left + width);
314
+ } else { // Right
315
+ return new Rect(-BIG_NUM, BIG_NUM, left, BIG_NUM);
333
316
  }
334
- flyoutWidth = Math.max(flyoutWidth, width);
335
317
  }
336
- for (let i = 0, button; (button = this.buttons_[i]); i++) {
337
- flyoutWidth = Math.max(flyoutWidth, button.width);
338
- }
339
- flyoutWidth += this.MARGIN * 1.5 + this.tabWidth_;
340
- flyoutWidth *= this.workspace_.scale;
341
- flyoutWidth += Scrollbar.scrollbarThickness;
342
318
 
343
- if (this.width_ !== flyoutWidth) {
319
+ /**
320
+ * Compute width of flyout. toolbox.Position mat under each block.
321
+ * For RTL: Lay out the blocks and buttons to be right-aligned.
322
+ * @protected
323
+ */
324
+ reflowInternal_() {
325
+ this.workspace_.scale = this.getFlyoutScale();
326
+ let flyoutWidth = 0;
327
+ const blocks = this.workspace_.getTopBlocks(false);
344
328
  for (let i = 0, block; (block = blocks[i]); i++) {
345
- if (this.RTL) {
346
- // With the flyoutWidth known, right-align the blocks.
347
- const oldX = block.getRelativeToSurfaceXY().x;
348
- let newX = flyoutWidth / this.workspace_.scale - this.MARGIN;
349
- if (!block.outputConnection) {
350
- newX -= this.tabWidth_;
329
+ let width = block.getHeightWidth().width;
330
+ if (block.outputConnection) {
331
+ width -= this.tabWidth_;
332
+ }
333
+ flyoutWidth = Math.max(flyoutWidth, width);
334
+ }
335
+ for (let i = 0, button; (button = this.buttons_[i]); i++) {
336
+ flyoutWidth = Math.max(flyoutWidth, button.width);
337
+ }
338
+ flyoutWidth += this.MARGIN * 1.5 + this.tabWidth_;
339
+ flyoutWidth *= this.workspace_.scale;
340
+ flyoutWidth += Scrollbar.scrollbarThickness;
341
+
342
+ if (this.width_ !== flyoutWidth) {
343
+ for (let i = 0, block; (block = blocks[i]); i++) {
344
+ if (this.RTL) {
345
+ // With the flyoutWidth known, right-align the blocks.
346
+ const oldX = block.getRelativeToSurfaceXY().x;
347
+ let newX = flyoutWidth / this.workspace_.scale - this.MARGIN;
348
+ if (!block.outputConnection) {
349
+ newX -= this.tabWidth_;
350
+ }
351
+ block.moveBy(newX - oldX, 0);
352
+ }
353
+ if (this.rectMap_.has(block)) {
354
+ this.moveRectToBlock_(this.rectMap_.get(block), block);
351
355
  }
352
- block.moveBy(newX - oldX, 0);
353
356
  }
354
- if (block.flyoutRect_) {
355
- this.moveRectToBlock_(block.flyoutRect_, block);
357
+ if (this.RTL) {
358
+ // With the flyoutWidth known, right-align the buttons.
359
+ for (let i = 0, button; (button = this.buttons_[i]); i++) {
360
+ const y = button.getPosition().y;
361
+ const x = flyoutWidth / this.workspace_.scale - button.width -
362
+ this.MARGIN - this.tabWidth_;
363
+ button.moveTo(x, y);
364
+ }
356
365
  }
357
- }
358
- if (this.RTL) {
359
- // With the flyoutWidth known, right-align the buttons.
360
- for (let i = 0, button; (button = this.buttons_[i]); i++) {
361
- const y = button.getPosition().y;
362
- const x = flyoutWidth / this.workspace_.scale - button.width -
363
- this.MARGIN - this.tabWidth_;
364
- button.moveTo(x, y);
366
+
367
+ if (this.targetWorkspace.toolboxPosition === this.toolboxPosition_ &&
368
+ this.toolboxPosition_ === toolbox.Position.LEFT &&
369
+ !this.targetWorkspace.getToolbox()) {
370
+ // This flyout is a simple toolbox. Reposition the workspace so that
371
+ // (0,0) is in the correct position relative to the new absolute edge
372
+ // (ie toolbox edge).
373
+ this.targetWorkspace.translate(
374
+ this.targetWorkspace.scrollX + flyoutWidth,
375
+ this.targetWorkspace.scrollY);
365
376
  }
366
- }
367
377
 
368
- if (this.targetWorkspace.toolboxPosition === this.toolboxPosition_ &&
369
- this.toolboxPosition_ === toolbox.Position.LEFT &&
370
- !this.targetWorkspace.getToolbox()) {
371
- // This flyout is a simple toolbox. Reposition the workspace so that (0,0)
372
- // is in the correct position relative to the new absolute edge (ie
373
- // toolbox edge).
374
- this.targetWorkspace.translate(
375
- this.targetWorkspace.scrollX + flyoutWidth,
376
- this.targetWorkspace.scrollY);
378
+ // Record the width for workspace metrics and .position.
379
+ this.width_ = flyoutWidth;
380
+ this.position();
381
+ this.targetWorkspace.recordDragTargets();
377
382
  }
378
-
379
- // Record the width for workspace metrics and .position.
380
- this.width_ = flyoutWidth;
381
- this.position();
382
- this.targetWorkspace.recordDragTargets();
383
383
  }
384
- };
384
+ }
385
+
386
+ /**
387
+ * The name of the vertical flyout in the registry.
388
+ * @type {string}
389
+ */
390
+ VerticalFlyout.registryName = 'verticalFlyout';
385
391
 
386
392
  registry.register(
387
393
  registry.Type.FLYOUTS_VERTICAL_TOOLBOX, registry.DEFAULT, VerticalFlyout);