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
@@ -63,621 +63,659 @@ const HEIGHT_MULTIPLIER = 3 / 4;
63
63
 
64
64
  /**
65
65
  * Class for a marker.
66
- * @param {!WorkspaceSvg} workspace The workspace the marker belongs to.
67
- * @param {!ConstantProvider} constants The constants for
68
- * the renderer.
69
- * @param {!Marker} marker The marker to draw.
70
- * @constructor
71
66
  * @alias Blockly.blockRendering.MarkerSvg
72
67
  */
73
- const MarkerSvg = function(workspace, constants, marker) {
68
+ class MarkerSvg {
74
69
  /**
75
- * The workspace the marker belongs to.
76
- * @type {!WorkspaceSvg}
77
- * @private
70
+ * @param {!WorkspaceSvg} workspace The workspace the marker belongs to.
71
+ * @param {!ConstantProvider} constants The constants for
72
+ * the renderer.
73
+ * @param {!Marker} marker The marker to draw.
78
74
  */
79
- this.workspace_ = workspace;
75
+ constructor(workspace, constants, marker) {
76
+ /**
77
+ * The workspace the marker belongs to.
78
+ * @type {!WorkspaceSvg}
79
+ * @private
80
+ */
81
+ this.workspace_ = workspace;
82
+
83
+ /**
84
+ * The marker to draw.
85
+ * @type {!Marker}
86
+ * @private
87
+ */
88
+ this.marker_ = marker;
89
+
90
+ /**
91
+ * The workspace, field, or block that the marker SVG element should be
92
+ * attached to.
93
+ * @type {IASTNodeLocationSvg}
94
+ * @private
95
+ */
96
+ this.parent_ = null;
97
+
98
+ /**
99
+ * The constants necessary to draw the marker.
100
+ * @type {ConstantProvider}
101
+ * @protected
102
+ */
103
+ this.constants_ = constants;
104
+
105
+ /**
106
+ * The current SVG element for the marker.
107
+ * @type {Element}
108
+ */
109
+ this.currentMarkerSvg = null;
110
+
111
+ const defaultColour = this.isCursor() ? this.constants_.CURSOR_COLOUR :
112
+ this.constants_.MARKER_COLOUR;
113
+
114
+ /**
115
+ * The colour of the marker.
116
+ * @type {string}
117
+ */
118
+ this.colour_ = marker.colour || defaultColour;
119
+
120
+ /**
121
+ * The root SVG group containing the marker.
122
+ * @type {SVGGElement}
123
+ * @protected
124
+ */
125
+ this.markerSvg_ = null;
126
+
127
+ /**
128
+ * @type {?SVGGElement}
129
+ * @protected
130
+ */
131
+ this.svgGroup_ = null;
132
+
133
+ /**
134
+ * @type {?SVGPathElement}
135
+ * @protected
136
+ */
137
+ this.markerBlock_ = null;
138
+
139
+ /**
140
+ * @type {?SVGPathElement}
141
+ * @protected
142
+ */
143
+ this.markerInput_ = null;
144
+
145
+ /**
146
+ * @type {?SVGRectElement}
147
+ * @protected
148
+ */
149
+ this.markerSvgLine_ = null;
150
+
151
+ /**
152
+ * @type {?SVGRectElement}
153
+ * @protected
154
+ */
155
+ this.markerSvgRect_ = null;
156
+ }
80
157
 
81
158
  /**
82
- * The marker to draw.
83
- * @type {!Marker}
84
- * @private
159
+ * Return the root node of the SVG or null if none exists.
160
+ * @return {SVGElement} The root SVG node.
85
161
  */
86
- this.marker_ = marker;
162
+ getSvgRoot() {
163
+ return this.svgGroup_;
164
+ }
87
165
 
88
166
  /**
89
- * The workspace, field, or block that the marker SVG element should be
90
- * attached to.
91
- * @type {IASTNodeLocationSvg}
92
- * @private
167
+ * Get the marker.
168
+ * @return {!Marker} The marker to draw for.
93
169
  */
94
- this.parent_ = null;
170
+ getMarker() {
171
+ return this.marker_;
172
+ }
95
173
 
96
174
  /**
97
- * The constants necessary to draw the marker.
98
- * @type {ConstantProvider}
99
- * @protected
175
+ * True if the marker should be drawn as a cursor, false otherwise.
176
+ * A cursor is drawn as a flashing line. A marker is drawn as a solid line.
177
+ * @return {boolean} True if the marker is a cursor, false otherwise.
100
178
  */
101
- this.constants_ = constants;
179
+ isCursor() {
180
+ return this.marker_.type === 'cursor';
181
+ }
102
182
 
103
183
  /**
104
- * The current SVG element for the marker.
105
- * @type {Element}
184
+ * Create the DOM element for the marker.
185
+ * @return {!SVGElement} The marker controls SVG group.
186
+ * @package
106
187
  */
107
- this.currentMarkerSvg = null;
188
+ createDom() {
189
+ const className = this.isCursor() ? CURSOR_CLASS : MARKER_CLASS;
190
+
191
+ this.svgGroup_ = dom.createSvgElement(Svg.G, {'class': className}, null);
108
192
 
109
- const defaultColour = this.isCursor() ? this.constants_.CURSOR_COLOUR :
110
- this.constants_.MARKER_COLOUR;
193
+ this.createDomInternal_();
194
+ return this.svgGroup_;
195
+ }
111
196
 
112
197
  /**
113
- * The colour of the marker.
114
- * @type {string}
198
+ * Attaches the SVG root of the marker to the SVG group of the parent.
199
+ * @param {!IASTNodeLocationSvg} newParent The workspace, field, or
200
+ * block that the marker SVG element should be attached to.
201
+ * @protected
115
202
  */
116
- this.colour_ = marker.colour || defaultColour;
117
- };
203
+ setParent_(newParent) {
204
+ if (!this.isCursor()) {
205
+ if (this.parent_) {
206
+ this.parent_.setMarkerSvg(null);
207
+ }
208
+ newParent.setMarkerSvg(this.getSvgRoot());
209
+ } else {
210
+ if (this.parent_) {
211
+ this.parent_.setCursorSvg(null);
212
+ }
213
+ newParent.setCursorSvg(this.getSvgRoot());
214
+ }
215
+ this.parent_ = newParent;
216
+ }
118
217
 
119
- /**
120
- * Return the root node of the SVG or null if none exists.
121
- * @return {SVGElement} The root SVG node.
122
- */
123
- MarkerSvg.prototype.getSvgRoot = function() {
124
- return this.svgGroup_;
125
- };
218
+ /**
219
+ * Update the marker.
220
+ * @param {ASTNode} oldNode The previous node the marker was on or null.
221
+ * @param {ASTNode} curNode The node that we want to draw the marker for.
222
+ */
223
+ draw(oldNode, curNode) {
224
+ if (!curNode) {
225
+ this.hide();
226
+ return;
227
+ }
126
228
 
127
- /**
128
- * Get the marker.
129
- * @return {!Marker} The marker to draw for.
130
- */
131
- MarkerSvg.prototype.getMarker = function() {
132
- return this.marker_;
133
- };
229
+ this.constants_ = this.workspace_.getRenderer().getConstants();
134
230
 
135
- /**
136
- * True if the marker should be drawn as a cursor, false otherwise.
137
- * A cursor is drawn as a flashing line. A marker is drawn as a solid line.
138
- * @return {boolean} True if the marker is a cursor, false otherwise.
139
- */
140
- MarkerSvg.prototype.isCursor = function() {
141
- return this.marker_.type === 'cursor';
142
- };
231
+ const defaultColour = this.isCursor() ? this.constants_.CURSOR_COLOUR :
232
+ this.constants_.MARKER_COLOUR;
233
+ this.colour_ = this.marker_.colour || defaultColour;
234
+ this.applyColour_(curNode);
143
235
 
144
- /**
145
- * Create the DOM element for the marker.
146
- * @return {!SVGElement} The marker controls SVG group.
147
- * @package
148
- */
149
- MarkerSvg.prototype.createDom = function() {
150
- const className = this.isCursor() ? CURSOR_CLASS : MARKER_CLASS;
236
+ this.showAtLocation_(curNode);
151
237
 
152
- this.svgGroup_ = dom.createSvgElement(Svg.G, {'class': className}, null);
238
+ this.fireMarkerEvent_(oldNode, curNode);
153
239
 
154
- this.createDomInternal_();
155
- return this.svgGroup_;
156
- };
157
-
158
- /**
159
- * Attaches the SVG root of the marker to the SVG group of the parent.
160
- * @param {!IASTNodeLocationSvg} newParent The workspace, field, or
161
- * block that the marker SVG element should be attached to.
162
- * @protected
163
- */
164
- MarkerSvg.prototype.setParent_ = function(newParent) {
165
- if (!this.isCursor()) {
166
- if (this.parent_) {
167
- this.parent_.setMarkerSvg(null);
240
+ // Ensures the marker will be visible immediately after the move.
241
+ const animate = this.currentMarkerSvg.childNodes[0];
242
+ if (animate !== undefined) {
243
+ animate.beginElement && animate.beginElement();
168
244
  }
169
- newParent.setMarkerSvg(this.getSvgRoot());
170
- } else {
171
- if (this.parent_) {
172
- this.parent_.setCursorSvg(null);
173
- }
174
- newParent.setCursorSvg(this.getSvgRoot());
175
245
  }
176
- this.parent_ = newParent;
177
- };
178
246
 
179
- /**
180
- * Update the marker.
181
- * @param {ASTNode} oldNode The previous node the marker was on or null.
182
- * @param {ASTNode} curNode The node that we want to draw the marker for.
183
- */
184
- MarkerSvg.prototype.draw = function(oldNode, curNode) {
185
- if (!curNode) {
186
- this.hide();
187
- return;
247
+ /**
248
+ * Update the marker's visible state based on the type of curNode..
249
+ * @param {!ASTNode} curNode The node that we want to draw the marker for.
250
+ * @protected
251
+ */
252
+ showAtLocation_(curNode) {
253
+ const curNodeAsConnection =
254
+ /** @type {!Connection} */ (curNode.getLocation());
255
+ const connectionType = curNodeAsConnection.type;
256
+ if (curNode.getType() === ASTNode.types.BLOCK) {
257
+ this.showWithBlock_(curNode);
258
+ } else if (curNode.getType() === ASTNode.types.OUTPUT) {
259
+ this.showWithOutput_(curNode);
260
+ } else if (connectionType === ConnectionType.INPUT_VALUE) {
261
+ this.showWithInput_(curNode);
262
+ } else if (connectionType === ConnectionType.NEXT_STATEMENT) {
263
+ this.showWithNext_(curNode);
264
+ } else if (curNode.getType() === ASTNode.types.PREVIOUS) {
265
+ this.showWithPrevious_(curNode);
266
+ } else if (curNode.getType() === ASTNode.types.FIELD) {
267
+ this.showWithField_(curNode);
268
+ } else if (curNode.getType() === ASTNode.types.WORKSPACE) {
269
+ this.showWithCoordinates_(curNode);
270
+ } else if (curNode.getType() === ASTNode.types.STACK) {
271
+ this.showWithStack_(curNode);
272
+ }
188
273
  }
189
274
 
190
- this.constants_ = this.workspace_.getRenderer().getConstants();
191
-
192
- const defaultColour = this.isCursor() ? this.constants_.CURSOR_COLOUR :
193
- this.constants_.MARKER_COLOUR;
194
- this.colour_ = this.marker_.colour || defaultColour;
195
- this.applyColour_(curNode);
275
+ /**************************
276
+ * Display
277
+ **************************/
196
278
 
197
- this.showAtLocation_(curNode);
198
-
199
- this.fireMarkerEvent_(oldNode, curNode);
200
-
201
- // Ensures the marker will be visible immediately after the move.
202
- const animate = this.currentMarkerSvg.childNodes[0];
203
- if (animate !== undefined) {
204
- animate.beginElement && animate.beginElement();
279
+ /**
280
+ * Show the marker as a combination of the previous connection and block,
281
+ * the output connection and block, or just the block.
282
+ * @param {!ASTNode} curNode The node to draw the marker for.
283
+ * @private
284
+ */
285
+ showWithBlockPrevOutput_(curNode) {
286
+ const block = /** @type {!BlockSvg} */ (curNode.getSourceBlock());
287
+ const width = block.width;
288
+ const height = block.height;
289
+ const markerHeight = height * HEIGHT_MULTIPLIER;
290
+ const markerOffset = this.constants_.CURSOR_BLOCK_PADDING;
291
+
292
+ if (block.previousConnection) {
293
+ const connectionShape =
294
+ this.constants_.shapeFor(block.previousConnection);
295
+ this.positionPrevious_(
296
+ width, markerOffset, markerHeight, connectionShape);
297
+ } else if (block.outputConnection) {
298
+ const connectionShape = this.constants_.shapeFor(block.outputConnection);
299
+ this.positionOutput_(width, height, connectionShape);
300
+ } else {
301
+ this.positionBlock_(width, markerOffset, markerHeight);
302
+ }
303
+ this.setParent_(block);
304
+ this.showCurrent_();
205
305
  }
206
- };
207
306
 
208
-
209
- /**
210
- * Update the marker's visible state based on the type of curNode..
211
- * @param {!ASTNode} curNode The node that we want to draw the marker for.
212
- * @protected
213
- */
214
- MarkerSvg.prototype.showAtLocation_ = function(curNode) {
215
- const curNodeAsConnection =
216
- /** @type {!Connection} */ (curNode.getLocation());
217
- const connectionType = curNodeAsConnection.type;
218
- if (curNode.getType() === ASTNode.types.BLOCK) {
219
- this.showWithBlock_(curNode);
220
- } else if (curNode.getType() === ASTNode.types.OUTPUT) {
221
- this.showWithOutput_(curNode);
222
- } else if (connectionType === ConnectionType.INPUT_VALUE) {
223
- this.showWithInput_(curNode);
224
- } else if (connectionType === ConnectionType.NEXT_STATEMENT) {
225
- this.showWithNext_(curNode);
226
- } else if (curNode.getType() === ASTNode.types.PREVIOUS) {
227
- this.showWithPrevious_(curNode);
228
- } else if (curNode.getType() === ASTNode.types.FIELD) {
229
- this.showWithField_(curNode);
230
- } else if (curNode.getType() === ASTNode.types.WORKSPACE) {
231
- this.showWithCoordinates_(curNode);
232
- } else if (curNode.getType() === ASTNode.types.STACK) {
233
- this.showWithStack_(curNode);
307
+ /**
308
+ * Position and display the marker for a block.
309
+ * @param {!ASTNode} curNode The node to draw the marker for.
310
+ * @protected
311
+ */
312
+ showWithBlock_(curNode) {
313
+ this.showWithBlockPrevOutput_(curNode);
234
314
  }
235
- };
236
-
237
- /**************************
238
- * Display
239
- **************************/
240
315
 
241
- /**
242
- * Show the marker as a combination of the previous connection and block,
243
- * the output connection and block, or just the block.
244
- * @param {!ASTNode} curNode The node to draw the marker for.
245
- * @private
246
- */
247
- MarkerSvg.prototype.showWithBlockPrevOutput_ = function(curNode) {
248
- const block = /** @type {!BlockSvg} */ (curNode.getSourceBlock());
249
- const width = block.width;
250
- const height = block.height;
251
- const markerHeight = height * HEIGHT_MULTIPLIER;
252
- const markerOffset = this.constants_.CURSOR_BLOCK_PADDING;
253
-
254
- if (block.previousConnection) {
255
- const connectionShape = this.constants_.shapeFor(block.previousConnection);
256
- this.positionPrevious_(width, markerOffset, markerHeight, connectionShape);
257
- } else if (block.outputConnection) {
258
- const connectionShape = this.constants_.shapeFor(block.outputConnection);
259
- this.positionOutput_(width, height, connectionShape);
260
- } else {
261
- this.positionBlock_(width, markerOffset, markerHeight);
316
+ /**
317
+ * Position and display the marker for a previous connection.
318
+ * @param {!ASTNode} curNode The node to draw the marker for.
319
+ * @protected
320
+ */
321
+ showWithPrevious_(curNode) {
322
+ this.showWithBlockPrevOutput_(curNode);
262
323
  }
263
- this.setParent_(block);
264
- this.showCurrent_();
265
- };
266
-
267
- /**
268
- * Position and display the marker for a block.
269
- * @param {!ASTNode} curNode The node to draw the marker for.
270
- * @protected
271
- */
272
- MarkerSvg.prototype.showWithBlock_ = function(curNode) {
273
- this.showWithBlockPrevOutput_(curNode);
274
- };
275
324
 
276
- /**
277
- * Position and display the marker for a previous connection.
278
- * @param {!ASTNode} curNode The node to draw the marker for.
279
- * @protected
280
- */
281
- MarkerSvg.prototype.showWithPrevious_ = function(curNode) {
282
- this.showWithBlockPrevOutput_(curNode);
283
- };
284
-
285
- /**
286
- * Position and display the marker for an output connection.
287
- * @param {!ASTNode} curNode The node to draw the marker for.
288
- * @protected
289
- */
290
- MarkerSvg.prototype.showWithOutput_ = function(curNode) {
291
- this.showWithBlockPrevOutput_(curNode);
292
- };
293
-
294
- /**
295
- * Position and display the marker for a workspace coordinate.
296
- * This is a horizontal line.
297
- * @param {!ASTNode} curNode The node to draw the marker for.
298
- * @protected
299
- */
300
- MarkerSvg.prototype.showWithCoordinates_ = function(curNode) {
301
- const wsCoordinate = curNode.getWsCoordinate();
302
- let x = wsCoordinate.x;
303
- const y = wsCoordinate.y;
304
-
305
- if (this.workspace_.RTL) {
306
- x -= this.constants_.CURSOR_WS_WIDTH;
325
+ /**
326
+ * Position and display the marker for an output connection.
327
+ * @param {!ASTNode} curNode The node to draw the marker for.
328
+ * @protected
329
+ */
330
+ showWithOutput_(curNode) {
331
+ this.showWithBlockPrevOutput_(curNode);
307
332
  }
308
333
 
309
- this.positionLine_(x, y, this.constants_.CURSOR_WS_WIDTH);
310
- this.setParent_(this.workspace_);
311
- this.showCurrent_();
312
- };
313
-
314
- /**
315
- * Position and display the marker for a field.
316
- * This is a box around the field.
317
- * @param {!ASTNode} curNode The node to draw the marker for.
318
- * @protected
319
- */
320
- MarkerSvg.prototype.showWithField_ = function(curNode) {
321
- const field = /** @type {Field} */ (curNode.getLocation());
322
- const width = field.getSize().width;
323
- const height = field.getSize().height;
334
+ /**
335
+ * Position and display the marker for a workspace coordinate.
336
+ * This is a horizontal line.
337
+ * @param {!ASTNode} curNode The node to draw the marker for.
338
+ * @protected
339
+ */
340
+ showWithCoordinates_(curNode) {
341
+ const wsCoordinate = curNode.getWsCoordinate();
342
+ let x = wsCoordinate.x;
343
+ const y = wsCoordinate.y;
324
344
 
325
- this.positionRect_(0, 0, width, height);
326
- this.setParent_(field);
327
- this.showCurrent_();
328
- };
345
+ if (this.workspace_.RTL) {
346
+ x -= this.constants_.CURSOR_WS_WIDTH;
347
+ }
329
348
 
330
- /**
331
- * Position and display the marker for an input.
332
- * This is a puzzle piece.
333
- * @param {!ASTNode} curNode The node to draw the marker for.
334
- * @protected
335
- */
336
- MarkerSvg.prototype.showWithInput_ = function(curNode) {
337
- const connection = /** @type {RenderedConnection} */
338
- (curNode.getLocation());
339
- const sourceBlock = /** @type {!BlockSvg} */ (connection.getSourceBlock());
349
+ this.positionLine_(x, y, this.constants_.CURSOR_WS_WIDTH);
350
+ this.setParent_(this.workspace_);
351
+ this.showCurrent_();
352
+ }
340
353
 
341
- this.positionInput_(connection);
342
- this.setParent_(sourceBlock);
343
- this.showCurrent_();
344
- };
354
+ /**
355
+ * Position and display the marker for a field.
356
+ * This is a box around the field.
357
+ * @param {!ASTNode} curNode The node to draw the marker for.
358
+ * @protected
359
+ */
360
+ showWithField_(curNode) {
361
+ const field = /** @type {Field} */ (curNode.getLocation());
362
+ const width = field.getSize().width;
363
+ const height = field.getSize().height;
364
+
365
+ this.positionRect_(0, 0, width, height);
366
+ this.setParent_(field);
367
+ this.showCurrent_();
368
+ }
345
369
 
370
+ /**
371
+ * Position and display the marker for an input.
372
+ * This is a puzzle piece.
373
+ * @param {!ASTNode} curNode The node to draw the marker for.
374
+ * @protected
375
+ */
376
+ showWithInput_(curNode) {
377
+ const connection = /** @type {RenderedConnection} */
378
+ (curNode.getLocation());
379
+ const sourceBlock = /** @type {!BlockSvg} */ (connection.getSourceBlock());
380
+
381
+ this.positionInput_(connection);
382
+ this.setParent_(sourceBlock);
383
+ this.showCurrent_();
384
+ }
346
385
 
347
- /**
348
- * Position and display the marker for a next connection.
349
- * This is a horizontal line.
350
- * @param {!ASTNode} curNode The node to draw the marker for.
351
- * @protected
352
- */
353
- MarkerSvg.prototype.showWithNext_ = function(curNode) {
354
- const connection =
355
- /** @type {!RenderedConnection} */ (curNode.getLocation());
356
- const targetBlock =
357
- /** @type {BlockSvg} */ (connection.getSourceBlock());
358
- let x = 0;
359
- const y = connection.getOffsetInBlock().y;
360
- const width = targetBlock.getHeightWidth().width;
361
- if (this.workspace_.RTL) {
362
- x = -width;
386
+ /**
387
+ * Position and display the marker for a next connection.
388
+ * This is a horizontal line.
389
+ * @param {!ASTNode} curNode The node to draw the marker for.
390
+ * @protected
391
+ */
392
+ showWithNext_(curNode) {
393
+ const connection =
394
+ /** @type {!RenderedConnection} */ (curNode.getLocation());
395
+ const targetBlock =
396
+ /** @type {BlockSvg} */ (connection.getSourceBlock());
397
+ let x = 0;
398
+ const y = connection.getOffsetInBlock().y;
399
+ const width = targetBlock.getHeightWidth().width;
400
+ if (this.workspace_.RTL) {
401
+ x = -width;
402
+ }
403
+ this.positionLine_(x, y, width);
404
+ this.setParent_(targetBlock);
405
+ this.showCurrent_();
363
406
  }
364
- this.positionLine_(x, y, width);
365
- this.setParent_(targetBlock);
366
- this.showCurrent_();
367
- };
368
407
 
369
- /**
370
- * Position and display the marker for a stack.
371
- * This is a box with extra padding around the entire stack of blocks.
372
- * @param {!ASTNode} curNode The node to draw the marker for.
373
- * @protected
374
- */
375
- MarkerSvg.prototype.showWithStack_ = function(curNode) {
376
- const block = /** @type {BlockSvg} */ (curNode.getLocation());
408
+ /**
409
+ * Position and display the marker for a stack.
410
+ * This is a box with extra padding around the entire stack of blocks.
411
+ * @param {!ASTNode} curNode The node to draw the marker for.
412
+ * @protected
413
+ */
414
+ showWithStack_(curNode) {
415
+ const block = /** @type {BlockSvg} */ (curNode.getLocation());
377
416
 
378
- // Gets the height and width of entire stack.
379
- const heightWidth = block.getHeightWidth();
417
+ // Gets the height and width of entire stack.
418
+ const heightWidth = block.getHeightWidth();
380
419
 
381
- // Add padding so that being on a stack looks different than being on a block.
382
- const width = heightWidth.width + this.constants_.CURSOR_STACK_PADDING;
383
- const height = heightWidth.height + this.constants_.CURSOR_STACK_PADDING;
420
+ // Add padding so that being on a stack looks different than being on a
421
+ // block.
422
+ const width = heightWidth.width + this.constants_.CURSOR_STACK_PADDING;
423
+ const height = heightWidth.height + this.constants_.CURSOR_STACK_PADDING;
384
424
 
385
- // Shift the rectangle slightly to upper left so padding is equal on all
386
- // sides.
387
- const xPadding = -this.constants_.CURSOR_STACK_PADDING / 2;
388
- const yPadding = -this.constants_.CURSOR_STACK_PADDING / 2;
425
+ // Shift the rectangle slightly to upper left so padding is equal on all
426
+ // sides.
427
+ const xPadding = -this.constants_.CURSOR_STACK_PADDING / 2;
428
+ const yPadding = -this.constants_.CURSOR_STACK_PADDING / 2;
389
429
 
390
- let x = xPadding;
391
- const y = yPadding;
430
+ let x = xPadding;
431
+ const y = yPadding;
392
432
 
393
- if (this.workspace_.RTL) {
394
- x = -(width + xPadding);
433
+ if (this.workspace_.RTL) {
434
+ x = -(width + xPadding);
435
+ }
436
+ this.positionRect_(x, y, width, height);
437
+ this.setParent_(block);
438
+ this.showCurrent_();
395
439
  }
396
- this.positionRect_(x, y, width, height);
397
- this.setParent_(block);
398
- this.showCurrent_();
399
- };
400
440
 
401
- /**
402
- * Show the current marker.
403
- * @protected
404
- */
405
- MarkerSvg.prototype.showCurrent_ = function() {
406
- this.hide();
407
- this.currentMarkerSvg.style.display = '';
408
- };
409
-
410
- /**************************
411
- * Position
412
- **************************/
413
-
414
- /**
415
- * Position the marker for a block.
416
- * Displays an outline of the top half of a rectangle around a block.
417
- * @param {number} width The width of the block.
418
- * @param {number} markerOffset The extra padding for around the block.
419
- * @param {number} markerHeight The height of the marker.
420
- * @protected
421
- */
422
- MarkerSvg.prototype.positionBlock_ = function(
423
- width, markerOffset, markerHeight) {
424
- const markerPath = svgPaths.moveBy(-markerOffset, markerHeight) +
425
- svgPaths.lineOnAxis('V', -markerOffset) +
426
- svgPaths.lineOnAxis('H', width + markerOffset * 2) +
427
- svgPaths.lineOnAxis('V', markerHeight);
428
- this.markerBlock_.setAttribute('d', markerPath);
429
- if (this.workspace_.RTL) {
430
- this.flipRtl_(this.markerBlock_);
441
+ /**
442
+ * Show the current marker.
443
+ * @protected
444
+ */
445
+ showCurrent_() {
446
+ this.hide();
447
+ this.currentMarkerSvg.style.display = '';
431
448
  }
432
- this.currentMarkerSvg = this.markerBlock_;
433
- };
434
-
435
- /**
436
- * Position the marker for an input connection.
437
- * Displays a filled in puzzle piece.
438
- * @param {!RenderedConnection} connection The connection to position
439
- * marker around.
440
- * @protected
441
- */
442
- MarkerSvg.prototype.positionInput_ = function(connection) {
443
- const x = connection.getOffsetInBlock().x;
444
- const y = connection.getOffsetInBlock().y;
445
449
 
446
- const path =
447
- svgPaths.moveTo(0, 0) + this.constants_.shapeFor(connection).pathDown;
450
+ /**************************
451
+ * Position
452
+ **************************/
448
453
 
449
- this.markerInput_.setAttribute('d', path);
450
- this.markerInput_.setAttribute(
451
- 'transform',
452
- 'translate(' + x + ',' + y + ')' +
453
- (this.workspace_.RTL ? ' scale(-1 1)' : ''));
454
- this.currentMarkerSvg = this.markerInput_;
455
- };
454
+ /**
455
+ * Position the marker for a block.
456
+ * Displays an outline of the top half of a rectangle around a block.
457
+ * @param {number} width The width of the block.
458
+ * @param {number} markerOffset The extra padding for around the block.
459
+ * @param {number} markerHeight The height of the marker.
460
+ * @protected
461
+ */
462
+ positionBlock_(width, markerOffset, markerHeight) {
463
+ const markerPath = svgPaths.moveBy(-markerOffset, markerHeight) +
464
+ svgPaths.lineOnAxis('V', -markerOffset) +
465
+ svgPaths.lineOnAxis('H', width + markerOffset * 2) +
466
+ svgPaths.lineOnAxis('V', markerHeight);
467
+ this.markerBlock_.setAttribute('d', markerPath);
468
+ if (this.workspace_.RTL) {
469
+ this.flipRtl_(this.markerBlock_);
470
+ }
471
+ this.currentMarkerSvg = this.markerBlock_;
472
+ }
456
473
 
457
- /**
458
- * Move and show the marker at the specified coordinate in workspace units.
459
- * Displays a horizontal line.
460
- * @param {number} x The new x, in workspace units.
461
- * @param {number} y The new y, in workspace units.
462
- * @param {number} width The new width, in workspace units.
463
- * @protected
464
- */
465
- MarkerSvg.prototype.positionLine_ = function(x, y, width) {
466
- this.markerSvgLine_.setAttribute('x', x);
467
- this.markerSvgLine_.setAttribute('y', y);
468
- this.markerSvgLine_.setAttribute('width', width);
469
- this.currentMarkerSvg = this.markerSvgLine_;
470
- };
474
+ /**
475
+ * Position the marker for an input connection.
476
+ * Displays a filled in puzzle piece.
477
+ * @param {!RenderedConnection} connection The connection to position
478
+ * marker around.
479
+ * @protected
480
+ */
481
+ positionInput_(connection) {
482
+ const x = connection.getOffsetInBlock().x;
483
+ const y = connection.getOffsetInBlock().y;
484
+
485
+ const path =
486
+ svgPaths.moveTo(0, 0) + this.constants_.shapeFor(connection).pathDown;
487
+
488
+ this.markerInput_.setAttribute('d', path);
489
+ this.markerInput_.setAttribute(
490
+ 'transform',
491
+ 'translate(' + x + ',' + y + ')' +
492
+ (this.workspace_.RTL ? ' scale(-1 1)' : ''));
493
+ this.currentMarkerSvg = this.markerInput_;
494
+ }
471
495
 
472
- /**
473
- * Position the marker for an output connection.
474
- * Displays a puzzle outline and the top and bottom path.
475
- * @param {number} width The width of the block.
476
- * @param {number} height The height of the block.
477
- * @param {!Object} connectionShape The shape object for the connection.
478
- * @protected
479
- */
480
- MarkerSvg.prototype.positionOutput_ = function(width, height, connectionShape) {
481
- const markerPath = svgPaths.moveBy(width, 0) +
482
- svgPaths.lineOnAxis('h', -(width - connectionShape.width)) +
483
- svgPaths.lineOnAxis('v', this.constants_.TAB_OFFSET_FROM_TOP) +
484
- connectionShape.pathDown + svgPaths.lineOnAxis('V', height) +
485
- svgPaths.lineOnAxis('H', width);
486
- this.markerBlock_.setAttribute('d', markerPath);
487
- if (this.workspace_.RTL) {
488
- this.flipRtl_(this.markerBlock_);
496
+ /**
497
+ * Move and show the marker at the specified coordinate in workspace units.
498
+ * Displays a horizontal line.
499
+ * @param {number} x The new x, in workspace units.
500
+ * @param {number} y The new y, in workspace units.
501
+ * @param {number} width The new width, in workspace units.
502
+ * @protected
503
+ */
504
+ positionLine_(x, y, width) {
505
+ this.markerSvgLine_.setAttribute('x', x);
506
+ this.markerSvgLine_.setAttribute('y', y);
507
+ this.markerSvgLine_.setAttribute('width', width);
508
+ this.currentMarkerSvg = this.markerSvgLine_;
489
509
  }
490
- this.currentMarkerSvg = this.markerBlock_;
491
- };
492
510
 
493
- /**
494
- * Position the marker for a previous connection.
495
- * Displays a half rectangle with a notch in the top to represent the previous
496
- * connection.
497
- * @param {number} width The width of the block.
498
- * @param {number} markerOffset The offset of the marker from around the block.
499
- * @param {number} markerHeight The height of the marker.
500
- * @param {!Object} connectionShape The shape object for the connection.
501
- * @protected
502
- */
503
- MarkerSvg.prototype.positionPrevious_ = function(
504
- width, markerOffset, markerHeight, connectionShape) {
505
- const markerPath = svgPaths.moveBy(-markerOffset, markerHeight) +
506
- svgPaths.lineOnAxis('V', -markerOffset) +
507
- svgPaths.lineOnAxis('H', this.constants_.NOTCH_OFFSET_LEFT) +
508
- connectionShape.pathLeft +
509
- svgPaths.lineOnAxis('H', width + markerOffset * 2) +
510
- svgPaths.lineOnAxis('V', markerHeight);
511
- this.markerBlock_.setAttribute('d', markerPath);
512
- if (this.workspace_.RTL) {
513
- this.flipRtl_(this.markerBlock_);
511
+ /**
512
+ * Position the marker for an output connection.
513
+ * Displays a puzzle outline and the top and bottom path.
514
+ * @param {number} width The width of the block.
515
+ * @param {number} height The height of the block.
516
+ * @param {!Object} connectionShape The shape object for the connection.
517
+ * @protected
518
+ */
519
+ positionOutput_(width, height, connectionShape) {
520
+ const markerPath = svgPaths.moveBy(width, 0) +
521
+ svgPaths.lineOnAxis('h', -(width - connectionShape.width)) +
522
+ svgPaths.lineOnAxis('v', this.constants_.TAB_OFFSET_FROM_TOP) +
523
+ connectionShape.pathDown + svgPaths.lineOnAxis('V', height) +
524
+ svgPaths.lineOnAxis('H', width);
525
+ this.markerBlock_.setAttribute('d', markerPath);
526
+ if (this.workspace_.RTL) {
527
+ this.flipRtl_(this.markerBlock_);
528
+ }
529
+ this.currentMarkerSvg = this.markerBlock_;
514
530
  }
515
- this.currentMarkerSvg = this.markerBlock_;
516
- };
517
531
 
518
- /**
519
- * Move and show the marker at the specified coordinate in workspace units.
520
- * Displays a filled in rectangle.
521
- * @param {number} x The new x, in workspace units.
522
- * @param {number} y The new y, in workspace units.
523
- * @param {number} width The new width, in workspace units.
524
- * @param {number} height The new height, in workspace units.
525
- * @protected
526
- */
527
- MarkerSvg.prototype.positionRect_ = function(x, y, width, height) {
528
- this.markerSvgRect_.setAttribute('x', x);
529
- this.markerSvgRect_.setAttribute('y', y);
530
- this.markerSvgRect_.setAttribute('width', width);
531
- this.markerSvgRect_.setAttribute('height', height);
532
- this.currentMarkerSvg = this.markerSvgRect_;
533
- };
532
+ /**
533
+ * Position the marker for a previous connection.
534
+ * Displays a half rectangle with a notch in the top to represent the previous
535
+ * connection.
536
+ * @param {number} width The width of the block.
537
+ * @param {number} markerOffset The offset of the marker from around the
538
+ * block.
539
+ * @param {number} markerHeight The height of the marker.
540
+ * @param {!Object} connectionShape The shape object for the connection.
541
+ * @protected
542
+ */
543
+ positionPrevious_(width, markerOffset, markerHeight, connectionShape) {
544
+ const markerPath = svgPaths.moveBy(-markerOffset, markerHeight) +
545
+ svgPaths.lineOnAxis('V', -markerOffset) +
546
+ svgPaths.lineOnAxis('H', this.constants_.NOTCH_OFFSET_LEFT) +
547
+ connectionShape.pathLeft +
548
+ svgPaths.lineOnAxis('H', width + markerOffset * 2) +
549
+ svgPaths.lineOnAxis('V', markerHeight);
550
+ this.markerBlock_.setAttribute('d', markerPath);
551
+ if (this.workspace_.RTL) {
552
+ this.flipRtl_(this.markerBlock_);
553
+ }
554
+ this.currentMarkerSvg = this.markerBlock_;
555
+ }
534
556
 
535
- /**
536
- * Flip the SVG paths in RTL.
537
- * @param {!SVGElement} markerSvg The marker that we want to flip.
538
- * @private
539
- */
540
- MarkerSvg.prototype.flipRtl_ = function(markerSvg) {
541
- markerSvg.setAttribute('transform', 'scale(-1 1)');
542
- };
557
+ /**
558
+ * Move and show the marker at the specified coordinate in workspace units.
559
+ * Displays a filled in rectangle.
560
+ * @param {number} x The new x, in workspace units.
561
+ * @param {number} y The new y, in workspace units.
562
+ * @param {number} width The new width, in workspace units.
563
+ * @param {number} height The new height, in workspace units.
564
+ * @protected
565
+ */
566
+ positionRect_(x, y, width, height) {
567
+ this.markerSvgRect_.setAttribute('x', x);
568
+ this.markerSvgRect_.setAttribute('y', y);
569
+ this.markerSvgRect_.setAttribute('width', width);
570
+ this.markerSvgRect_.setAttribute('height', height);
571
+ this.currentMarkerSvg = this.markerSvgRect_;
572
+ }
543
573
 
544
- /**
545
- * Hide the marker.
546
- */
547
- MarkerSvg.prototype.hide = function() {
548
- this.markerSvgLine_.style.display = 'none';
549
- this.markerSvgRect_.style.display = 'none';
550
- this.markerInput_.style.display = 'none';
551
- this.markerBlock_.style.display = 'none';
552
- };
574
+ /**
575
+ * Flip the SVG paths in RTL.
576
+ * @param {!SVGElement} markerSvg The marker that we want to flip.
577
+ * @private
578
+ */
579
+ flipRtl_(markerSvg) {
580
+ markerSvg.setAttribute('transform', 'scale(-1 1)');
581
+ }
553
582
 
583
+ /**
584
+ * Hide the marker.
585
+ */
586
+ hide() {
587
+ this.markerSvgLine_.style.display = 'none';
588
+ this.markerSvgRect_.style.display = 'none';
589
+ this.markerInput_.style.display = 'none';
590
+ this.markerBlock_.style.display = 'none';
591
+ }
554
592
 
555
- /**
556
- * Fire event for the marker or marker.
557
- * @param {ASTNode} oldNode The old node the marker used to be on.
558
- * @param {!ASTNode} curNode The new node the marker is currently on.
559
- * @private
560
- */
561
- MarkerSvg.prototype.fireMarkerEvent_ = function(oldNode, curNode) {
562
- const curBlock = curNode.getSourceBlock();
563
- const event = new (eventUtils.get(eventUtils.MARKER_MOVE))(
564
- curBlock, this.isCursor(), oldNode, curNode);
565
- eventUtils.fire(event);
566
- };
593
+ /**
594
+ * Fire event for the marker or marker.
595
+ * @param {ASTNode} oldNode The old node the marker used to be on.
596
+ * @param {!ASTNode} curNode The new node the marker is currently on.
597
+ * @private
598
+ */
599
+ fireMarkerEvent_(oldNode, curNode) {
600
+ const curBlock = curNode.getSourceBlock();
601
+ const event = new (eventUtils.get(eventUtils.MARKER_MOVE))(
602
+ curBlock, this.isCursor(), oldNode, curNode);
603
+ eventUtils.fire(event);
604
+ }
567
605
 
568
- /**
569
- * Get the properties to make a marker blink.
570
- * @return {!Object} The object holding attributes to make the marker blink.
571
- * @protected
572
- */
573
- MarkerSvg.prototype.getBlinkProperties_ = function() {
574
- return {
575
- 'attributeType': 'XML',
576
- 'attributeName': 'fill',
577
- 'dur': '1s',
578
- 'values': this.colour_ + ';transparent;transparent;',
579
- 'repeatCount': 'indefinite',
580
- };
581
- };
606
+ /**
607
+ * Get the properties to make a marker blink.
608
+ * @return {!Object} The object holding attributes to make the marker blink.
609
+ * @protected
610
+ */
611
+ getBlinkProperties_() {
612
+ return {
613
+ 'attributeType': 'XML',
614
+ 'attributeName': 'fill',
615
+ 'dur': '1s',
616
+ 'values': this.colour_ + ';transparent;transparent;',
617
+ 'repeatCount': 'indefinite',
618
+ };
619
+ }
582
620
 
621
+ /**
622
+ * Create the marker SVG.
623
+ * @return {Element} The SVG node created.
624
+ * @protected
625
+ */
626
+ createDomInternal_() {
627
+ /* This markup will be generated and added to the .svgGroup_:
628
+ <g>
629
+ <rect width="100" height="5">
630
+ <animate attributeType="XML" attributeName="fill" dur="1s"
631
+ values="transparent;transparent;#fff;transparent"
632
+ repeatCount="indefinite" />
633
+ </rect>
634
+ </g>
635
+ */
636
+
637
+ this.markerSvg_ = dom.createSvgElement(
638
+ Svg.G, {
639
+ 'width': this.constants_.CURSOR_WS_WIDTH,
640
+ 'height': this.constants_.WS_CURSOR_HEIGHT,
641
+ },
642
+ this.svgGroup_);
643
+
644
+ // A horizontal line used to represent a workspace coordinate or next
645
+ // connection.
646
+ this.markerSvgLine_ = dom.createSvgElement(
647
+ Svg.RECT, {
648
+ 'width': this.constants_.CURSOR_WS_WIDTH,
649
+ 'height': this.constants_.WS_CURSOR_HEIGHT,
650
+ 'style': 'display: none',
651
+ },
652
+ this.markerSvg_);
653
+
654
+ // A filled in rectangle used to represent a stack.
655
+ this.markerSvgRect_ = dom.createSvgElement(
656
+ Svg.RECT, {
657
+ 'class': 'blocklyVerticalMarker',
658
+ 'rx': 10,
659
+ 'ry': 10,
660
+ 'style': 'display: none',
661
+ },
662
+ this.markerSvg_);
663
+
664
+ // A filled in puzzle piece used to represent an input value.
665
+ this.markerInput_ = dom.createSvgElement(
666
+ Svg.PATH, {'transform': '', 'style': 'display: none'}, this.markerSvg_);
667
+
668
+ // A path used to represent a previous connection and a block, an output
669
+ // connection and a block, or a block.
670
+ this.markerBlock_ = dom.createSvgElement(
671
+ Svg.PATH, {
672
+ 'transform': '',
673
+ 'style': 'display: none',
674
+ 'fill': 'none',
675
+ 'stroke-width': this.constants_.CURSOR_STROKE_WIDTH,
676
+ },
677
+ this.markerSvg_);
678
+
679
+ // Markers and stack markers don't blink.
680
+ if (this.isCursor()) {
681
+ const blinkProperties = this.getBlinkProperties_();
682
+ dom.createSvgElement(Svg.ANIMATE, blinkProperties, this.markerSvgLine_);
683
+ dom.createSvgElement(Svg.ANIMATE, blinkProperties, this.markerInput_);
684
+ blinkProperties['attributeName'] = 'stroke';
685
+ dom.createSvgElement(Svg.ANIMATE, blinkProperties, this.markerBlock_);
686
+ }
583
687
 
584
- /**
585
- * Create the marker SVG.
586
- * @return {Element} The SVG node created.
587
- * @protected
588
- */
589
- MarkerSvg.prototype.createDomInternal_ = function() {
590
- /* This markup will be generated and added to the .svgGroup_:
591
- <g>
592
- <rect width="100" height="5">
593
- <animate attributeType="XML" attributeName="fill" dur="1s"
594
- values="transparent;transparent;#fff;transparent"
595
- repeatCount="indefinite" />
596
- </rect>
597
- </g>
598
- */
599
-
600
- this.markerSvg_ = dom.createSvgElement(
601
- Svg.G, {
602
- 'width': this.constants_.CURSOR_WS_WIDTH,
603
- 'height': this.constants_.WS_CURSOR_HEIGHT,
604
- },
605
- this.svgGroup_);
606
-
607
- // A horizontal line used to represent a workspace coordinate or next
608
- // connection.
609
- this.markerSvgLine_ = dom.createSvgElement(
610
- Svg.RECT, {
611
- 'width': this.constants_.CURSOR_WS_WIDTH,
612
- 'height': this.constants_.WS_CURSOR_HEIGHT,
613
- 'style': 'display: none',
614
- },
615
- this.markerSvg_);
616
-
617
- // A filled in rectangle used to represent a stack.
618
- this.markerSvgRect_ = dom.createSvgElement(
619
- Svg.RECT, {
620
- 'class': 'blocklyVerticalMarker',
621
- 'rx': 10,
622
- 'ry': 10,
623
- 'style': 'display: none',
624
- },
625
- this.markerSvg_);
626
-
627
- // A filled in puzzle piece used to represent an input value.
628
- this.markerInput_ = dom.createSvgElement(
629
- Svg.PATH, {'transform': '', 'style': 'display: none'}, this.markerSvg_);
630
-
631
- // A path used to represent a previous connection and a block, an output
632
- // connection and a block, or a block.
633
- this.markerBlock_ = dom.createSvgElement(
634
- Svg.PATH, {
635
- 'transform': '',
636
- 'style': 'display: none',
637
- 'fill': 'none',
638
- 'stroke-width': this.constants_.CURSOR_STROKE_WIDTH,
639
- },
640
- this.markerSvg_);
641
-
642
- // Markers and stack markers don't blink.
643
- if (this.isCursor()) {
644
- const blinkProperties = this.getBlinkProperties_();
645
- dom.createSvgElement(Svg.ANIMATE, blinkProperties, this.markerSvgLine_);
646
- dom.createSvgElement(Svg.ANIMATE, blinkProperties, this.markerInput_);
647
- blinkProperties['attributeName'] = 'stroke';
648
- dom.createSvgElement(Svg.ANIMATE, blinkProperties, this.markerBlock_);
688
+ return this.markerSvg_;
649
689
  }
650
690
 
651
- return this.markerSvg_;
652
- };
653
-
654
- /**
655
- * Apply the marker's colour.
656
- * @param {!ASTNode} _curNode The node that we want to draw the marker
657
- * for.
658
- * @protected
659
- */
660
- MarkerSvg.prototype.applyColour_ = function(_curNode) {
661
- this.markerSvgLine_.setAttribute('fill', this.colour_);
662
- this.markerSvgRect_.setAttribute('stroke', this.colour_);
663
- this.markerInput_.setAttribute('fill', this.colour_);
664
- this.markerBlock_.setAttribute('stroke', this.colour_);
665
-
666
- if (this.isCursor()) {
667
- const values = this.colour_ + ';transparent;transparent;';
668
- this.markerSvgLine_.firstChild.setAttribute('values', values);
669
- this.markerInput_.firstChild.setAttribute('values', values);
670
- this.markerBlock_.firstChild.setAttribute('values', values);
691
+ /**
692
+ * Apply the marker's colour.
693
+ * @param {!ASTNode} _curNode The node that we want to draw the marker
694
+ * for.
695
+ * @protected
696
+ */
697
+ applyColour_(_curNode) {
698
+ this.markerSvgLine_.setAttribute('fill', this.colour_);
699
+ this.markerSvgRect_.setAttribute('stroke', this.colour_);
700
+ this.markerInput_.setAttribute('fill', this.colour_);
701
+ this.markerBlock_.setAttribute('stroke', this.colour_);
702
+
703
+ if (this.isCursor()) {
704
+ const values = this.colour_ + ';transparent;transparent;';
705
+ this.markerSvgLine_.firstChild.setAttribute('values', values);
706
+ this.markerInput_.firstChild.setAttribute('values', values);
707
+ this.markerBlock_.firstChild.setAttribute('values', values);
708
+ }
671
709
  }
672
- };
673
710
 
674
- /**
675
- * Dispose of this marker.
676
- */
677
- MarkerSvg.prototype.dispose = function() {
678
- if (this.svgGroup_) {
679
- dom.removeNode(this.svgGroup_);
711
+ /**
712
+ * Dispose of this marker.
713
+ */
714
+ dispose() {
715
+ if (this.svgGroup_) {
716
+ dom.removeNode(this.svgGroup_);
717
+ }
680
718
  }
681
- };
719
+ }
682
720
 
683
721
  exports.MarkerSvg = MarkerSvg;