blockly 7.20211209.4 → 8.0.1
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 +5 -4
- package/blockly_compressed.js +4 -3
- 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 +45 -32
- package/blocks/text.js +22 -13
- package/blocks/variables.js +14 -3
- package/blocks/variables_dynamic.js +13 -3
- package/blocks_compressed.js +1 -1
- 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 +26 -10
- 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/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/msg/smn.js +436 -0
- package/package.json +7 -6
- package/blocks/all.js +0 -23
package/core/dropdowndiv.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* A div that floats on top of the workspace, for drop-down menus.
|
|
17
17
|
* @class
|
|
18
18
|
*/
|
|
19
|
-
goog.module('Blockly.
|
|
19
|
+
goog.module('Blockly.dropDownDiv');
|
|
20
20
|
|
|
21
21
|
const common = goog.require('Blockly.common');
|
|
22
22
|
const dom = goog.require('Blockly.utils.dom');
|
|
@@ -33,21 +33,14 @@ const {Size} = goog.requireType('Blockly.utils.Size');
|
|
|
33
33
|
const {WorkspaceSvg} = goog.requireType('Blockly.WorkspaceSvg');
|
|
34
34
|
|
|
35
35
|
|
|
36
|
-
/**
|
|
37
|
-
* Class for drop-down div.
|
|
38
|
-
* @constructor
|
|
39
|
-
* @package
|
|
40
|
-
* @alias Blockly.DropDownDiv
|
|
41
|
-
*/
|
|
42
|
-
const DropDownDiv = function() {};
|
|
43
|
-
|
|
44
36
|
/**
|
|
45
37
|
* Arrow size in px. Should match the value in CSS
|
|
46
38
|
* (need to position pre-render).
|
|
47
39
|
* @type {number}
|
|
48
40
|
* @const
|
|
49
41
|
*/
|
|
50
|
-
|
|
42
|
+
const ARROW_SIZE = 16;
|
|
43
|
+
exports.ARROW_SIZE = ARROW_SIZE;
|
|
51
44
|
|
|
52
45
|
/**
|
|
53
46
|
* Drop-down border size in px. Should match the value in CSS (need to position
|
|
@@ -55,7 +48,8 @@ DropDownDiv.ARROW_SIZE = 16;
|
|
|
55
48
|
* @type {number}
|
|
56
49
|
* @const
|
|
57
50
|
*/
|
|
58
|
-
|
|
51
|
+
const BORDER_SIZE = 1;
|
|
52
|
+
exports.BORDER_SIZE = BORDER_SIZE;
|
|
59
53
|
|
|
60
54
|
/**
|
|
61
55
|
* Amount the arrow must be kept away from the edges of the main drop-down div,
|
|
@@ -63,93 +57,86 @@ DropDownDiv.BORDER_SIZE = 1;
|
|
|
63
57
|
* @type {number}
|
|
64
58
|
* @const
|
|
65
59
|
*/
|
|
66
|
-
|
|
60
|
+
const ARROW_HORIZONTAL_PADDING = 12;
|
|
61
|
+
exports.ARROW_HORIZONTAL_PADDING = ARROW_HORIZONTAL_PADDING;
|
|
67
62
|
|
|
68
63
|
/**
|
|
69
64
|
* Amount drop-downs should be padded away from the source, in px.
|
|
70
65
|
* @type {number}
|
|
71
66
|
* @const
|
|
72
67
|
*/
|
|
73
|
-
|
|
68
|
+
const PADDING_Y = 16;
|
|
69
|
+
exports.PADDING_Y = PADDING_Y;
|
|
74
70
|
|
|
75
71
|
/**
|
|
76
72
|
* Length of animations in seconds.
|
|
77
73
|
* @type {number}
|
|
78
74
|
* @const
|
|
79
75
|
*/
|
|
80
|
-
|
|
76
|
+
const ANIMATION_TIME = 0.25;
|
|
77
|
+
exports.ANIMATION_TIME = ANIMATION_TIME;
|
|
81
78
|
|
|
82
79
|
/**
|
|
83
80
|
* Timer for animation out, to be cleared if we need to immediately hide
|
|
84
81
|
* without disrupting new shows.
|
|
85
82
|
* @type {?number}
|
|
86
|
-
* @private
|
|
87
83
|
*/
|
|
88
|
-
|
|
84
|
+
let animateOutTimer = null;
|
|
89
85
|
|
|
90
86
|
/**
|
|
91
87
|
* Callback for when the drop-down is hidden.
|
|
92
88
|
* @type {?Function}
|
|
93
|
-
* @private
|
|
94
89
|
*/
|
|
95
|
-
|
|
90
|
+
let onHide = null;
|
|
96
91
|
|
|
97
92
|
/**
|
|
98
93
|
* A class name representing the current owner's workspace renderer.
|
|
99
94
|
* @type {string}
|
|
100
|
-
* @private
|
|
101
95
|
*/
|
|
102
|
-
|
|
96
|
+
let renderedClassName = '';
|
|
103
97
|
|
|
104
98
|
/**
|
|
105
99
|
* A class name representing the current owner's workspace theme.
|
|
106
100
|
* @type {string}
|
|
107
|
-
* @private
|
|
108
101
|
*/
|
|
109
|
-
|
|
102
|
+
let themeClassName = '';
|
|
110
103
|
|
|
111
104
|
/**
|
|
112
105
|
* The content element.
|
|
113
|
-
* @type {!
|
|
114
|
-
* @private
|
|
106
|
+
* @type {!HTMLDivElement}
|
|
115
107
|
*/
|
|
116
|
-
|
|
108
|
+
let div;
|
|
117
109
|
|
|
118
110
|
/**
|
|
119
111
|
* The content element.
|
|
120
|
-
* @type {!
|
|
121
|
-
* @private
|
|
112
|
+
* @type {!HTMLDivElement}
|
|
122
113
|
*/
|
|
123
|
-
|
|
114
|
+
let content;
|
|
124
115
|
|
|
125
116
|
/**
|
|
126
117
|
* The arrow element.
|
|
127
|
-
* @type {!
|
|
128
|
-
* @private
|
|
118
|
+
* @type {!HTMLDivElement}
|
|
129
119
|
*/
|
|
130
|
-
|
|
120
|
+
let arrow;
|
|
131
121
|
|
|
132
122
|
/**
|
|
133
123
|
* Drop-downs will appear within the bounds of this element if possible.
|
|
134
|
-
* Set in
|
|
124
|
+
* Set in setBoundsElement.
|
|
135
125
|
* @type {?Element}
|
|
136
|
-
* @private
|
|
137
126
|
*/
|
|
138
|
-
|
|
127
|
+
let boundsElement = null;
|
|
139
128
|
|
|
140
129
|
/**
|
|
141
130
|
* The object currently using the drop-down.
|
|
142
131
|
* @type {?Object}
|
|
143
|
-
* @private
|
|
144
132
|
*/
|
|
145
|
-
|
|
133
|
+
let owner = null;
|
|
146
134
|
|
|
147
135
|
/**
|
|
148
136
|
* Whether the dropdown was positioned to a field or the source block.
|
|
149
137
|
* @type {?boolean}
|
|
150
|
-
* @private
|
|
151
138
|
*/
|
|
152
|
-
|
|
139
|
+
let positionToField = null;
|
|
153
140
|
|
|
154
141
|
/**
|
|
155
142
|
* Dropdown bounds info object used to encapsulate sizing information about a
|
|
@@ -163,7 +150,8 @@ DropDownDiv.positionToField_ = null;
|
|
|
163
150
|
* height:number
|
|
164
151
|
* }}
|
|
165
152
|
*/
|
|
166
|
-
|
|
153
|
+
let BoundsInfo;
|
|
154
|
+
exports.BoundsInfo = BoundsInfo;
|
|
167
155
|
|
|
168
156
|
/**
|
|
169
157
|
* Dropdown position metrics.
|
|
@@ -178,84 +166,85 @@ DropDownDiv.BoundsInfo;
|
|
|
178
166
|
* arrowVisible:boolean
|
|
179
167
|
* }}
|
|
180
168
|
*/
|
|
181
|
-
|
|
169
|
+
let PositionMetrics;
|
|
170
|
+
exports.PositionMetrics = PositionMetrics;
|
|
182
171
|
|
|
183
172
|
/**
|
|
184
173
|
* Create and insert the DOM element for this div.
|
|
185
174
|
* @package
|
|
186
175
|
*/
|
|
187
|
-
|
|
188
|
-
if (
|
|
176
|
+
const createDom = function() {
|
|
177
|
+
if (div) {
|
|
189
178
|
return; // Already created.
|
|
190
179
|
}
|
|
191
|
-
|
|
192
|
-
|
|
180
|
+
div = /** @type {!HTMLDivElement} */ (document.createElement('div'));
|
|
181
|
+
div.className = 'blocklyDropDownDiv';
|
|
193
182
|
const parentDiv = common.getParentContainer() || document.body;
|
|
194
|
-
parentDiv.appendChild(
|
|
195
|
-
|
|
196
|
-
DropDownDiv.DIV_ = containerDiv;
|
|
183
|
+
parentDiv.appendChild(div);
|
|
197
184
|
|
|
198
|
-
|
|
185
|
+
content = /** @type {!HTMLDivElement} */ (document.createElement('div'));
|
|
199
186
|
content.className = 'blocklyDropDownContent';
|
|
200
|
-
|
|
201
|
-
DropDownDiv.content_ = content;
|
|
187
|
+
div.appendChild(content);
|
|
202
188
|
|
|
203
|
-
|
|
189
|
+
arrow = /** @type {!HTMLDivElement} */ (document.createElement('div'));
|
|
204
190
|
arrow.className = 'blocklyDropDownArrow';
|
|
205
|
-
|
|
206
|
-
DropDownDiv.arrow_ = arrow;
|
|
191
|
+
div.appendChild(arrow);
|
|
207
192
|
|
|
208
|
-
|
|
193
|
+
div.style.opacity = 0;
|
|
209
194
|
|
|
210
195
|
// Transition animation for transform: translate() and opacity.
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
'opacity ' + DropDownDiv.ANIMATION_TIME + 's';
|
|
196
|
+
div.style.transition = 'transform ' + ANIMATION_TIME + 's, ' +
|
|
197
|
+
'opacity ' + ANIMATION_TIME + 's';
|
|
214
198
|
|
|
215
199
|
// Handle focusin/out events to add a visual indicator when
|
|
216
200
|
// a child is focused or blurred.
|
|
217
|
-
|
|
218
|
-
dom.addClass(
|
|
201
|
+
div.addEventListener('focusin', function() {
|
|
202
|
+
dom.addClass(div, 'blocklyFocused');
|
|
219
203
|
});
|
|
220
|
-
|
|
221
|
-
dom.removeClass(
|
|
204
|
+
div.addEventListener('focusout', function() {
|
|
205
|
+
dom.removeClass(div, 'blocklyFocused');
|
|
222
206
|
});
|
|
223
207
|
};
|
|
208
|
+
exports.createDom = createDom;
|
|
224
209
|
|
|
225
210
|
/**
|
|
226
211
|
* Set an element to maintain bounds within. Drop-downs will appear
|
|
227
212
|
* within the box of this element if possible.
|
|
228
|
-
* @param {?Element}
|
|
213
|
+
* @param {?Element} boundsElem Element to bind drop-down to.
|
|
229
214
|
*/
|
|
230
|
-
|
|
231
|
-
|
|
215
|
+
const setBoundsElement = function(boundsElem) {
|
|
216
|
+
boundsElement = boundsElem;
|
|
232
217
|
};
|
|
218
|
+
exports.setBoundsElement = setBoundsElement;
|
|
233
219
|
|
|
234
220
|
/**
|
|
235
221
|
* Provide the div for inserting content into the drop-down.
|
|
236
222
|
* @return {!Element} Div to populate with content.
|
|
237
223
|
*/
|
|
238
|
-
|
|
239
|
-
return
|
|
224
|
+
const getContentDiv = function() {
|
|
225
|
+
return content;
|
|
240
226
|
};
|
|
227
|
+
exports.getContentDiv = getContentDiv;
|
|
241
228
|
|
|
242
229
|
/**
|
|
243
230
|
* Clear the content of the drop-down.
|
|
244
231
|
*/
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
232
|
+
const clearContent = function() {
|
|
233
|
+
content.textContent = '';
|
|
234
|
+
content.style.width = '';
|
|
248
235
|
};
|
|
236
|
+
exports.clearContent = clearContent;
|
|
249
237
|
|
|
250
238
|
/**
|
|
251
239
|
* Set the colour for the drop-down.
|
|
252
240
|
* @param {string} backgroundColour Any CSS colour for the background.
|
|
253
241
|
* @param {string} borderColour Any CSS colour for the border.
|
|
254
242
|
*/
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
243
|
+
const setColour = function(backgroundColour, borderColour) {
|
|
244
|
+
div.style.backgroundColor = backgroundColour;
|
|
245
|
+
div.style.borderColor = borderColour;
|
|
258
246
|
};
|
|
247
|
+
exports.setColour = setColour;
|
|
259
248
|
|
|
260
249
|
/**
|
|
261
250
|
* Shortcut to show and place the drop-down with positioning determined
|
|
@@ -270,11 +259,12 @@ DropDownDiv.setColour = function(backgroundColour, borderColour) {
|
|
|
270
259
|
* positioning.
|
|
271
260
|
* @return {boolean} True if the menu rendered below block; false if above.
|
|
272
261
|
*/
|
|
273
|
-
|
|
262
|
+
const showPositionedByBlock = function(
|
|
274
263
|
field, block, opt_onHide, opt_secondaryYOffset) {
|
|
275
264
|
return showPositionedByRect(
|
|
276
265
|
getScaledBboxOfBlock(block), field, opt_onHide, opt_secondaryYOffset);
|
|
277
266
|
};
|
|
267
|
+
exports.showPositionedByBlock = showPositionedByBlock;
|
|
278
268
|
|
|
279
269
|
/**
|
|
280
270
|
* Shortcut to show and place the drop-down with positioning determined
|
|
@@ -288,14 +278,13 @@ DropDownDiv.showPositionedByBlock = function(
|
|
|
288
278
|
* positioning.
|
|
289
279
|
* @return {boolean} True if the menu rendered below block; false if above.
|
|
290
280
|
*/
|
|
291
|
-
|
|
281
|
+
const showPositionedByField = function(
|
|
292
282
|
field, opt_onHide, opt_secondaryYOffset) {
|
|
293
|
-
|
|
283
|
+
positionToField = true;
|
|
294
284
|
return showPositionedByRect(
|
|
295
285
|
getScaledBboxOfField(field), field, opt_onHide, opt_secondaryYOffset);
|
|
296
286
|
};
|
|
297
|
-
|
|
298
|
-
const internal = {};
|
|
287
|
+
exports.showPositionedByField = showPositionedByField;
|
|
299
288
|
|
|
300
289
|
/**
|
|
301
290
|
* Get the scaled bounding box of a block.
|
|
@@ -353,9 +342,9 @@ const showPositionedByRect = function(
|
|
|
353
342
|
workspace =
|
|
354
343
|
/** @type {!WorkspaceSvg} */ (workspace.options.parentWorkspace);
|
|
355
344
|
}
|
|
356
|
-
|
|
345
|
+
setBoundsElement(
|
|
357
346
|
/** @type {?Element} */ (workspace.getParentSvg().parentNode));
|
|
358
|
-
return
|
|
347
|
+
return show(
|
|
359
348
|
field, sourceBlock.RTL, primaryX, primaryY, secondaryX, secondaryY,
|
|
360
349
|
opt_onHide);
|
|
361
350
|
};
|
|
@@ -368,7 +357,7 @@ const showPositionedByRect = function(
|
|
|
368
357
|
* will point there, and the container will be positioned below it.
|
|
369
358
|
* If we can't maintain the container bounds at the primary point, fall-back to
|
|
370
359
|
* the secondary point and position above.
|
|
371
|
-
* @param {?Object}
|
|
360
|
+
* @param {?Object} newOwner The object showing the drop-down
|
|
372
361
|
* @param {boolean} rtl Right-to-left (true) or left-to-right (false).
|
|
373
362
|
* @param {number} primaryX Desired origin point x, in absolute px.
|
|
374
363
|
* @param {number} primaryY Desired origin point y, in absolute px.
|
|
@@ -381,20 +370,19 @@ const showPositionedByRect = function(
|
|
|
381
370
|
* @return {boolean} True if the menu rendered at the primary origin point.
|
|
382
371
|
* @package
|
|
383
372
|
*/
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
373
|
+
const show = function(
|
|
374
|
+
newOwner, rtl, primaryX, primaryY, secondaryX, secondaryY, opt_onHide) {
|
|
375
|
+
owner = newOwner;
|
|
376
|
+
onHide = opt_onHide || null;
|
|
388
377
|
// Set direction.
|
|
389
|
-
const div = DropDownDiv.DIV_;
|
|
390
378
|
div.style.direction = rtl ? 'rtl' : 'ltr';
|
|
391
379
|
|
|
392
380
|
const mainWorkspace =
|
|
393
381
|
/** @type {!WorkspaceSvg} */ (common.getMainWorkspace());
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
dom.addClass(div,
|
|
397
|
-
dom.addClass(div,
|
|
382
|
+
renderedClassName = mainWorkspace.getRenderer().getClassName();
|
|
383
|
+
themeClassName = mainWorkspace.getTheme().getClassName();
|
|
384
|
+
dom.addClass(div, renderedClassName);
|
|
385
|
+
dom.addClass(div, themeClassName);
|
|
398
386
|
|
|
399
387
|
// When we change `translate` multiple times in close succession,
|
|
400
388
|
// Chrome may choose to wait and apply them all at once.
|
|
@@ -407,17 +395,20 @@ DropDownDiv.show = function(
|
|
|
407
395
|
|
|
408
396
|
return positionInternal(primaryX, primaryY, secondaryX, secondaryY);
|
|
409
397
|
};
|
|
398
|
+
exports.show = show;
|
|
399
|
+
|
|
400
|
+
const internal = {};
|
|
410
401
|
|
|
411
402
|
/**
|
|
412
403
|
* Get sizing info about the bounding element.
|
|
413
|
-
* @return {!
|
|
404
|
+
* @return {!BoundsInfo} An object containing size
|
|
414
405
|
* information about the bounding element (bounding box and width/height).
|
|
415
406
|
*/
|
|
416
407
|
internal.getBoundsInfo = function() {
|
|
417
408
|
const boundPosition = style.getPageOffset(
|
|
418
|
-
/** @type {!Element} */ (
|
|
409
|
+
/** @type {!Element} */ (boundsElement));
|
|
419
410
|
const boundSize = style.getSize(
|
|
420
|
-
/** @type {!Element} */ (
|
|
411
|
+
/** @type {!Element} */ (boundsElement));
|
|
421
412
|
|
|
422
413
|
return {
|
|
423
414
|
left: boundPosition.x,
|
|
@@ -431,21 +422,21 @@ internal.getBoundsInfo = function() {
|
|
|
431
422
|
|
|
432
423
|
/**
|
|
433
424
|
* Helper to position the drop-down and the arrow, maintaining bounds.
|
|
434
|
-
* See explanation of origin points in
|
|
425
|
+
* See explanation of origin points in show.
|
|
435
426
|
* @param {number} primaryX Desired origin point x, in absolute px.
|
|
436
427
|
* @param {number} primaryY Desired origin point y, in absolute px.
|
|
437
428
|
* @param {number} secondaryX Secondary/alternative origin point x,
|
|
438
429
|
* in absolute px.
|
|
439
430
|
* @param {number} secondaryY Secondary/alternative origin point y,
|
|
440
431
|
* in absolute px.
|
|
441
|
-
* @return {!
|
|
432
|
+
* @return {!PositionMetrics} Various final metrics,
|
|
442
433
|
* including rendered positions for drop-down and arrow.
|
|
443
434
|
*/
|
|
444
435
|
internal.getPositionMetrics = function(
|
|
445
436
|
primaryX, primaryY, secondaryX, secondaryY) {
|
|
446
437
|
const boundsInfo = internal.getBoundsInfo();
|
|
447
438
|
const divSize = style.getSize(
|
|
448
|
-
/** @type {!Element} */ (
|
|
439
|
+
/** @type {!Element} */ (div));
|
|
449
440
|
|
|
450
441
|
// Can we fit in-bounds below the target?
|
|
451
442
|
if (primaryY + divSize.height < boundsInfo.bottom) {
|
|
@@ -472,20 +463,20 @@ internal.getPositionMetrics = function(
|
|
|
472
463
|
* Get the metrics for positioning the div below the source.
|
|
473
464
|
* @param {number} primaryX Desired origin point x, in absolute px.
|
|
474
465
|
* @param {number} primaryY Desired origin point y, in absolute px.
|
|
475
|
-
* @param {!
|
|
466
|
+
* @param {!BoundsInfo} boundsInfo An object containing size
|
|
476
467
|
* information about the bounding element (bounding box and width/height).
|
|
477
468
|
* @param {!Size} divSize An object containing information about
|
|
478
469
|
* the size of the DropDownDiv (width & height).
|
|
479
|
-
* @return {!
|
|
470
|
+
* @return {!PositionMetrics} Various final metrics,
|
|
480
471
|
* including rendered positions for drop-down and arrow.
|
|
481
472
|
*/
|
|
482
473
|
const getPositionBelowMetrics = function(
|
|
483
474
|
primaryX, primaryY, boundsInfo, divSize) {
|
|
484
|
-
const xCoords =
|
|
485
|
-
primaryX, boundsInfo.left, boundsInfo.right, divSize.width);
|
|
475
|
+
const xCoords =
|
|
476
|
+
getPositionX(primaryX, boundsInfo.left, boundsInfo.right, divSize.width);
|
|
486
477
|
|
|
487
|
-
const arrowY = -(
|
|
488
|
-
const finalY = primaryY +
|
|
478
|
+
const arrowY = -(ARROW_SIZE / 2 + BORDER_SIZE);
|
|
479
|
+
const finalY = primaryY + PADDING_Y;
|
|
489
480
|
|
|
490
481
|
return {
|
|
491
482
|
initialX: xCoords.divX,
|
|
@@ -505,21 +496,20 @@ const getPositionBelowMetrics = function(
|
|
|
505
496
|
* in absolute px.
|
|
506
497
|
* @param {number} secondaryY Secondary/alternative origin point y,
|
|
507
498
|
* in absolute px.
|
|
508
|
-
* @param {!
|
|
499
|
+
* @param {!BoundsInfo} boundsInfo An object containing size
|
|
509
500
|
* information about the bounding element (bounding box and width/height).
|
|
510
501
|
* @param {!Size} divSize An object containing information about
|
|
511
502
|
* the size of the DropDownDiv (width & height).
|
|
512
|
-
* @return {!
|
|
503
|
+
* @return {!PositionMetrics} Various final metrics,
|
|
513
504
|
* including rendered positions for drop-down and arrow.
|
|
514
505
|
*/
|
|
515
506
|
const getPositionAboveMetrics = function(
|
|
516
507
|
secondaryX, secondaryY, boundsInfo, divSize) {
|
|
517
|
-
const xCoords =
|
|
508
|
+
const xCoords = getPositionX(
|
|
518
509
|
secondaryX, boundsInfo.left, boundsInfo.right, divSize.width);
|
|
519
510
|
|
|
520
|
-
const arrowY = divSize.height - (
|
|
521
|
-
|
|
522
|
-
const finalY = secondaryY - divSize.height - DropDownDiv.PADDING_Y;
|
|
511
|
+
const arrowY = divSize.height - (BORDER_SIZE * 2) - (ARROW_SIZE / 2);
|
|
512
|
+
const finalY = secondaryY - divSize.height - PADDING_Y;
|
|
523
513
|
const initialY = secondaryY - divSize.height; // No padding on Y.
|
|
524
514
|
|
|
525
515
|
return {
|
|
@@ -537,16 +527,16 @@ const getPositionAboveMetrics = function(
|
|
|
537
527
|
/**
|
|
538
528
|
* Get the metrics for positioning the div at the top of the page.
|
|
539
529
|
* @param {number} sourceX Desired origin point x, in absolute px.
|
|
540
|
-
* @param {!
|
|
530
|
+
* @param {!BoundsInfo} boundsInfo An object containing size
|
|
541
531
|
* information about the bounding element (bounding box and width/height).
|
|
542
532
|
* @param {!Size} divSize An object containing information about
|
|
543
533
|
* the size of the DropDownDiv (width & height).
|
|
544
|
-
* @return {!
|
|
534
|
+
* @return {!PositionMetrics} Various final metrics,
|
|
545
535
|
* including rendered positions for drop-down and arrow.
|
|
546
536
|
*/
|
|
547
537
|
const getPositionTopOfPageMetrics = function(sourceX, boundsInfo, divSize) {
|
|
548
|
-
const xCoords =
|
|
549
|
-
sourceX, boundsInfo.left, boundsInfo.right, divSize.width);
|
|
538
|
+
const xCoords =
|
|
539
|
+
getPositionX(sourceX, boundsInfo.left, boundsInfo.right, divSize.width);
|
|
550
540
|
|
|
551
541
|
// No need to provide arrow-specific information because it won't be visible.
|
|
552
542
|
return {
|
|
@@ -574,8 +564,7 @@ const getPositionTopOfPageMetrics = function(sourceX, boundsInfo, divSize) {
|
|
|
574
564
|
* the x positions of the left side of the DropDownDiv and the arrow.
|
|
575
565
|
* @package
|
|
576
566
|
*/
|
|
577
|
-
|
|
578
|
-
sourceX, boundsLeft, boundsRight, divWidth) {
|
|
567
|
+
const getPositionX = function(sourceX, boundsLeft, boundsRight, divWidth) {
|
|
579
568
|
let divX = sourceX;
|
|
580
569
|
// Offset the topLeft coord so that the dropdowndiv is centered.
|
|
581
570
|
divX -= divWidth / 2;
|
|
@@ -584,77 +573,79 @@ DropDownDiv.getPositionX = function(
|
|
|
584
573
|
|
|
585
574
|
let arrowX = sourceX;
|
|
586
575
|
// Offset the arrow coord so that the arrow is centered.
|
|
587
|
-
arrowX -=
|
|
576
|
+
arrowX -= ARROW_SIZE / 2;
|
|
588
577
|
// Convert the arrow position to be relative to the top left of the div.
|
|
589
578
|
let relativeArrowX = arrowX - divX;
|
|
590
|
-
const horizPadding =
|
|
579
|
+
const horizPadding = ARROW_HORIZONTAL_PADDING;
|
|
591
580
|
// Clamp the arrow position so that it stays attached to the dropdowndiv.
|
|
592
581
|
relativeArrowX = math.clamp(
|
|
593
|
-
horizPadding, relativeArrowX,
|
|
594
|
-
divWidth - horizPadding - DropDownDiv.ARROW_SIZE);
|
|
582
|
+
horizPadding, relativeArrowX, divWidth - horizPadding - ARROW_SIZE);
|
|
595
583
|
|
|
596
584
|
return {arrowX: relativeArrowX, divX: divX};
|
|
597
585
|
};
|
|
586
|
+
exports.getPositionX = getPositionX;
|
|
598
587
|
|
|
599
588
|
/**
|
|
600
589
|
* Is the container visible?
|
|
601
590
|
* @return {boolean} True if visible.
|
|
602
591
|
*/
|
|
603
|
-
|
|
604
|
-
return !!
|
|
592
|
+
const isVisible = function() {
|
|
593
|
+
return !!owner;
|
|
605
594
|
};
|
|
595
|
+
exports.isVisible = isVisible;
|
|
606
596
|
|
|
607
597
|
/**
|
|
608
598
|
* Hide the menu only if it is owned by the provided object.
|
|
609
|
-
* @param {?Object}
|
|
599
|
+
* @param {?Object} divOwner Object which must be owning the drop-down to hide.
|
|
610
600
|
* @param {boolean=} opt_withoutAnimation True if we should hide the dropdown
|
|
611
601
|
* without animating.
|
|
612
602
|
* @return {boolean} True if hidden.
|
|
613
603
|
*/
|
|
614
|
-
|
|
615
|
-
if (
|
|
604
|
+
const hideIfOwner = function(divOwner, opt_withoutAnimation) {
|
|
605
|
+
if (owner === divOwner) {
|
|
616
606
|
if (opt_withoutAnimation) {
|
|
617
|
-
|
|
607
|
+
hideWithoutAnimation();
|
|
618
608
|
} else {
|
|
619
|
-
|
|
609
|
+
hide();
|
|
620
610
|
}
|
|
621
611
|
return true;
|
|
622
612
|
}
|
|
623
613
|
return false;
|
|
624
614
|
};
|
|
615
|
+
exports.hideIfOwner = hideIfOwner;
|
|
625
616
|
|
|
626
617
|
/**
|
|
627
618
|
* Hide the menu, triggering animation.
|
|
628
619
|
*/
|
|
629
|
-
|
|
620
|
+
const hide = function() {
|
|
630
621
|
// Start the animation by setting the translation and fading out.
|
|
631
622
|
// Reset to (initialX, initialY) - i.e., no translation.
|
|
632
|
-
|
|
633
|
-
|
|
623
|
+
div.style.transform = 'translate(0, 0)';
|
|
624
|
+
div.style.opacity = 0;
|
|
634
625
|
// Finish animation - reset all values to default.
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
},
|
|
638
|
-
if (
|
|
639
|
-
|
|
640
|
-
|
|
626
|
+
animateOutTimer = setTimeout(function() {
|
|
627
|
+
hideWithoutAnimation();
|
|
628
|
+
}, ANIMATION_TIME * 1000);
|
|
629
|
+
if (onHide) {
|
|
630
|
+
onHide();
|
|
631
|
+
onHide = null;
|
|
641
632
|
}
|
|
642
633
|
};
|
|
634
|
+
exports.hide = hide;
|
|
643
635
|
|
|
644
636
|
/**
|
|
645
637
|
* Hide the menu, without animation.
|
|
646
638
|
*/
|
|
647
|
-
|
|
648
|
-
if (!
|
|
639
|
+
const hideWithoutAnimation = function() {
|
|
640
|
+
if (!isVisible()) {
|
|
649
641
|
return;
|
|
650
642
|
}
|
|
651
|
-
if (
|
|
652
|
-
clearTimeout(
|
|
643
|
+
if (animateOutTimer) {
|
|
644
|
+
clearTimeout(animateOutTimer);
|
|
653
645
|
}
|
|
654
646
|
|
|
655
647
|
// Reset style properties in case this gets called directly
|
|
656
648
|
// instead of hide() - see discussion on #2551.
|
|
657
|
-
const div = DropDownDiv.DIV_;
|
|
658
649
|
div.style.transform = '';
|
|
659
650
|
div.style.left = '';
|
|
660
651
|
div.style.top = '';
|
|
@@ -663,23 +654,24 @@ DropDownDiv.hideWithoutAnimation = function() {
|
|
|
663
654
|
div.style.backgroundColor = '';
|
|
664
655
|
div.style.borderColor = '';
|
|
665
656
|
|
|
666
|
-
if (
|
|
667
|
-
|
|
668
|
-
|
|
657
|
+
if (onHide) {
|
|
658
|
+
onHide();
|
|
659
|
+
onHide = null;
|
|
669
660
|
}
|
|
670
|
-
|
|
671
|
-
|
|
661
|
+
clearContent();
|
|
662
|
+
owner = null;
|
|
672
663
|
|
|
673
|
-
if (
|
|
674
|
-
dom.removeClass(div,
|
|
675
|
-
|
|
664
|
+
if (renderedClassName) {
|
|
665
|
+
dom.removeClass(div, renderedClassName);
|
|
666
|
+
renderedClassName = '';
|
|
676
667
|
}
|
|
677
|
-
if (
|
|
678
|
-
dom.removeClass(div,
|
|
679
|
-
|
|
668
|
+
if (themeClassName) {
|
|
669
|
+
dom.removeClass(div, themeClassName);
|
|
670
|
+
themeClassName = '';
|
|
680
671
|
}
|
|
681
672
|
(/** @type {!WorkspaceSvg} */ (common.getMainWorkspace())).markFocused();
|
|
682
673
|
};
|
|
674
|
+
exports.hideWithoutAnimation = hideWithoutAnimation;
|
|
683
675
|
|
|
684
676
|
/**
|
|
685
677
|
* Set the dropdown div's position.
|
|
@@ -697,15 +689,15 @@ const positionInternal = function(primaryX, primaryY, secondaryX, secondaryY) {
|
|
|
697
689
|
|
|
698
690
|
// Update arrow CSS.
|
|
699
691
|
if (metrics.arrowVisible) {
|
|
700
|
-
|
|
701
|
-
|
|
692
|
+
arrow.style.display = '';
|
|
693
|
+
arrow.style.transform = 'translate(' + metrics.arrowX + 'px,' +
|
|
702
694
|
metrics.arrowY + 'px) rotate(45deg)';
|
|
703
|
-
|
|
695
|
+
arrow.setAttribute(
|
|
704
696
|
'class',
|
|
705
697
|
metrics.arrowAtTop ? 'blocklyDropDownArrow blocklyArrowTop' :
|
|
706
698
|
'blocklyDropDownArrow blocklyArrowBottom');
|
|
707
699
|
} else {
|
|
708
|
-
|
|
700
|
+
arrow.style.display = 'none';
|
|
709
701
|
}
|
|
710
702
|
|
|
711
703
|
const initialX = Math.floor(metrics.initialX);
|
|
@@ -713,7 +705,6 @@ const positionInternal = function(primaryX, primaryY, secondaryX, secondaryY) {
|
|
|
713
705
|
const finalX = Math.floor(metrics.finalX);
|
|
714
706
|
const finalY = Math.floor(metrics.finalY);
|
|
715
707
|
|
|
716
|
-
const div = DropDownDiv.DIV_;
|
|
717
708
|
// First apply initial translation.
|
|
718
709
|
div.style.left = initialX + 'px';
|
|
719
710
|
div.style.top = initialY + 'px';
|
|
@@ -736,17 +727,17 @@ const positionInternal = function(primaryX, primaryY, secondaryX, secondaryY) {
|
|
|
736
727
|
* calculate the new position, it will just hide it instead.
|
|
737
728
|
* @package
|
|
738
729
|
*/
|
|
739
|
-
|
|
730
|
+
const repositionForWindowResize = function() {
|
|
740
731
|
// This condition mainly catches the dropdown div when it is being used as a
|
|
741
732
|
// dropdown. It is important not to close it in this case because on Android,
|
|
742
733
|
// when a field is focused, the soft keyboard opens triggering a window resize
|
|
743
734
|
// event and we want the dropdown div to stick around so users can type into
|
|
744
735
|
// it.
|
|
745
|
-
if (
|
|
746
|
-
const field = /** @type {!Field} */ (
|
|
736
|
+
if (owner) {
|
|
737
|
+
const field = /** @type {!Field} */ (owner);
|
|
747
738
|
const block = /** @type {!BlockSvg} */ (field.getSourceBlock());
|
|
748
|
-
const bBox =
|
|
749
|
-
|
|
739
|
+
const bBox = positionToField ? getScaledBboxOfField(field) :
|
|
740
|
+
getScaledBboxOfBlock(block);
|
|
750
741
|
// If we can fit it, render below the block.
|
|
751
742
|
const primaryX = bBox.left + (bBox.right - bBox.left) / 2;
|
|
752
743
|
const primaryY = bBox.bottom;
|
|
@@ -755,10 +746,9 @@ DropDownDiv.repositionForWindowResize = function() {
|
|
|
755
746
|
const secondaryY = bBox.top;
|
|
756
747
|
positionInternal(primaryX, primaryY, secondaryX, secondaryY);
|
|
757
748
|
} else {
|
|
758
|
-
|
|
749
|
+
hide();
|
|
759
750
|
}
|
|
760
751
|
};
|
|
752
|
+
exports.repositionForWindowResize = repositionForWindowResize;
|
|
761
753
|
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
exports.DropDownDiv = DropDownDiv;
|
|
754
|
+
exports.TEST_ONLY = internal;
|