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.
- package/blockly.d.ts +18963 -18432
- package/blockly.min.js +852 -844
- package/blockly_compressed.js +669 -664
- package/blockly_compressed.js.map +1 -1
- package/blocks/blocks.js +47 -0
- package/blocks/colour.js +13 -3
- package/blocks/lists.js +22 -13
- package/blocks/logic.js +13 -3
- package/blocks/loops.js +24 -11
- package/blocks/math.js +12 -3
- package/blocks/procedures.js +41 -27
- package/blocks/text.js +22 -13
- package/blocks/variables.js +14 -3
- package/blocks/variables_dynamic.js +13 -3
- package/blocks_compressed.js +146 -141
- package/blocks_compressed.js.map +1 -1
- package/core/block.js +1869 -1814
- package/core/block_drag_surface.js +201 -200
- package/core/block_dragger.js +377 -373
- package/core/block_svg.js +1593 -1479
- package/core/blockly.js +8 -22
- package/core/blocks.js +9 -2
- package/core/browser_events.js +22 -5
- package/core/bubble.js +841 -797
- package/core/bubble_dragger.js +213 -206
- package/core/bump_objects.js +2 -2
- package/core/clipboard.js +9 -9
- package/core/comment.js +353 -332
- package/core/common.js +46 -17
- package/core/component_manager.js +181 -174
- package/core/config.js +87 -0
- package/core/connection.js +595 -584
- package/core/connection_checker.js +242 -244
- package/core/connection_db.js +235 -230
- package/core/contextmenu.js +9 -6
- package/core/contextmenu_items.js +1 -2
- package/core/contextmenu_registry.js +93 -89
- package/core/css.js +474 -474
- package/core/delete_area.js +45 -42
- package/core/drag_target.js +57 -56
- package/core/dropdowndiv.js +153 -163
- package/core/events/events.js +2 -2
- package/core/events/events_abstract.js +89 -77
- package/core/events/events_block_base.js +37 -36
- package/core/events/events_block_change.js +130 -124
- package/core/events/events_block_create.js +73 -71
- package/core/events/events_block_delete.js +84 -82
- package/core/events/events_block_drag.js +50 -49
- package/core/events/events_block_move.js +147 -140
- package/core/events/events_bubble_open.js +51 -50
- package/core/events/events_click.js +48 -44
- package/core/events/events_comment_base.js +72 -69
- package/core/events/events_comment_change.js +63 -61
- package/core/events/events_comment_create.js +44 -42
- package/core/events/events_comment_delete.js +42 -40
- package/core/events/events_comment_move.js +106 -104
- package/core/events/events_marker_move.js +65 -64
- package/core/events/events_selected.js +46 -45
- package/core/events/events_theme_change.js +36 -35
- package/core/events/events_toolbox_item_select.js +46 -45
- package/core/events/events_trashcan_open.js +37 -36
- package/core/events/events_ui.js +47 -46
- package/core/events/events_ui_base.js +30 -29
- package/core/events/events_var_base.js +37 -36
- package/core/events/events_var_create.js +50 -48
- package/core/events/events_var_delete.js +50 -48
- package/core/events/events_var_rename.js +51 -49
- package/core/events/events_viewport.js +66 -65
- package/core/events/utils.js +29 -14
- package/core/events/workspace_events.js +49 -55
- package/core/extensions.js +4 -3
- package/core/field.js +1061 -997
- package/core/field_angle.js +462 -442
- package/core/field_checkbox.js +194 -182
- package/core/field_colour.js +519 -505
- package/core/field_dropdown.js +617 -598
- package/core/field_image.js +229 -220
- package/core/field_label.js +102 -91
- package/core/field_label_serializable.js +42 -41
- package/core/field_multilineinput.js +372 -358
- package/core/field_number.js +272 -253
- package/core/field_textinput.js +499 -467
- package/core/field_variable.js +458 -420
- package/core/flyout_base.js +1005 -952
- package/core/flyout_button.js +277 -260
- package/core/flyout_horizontal.js +304 -302
- package/core/flyout_metrics_manager.js +64 -64
- package/core/flyout_vertical.js +306 -300
- package/core/generator.js +459 -446
- package/core/gesture.js +829 -813
- package/core/grid.js +166 -163
- package/core/icon.js +168 -159
- package/core/inject.js +7 -5
- package/core/input.js +257 -248
- package/core/insertion_marker_manager.js +655 -624
- package/core/internal_constants.js +0 -129
- package/core/keyboard_nav/ast_node.js +605 -596
- package/core/keyboard_nav/basic_cursor.js +166 -165
- package/core/keyboard_nav/cursor.js +99 -97
- package/core/keyboard_nav/marker.js +83 -79
- package/core/keyboard_nav/tab_navigate_cursor.js +18 -23
- package/core/marker_manager.js +153 -141
- package/core/menu.js +377 -372
- package/core/menuitem.js +223 -217
- package/core/metrics_manager.js +403 -390
- package/core/mutator.js +468 -437
- package/core/names.js +229 -188
- package/core/options.js +290 -284
- package/core/procedures.js +29 -17
- package/core/registry.js +19 -16
- package/core/rendered_connection.js +482 -463
- package/core/renderers/common/block_rendering.js +9 -3
- package/core/renderers/common/constants.js +1119 -1112
- package/core/renderers/common/debug.js +14 -0
- package/core/renderers/common/debugger.js +338 -316
- package/core/renderers/common/drawer.js +380 -370
- package/core/renderers/common/i_path_object.js +2 -2
- package/core/renderers/common/info.js +626 -618
- package/core/renderers/common/marker_svg.js +579 -541
- package/core/renderers/common/path_object.js +203 -200
- package/core/renderers/common/renderer.js +220 -218
- package/core/renderers/geras/constants.js +36 -36
- package/core/renderers/geras/drawer.js +155 -147
- package/core/renderers/geras/highlight_constants.js +244 -238
- package/core/renderers/geras/highlighter.js +231 -179
- package/core/renderers/geras/info.js +392 -369
- package/core/renderers/geras/measurables/inline_input.js +25 -19
- package/core/renderers/geras/measurables/statement_input.js +23 -17
- package/core/renderers/geras/path_object.js +106 -121
- package/core/renderers/geras/renderer.js +96 -98
- package/core/renderers/measurables/base.js +30 -18
- package/core/renderers/measurables/bottom_row.js +83 -80
- package/core/renderers/measurables/connection.js +22 -15
- package/core/renderers/measurables/external_value_input.js +35 -22
- package/core/renderers/measurables/field.js +35 -20
- package/core/renderers/measurables/hat.js +18 -13
- package/core/renderers/measurables/icon.js +24 -17
- package/core/renderers/measurables/in_row_spacer.js +15 -13
- package/core/renderers/measurables/inline_input.js +43 -33
- package/core/renderers/measurables/input_connection.js +41 -28
- package/core/renderers/measurables/input_row.js +50 -44
- package/core/renderers/measurables/jagged_edge.js +14 -12
- package/core/renderers/measurables/next_connection.js +16 -14
- package/core/renderers/measurables/output_connection.js +26 -20
- package/core/renderers/measurables/previous_connection.js +16 -15
- package/core/renderers/measurables/round_corner.js +20 -18
- package/core/renderers/measurables/row.js +184 -168
- package/core/renderers/measurables/spacer_row.js +38 -23
- package/core/renderers/measurables/square_corner.js +18 -16
- package/core/renderers/measurables/statement_input.js +23 -20
- package/core/renderers/measurables/top_row.js +88 -85
- package/core/renderers/minimalist/constants.js +8 -7
- package/core/renderers/minimalist/drawer.js +11 -10
- package/core/renderers/minimalist/info.js +18 -18
- package/core/renderers/minimalist/renderer.js +40 -39
- package/core/renderers/thrasos/info.js +258 -248
- package/core/renderers/thrasos/renderer.js +20 -20
- package/core/renderers/zelos/constants.js +898 -873
- package/core/renderers/zelos/drawer.js +186 -169
- package/core/renderers/zelos/info.js +502 -479
- package/core/renderers/zelos/marker_svg.js +129 -115
- package/core/renderers/zelos/measurables/bottom_row.js +31 -30
- package/core/renderers/zelos/measurables/inputs.js +22 -21
- package/core/renderers/zelos/measurables/row_elements.js +14 -13
- package/core/renderers/zelos/measurables/top_row.js +34 -33
- package/core/renderers/zelos/path_object.js +181 -180
- package/core/renderers/zelos/renderer.js +91 -92
- package/core/scrollbar.js +759 -713
- package/core/scrollbar_pair.js +250 -245
- package/core/serialization/blocks.js +19 -9
- package/core/serialization/workspaces.js +3 -2
- package/core/shortcut_registry.js +286 -277
- package/core/sprites.js +31 -0
- package/core/theme.js +135 -141
- package/core/theme_manager.js +147 -143
- package/core/toolbox/category.js +602 -576
- package/core/toolbox/collapsible_category.js +226 -227
- package/core/toolbox/separator.js +70 -61
- package/core/toolbox/toolbox.js +934 -927
- package/core/toolbox/toolbox_item.js +115 -99
- package/core/tooltip.js +108 -35
- package/core/touch.js +8 -3
- package/core/touch_gesture.js +254 -251
- package/core/trashcan.js +606 -595
- package/core/utils/coordinate.js +97 -95
- package/core/utils/dom.js +2 -2
- package/core/utils/global.js +2 -0
- package/core/utils/rect.js +41 -37
- package/core/utils/sentinel.js +25 -0
- package/core/utils/size.js +30 -27
- package/core/utils/svg.js +18 -16
- package/core/variable_map.js +325 -341
- package/core/variable_model.js +55 -54
- package/core/variables.js +9 -2
- package/core/variables_dynamic.js +3 -1
- package/core/warning.js +126 -120
- package/core/widgetdiv.js +4 -4
- package/core/workspace.js +685 -664
- package/core/workspace_audio.js +124 -118
- package/core/workspace_comment.js +308 -298
- package/core/workspace_comment_svg.js +1029 -951
- package/core/workspace_drag_surface_svg.js +147 -140
- package/core/workspace_dragger.js +70 -71
- package/core/workspace_svg.js +2322 -2297
- package/core/xml.js +30 -20
- package/core/zoom_controls.js +431 -439
- package/dart_compressed.js +40 -43
- package/dart_compressed.js.map +1 -1
- package/generators/dart/colour.js +56 -64
- package/generators/dart/lists.js +61 -50
- package/generators/dart/math.js +160 -148
- package/generators/dart/text.js +83 -61
- package/generators/javascript/colour.js +37 -34
- package/generators/javascript/lists.js +50 -43
- package/generators/javascript/math.js +123 -139
- package/generators/javascript/text.js +67 -81
- package/generators/lua/colour.js +25 -23
- package/generators/lua/lists.js +97 -69
- package/generators/lua/logic.js +1 -2
- package/generators/lua/math.js +182 -144
- package/generators/lua/text.js +116 -99
- package/generators/php/colour.js +38 -32
- package/generators/php/lists.js +109 -89
- package/generators/php/math.js +90 -81
- package/generators/php/text.js +63 -61
- package/generators/python/colour.js +18 -18
- package/generators/python/lists.js +38 -30
- package/generators/python/loops.js +12 -8
- package/generators/python/math.js +104 -106
- package/generators/python/text.js +34 -30
- package/javascript_compressed.js +37 -39
- package/javascript_compressed.js.map +1 -1
- package/lua_compressed.js +39 -42
- package/lua_compressed.js.map +1 -1
- package/msg/az.js +2 -2
- package/msg/be.js +4 -4
- package/msg/cs.js +15 -15
- package/msg/de.js +1 -1
- package/msg/diq.js +1 -1
- package/msg/eo.js +1 -1
- package/msg/es.js +1 -1
- package/msg/fa.js +1 -1
- package/msg/fr.js +4 -4
- package/msg/he.js +1 -1
- package/msg/hr.js +2 -2
- package/msg/hy.js +2 -2
- package/msg/id.js +12 -12
- package/msg/inh.js +14 -14
- package/msg/ja.js +7 -7
- package/msg/lv.js +29 -29
- package/msg/pa.js +3 -3
- package/msg/smn.js +436 -0
- package/msg/te.js +1 -1
- package/msg/yue.js +1 -1
- package/msg/zh-hans.js +3 -3
- package/msg/zh-hant.js +3 -3
- package/package.json +7 -6
- package/php_compressed.js +38 -42
- package/php_compressed.js.map +1 -1
- package/python_compressed.js +26 -25
- package/python_compressed.js.map +1 -1
- 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
|
-
|
|
68
|
+
class MarkerSvg {
|
|
74
69
|
/**
|
|
75
|
-
* The workspace the marker belongs to.
|
|
76
|
-
* @
|
|
77
|
-
*
|
|
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
|
-
|
|
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
|
-
*
|
|
83
|
-
* @
|
|
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
|
-
|
|
162
|
+
getSvgRoot() {
|
|
163
|
+
return this.svgGroup_;
|
|
164
|
+
}
|
|
87
165
|
|
|
88
166
|
/**
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
* @type {IASTNodeLocationSvg}
|
|
92
|
-
* @private
|
|
167
|
+
* Get the marker.
|
|
168
|
+
* @return {!Marker} The marker to draw for.
|
|
93
169
|
*/
|
|
94
|
-
|
|
170
|
+
getMarker() {
|
|
171
|
+
return this.marker_;
|
|
172
|
+
}
|
|
95
173
|
|
|
96
174
|
/**
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
* @
|
|
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
|
-
|
|
179
|
+
isCursor() {
|
|
180
|
+
return this.marker_.type === 'cursor';
|
|
181
|
+
}
|
|
102
182
|
|
|
103
183
|
/**
|
|
104
|
-
*
|
|
105
|
-
* @
|
|
184
|
+
* Create the DOM element for the marker.
|
|
185
|
+
* @return {!SVGElement} The marker controls SVG group.
|
|
186
|
+
* @package
|
|
106
187
|
*/
|
|
107
|
-
|
|
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
|
-
|
|
110
|
-
|
|
193
|
+
this.createDomInternal_();
|
|
194
|
+
return this.svgGroup_;
|
|
195
|
+
}
|
|
111
196
|
|
|
112
197
|
/**
|
|
113
|
-
*
|
|
114
|
-
* @
|
|
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
|
-
|
|
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
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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
|
-
|
|
137
|
-
|
|
138
|
-
|
|
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
|
-
|
|
238
|
+
this.fireMarkerEvent_(oldNode, curNode);
|
|
153
239
|
|
|
154
|
-
|
|
155
|
-
|
|
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
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
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
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
this.constants_.MARKER_COLOUR;
|
|
194
|
-
this.colour_ = this.marker_.colour || defaultColour;
|
|
195
|
-
this.applyColour_(curNode);
|
|
275
|
+
/**************************
|
|
276
|
+
* Display
|
|
277
|
+
**************************/
|
|
196
278
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
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
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
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
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
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
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
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
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
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
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
};
|
|
345
|
+
if (this.workspace_.RTL) {
|
|
346
|
+
x -= this.constants_.CURSOR_WS_WIDTH;
|
|
347
|
+
}
|
|
329
348
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
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
|
-
|
|
342
|
-
|
|
343
|
-
|
|
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
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
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
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
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
|
-
|
|
379
|
-
|
|
417
|
+
// Gets the height and width of entire stack.
|
|
418
|
+
const heightWidth = block.getHeightWidth();
|
|
380
419
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
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
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
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
|
-
|
|
391
|
-
|
|
430
|
+
let x = xPadding;
|
|
431
|
+
const y = yPadding;
|
|
392
432
|
|
|
393
|
-
|
|
394
|
-
|
|
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
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
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
|
-
|
|
447
|
-
|
|
450
|
+
/**************************
|
|
451
|
+
* Position
|
|
452
|
+
**************************/
|
|
448
453
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
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
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
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
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
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
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
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
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
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
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
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
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
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
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
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
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
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
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
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
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
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;
|