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/toolbox/category.js
CHANGED
|
@@ -34,688 +34,714 @@ const {ToolboxItem} = goog.require('Blockly.ToolboxItem');
|
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
36
|
* Class for a category in a toolbox.
|
|
37
|
-
* @param {!toolbox.CategoryInfo} categoryDef The information needed
|
|
38
|
-
* to create a category in the toolbox.
|
|
39
|
-
* @param {!IToolbox} toolbox The parent toolbox for the category.
|
|
40
|
-
* @param {ICollapsibleToolboxItem=} opt_parent The parent category or null if
|
|
41
|
-
* the category does not have a parent.
|
|
42
|
-
* @constructor
|
|
43
|
-
* @extends {ToolboxItem}
|
|
44
37
|
* @implements {ISelectableToolboxItem}
|
|
45
38
|
* @alias Blockly.ToolboxCategory
|
|
46
39
|
*/
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
40
|
+
class ToolboxCategory extends ToolboxItem {
|
|
41
|
+
/**
|
|
42
|
+
* @param {!toolbox.CategoryInfo} categoryDef The information needed
|
|
43
|
+
* to create a category in the toolbox.
|
|
44
|
+
* @param {!IToolbox} toolbox The parent toolbox for the category.
|
|
45
|
+
* @param {ICollapsibleToolboxItem=} opt_parent The parent category or null if
|
|
46
|
+
* the category does not have a parent.
|
|
47
|
+
*/
|
|
48
|
+
constructor(categoryDef, toolbox, opt_parent) {
|
|
49
|
+
super(categoryDef, toolbox, opt_parent);
|
|
50
|
+
|
|
51
|
+
/** @type {!toolbox.CategoryInfo} */
|
|
52
|
+
this.toolboxItemDef_;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The name that will be displayed on the category.
|
|
56
|
+
* @type {string}
|
|
57
|
+
* @protected
|
|
58
|
+
*/
|
|
59
|
+
this.name_ = '';
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* The colour of the category.
|
|
63
|
+
* @type {string}
|
|
64
|
+
* @protected
|
|
65
|
+
*/
|
|
66
|
+
this.colour_ = '';
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* The html container for the category.
|
|
70
|
+
* @type {?HTMLDivElement}
|
|
71
|
+
* @protected
|
|
72
|
+
*/
|
|
73
|
+
this.htmlDiv_ = null;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* The html element for the category row.
|
|
77
|
+
* @type {?HTMLDivElement}
|
|
78
|
+
* @protected
|
|
79
|
+
*/
|
|
80
|
+
this.rowDiv_ = null;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* The html element that holds children elements of the category row.
|
|
84
|
+
* @type {?HTMLDivElement}
|
|
85
|
+
* @protected
|
|
86
|
+
*/
|
|
87
|
+
this.rowContents_ = null;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* The html element for the toolbox icon.
|
|
91
|
+
* @type {?Element}
|
|
92
|
+
* @protected
|
|
93
|
+
*/
|
|
94
|
+
this.iconDom_ = null;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* The html element for the toolbox label.
|
|
98
|
+
* @type {?Element}
|
|
99
|
+
* @protected
|
|
100
|
+
*/
|
|
101
|
+
this.labelDom_ = null;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* All the css class names that are used to create a category.
|
|
105
|
+
* @type {!ToolboxCategory.CssConfig}
|
|
106
|
+
* @protected
|
|
107
|
+
*/
|
|
108
|
+
this.cssConfig_ = this.makeDefaultCssConfig_();
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* True if the category is meant to be hidden, false otherwise.
|
|
112
|
+
* @type {boolean}
|
|
113
|
+
* @protected
|
|
114
|
+
*/
|
|
115
|
+
this.isHidden_ = false;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* True if this category is disabled, false otherwise.
|
|
119
|
+
* @type {boolean}
|
|
120
|
+
* @protected
|
|
121
|
+
*/
|
|
122
|
+
this.isDisabled_ = false;
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* The flyout items for this category.
|
|
126
|
+
* @type {string|!toolbox.FlyoutItemInfoArray}
|
|
127
|
+
* @protected
|
|
128
|
+
*/
|
|
129
|
+
this.flyoutItems_ = [];
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Initializes the toolbox item.
|
|
134
|
+
* This includes creating the DOM and updating the state of any items based
|
|
135
|
+
* on the info object.
|
|
136
|
+
* Init should be called immediately after the construction of the toolbox
|
|
137
|
+
* item, to ensure that the category contents are properly parsed.
|
|
138
|
+
* @override
|
|
139
|
+
*/
|
|
140
|
+
init() {
|
|
141
|
+
this.parseCategoryDef_(this.toolboxItemDef_);
|
|
142
|
+
this.parseContents_(this.toolboxItemDef_);
|
|
143
|
+
this.createDom_();
|
|
144
|
+
if (this.toolboxItemDef_['hidden'] === 'true') {
|
|
145
|
+
this.hide();
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
50
149
|
|
|
51
150
|
/**
|
|
52
|
-
*
|
|
53
|
-
* @
|
|
151
|
+
* Creates an object holding the default classes for a category.
|
|
152
|
+
* @return {!ToolboxCategory.CssConfig} The configuration object holding
|
|
153
|
+
* all the CSS classes for a category.
|
|
54
154
|
* @protected
|
|
55
155
|
*/
|
|
56
|
-
|
|
156
|
+
makeDefaultCssConfig_() {
|
|
157
|
+
return {
|
|
158
|
+
'container': 'blocklyToolboxCategory',
|
|
159
|
+
'row': 'blocklyTreeRow',
|
|
160
|
+
'rowcontentcontainer': 'blocklyTreeRowContentContainer',
|
|
161
|
+
'icon': 'blocklyTreeIcon',
|
|
162
|
+
'label': 'blocklyTreeLabel',
|
|
163
|
+
'contents': 'blocklyToolboxContents',
|
|
164
|
+
'selected': 'blocklyTreeSelected',
|
|
165
|
+
'openicon': 'blocklyTreeIconOpen',
|
|
166
|
+
'closedicon': 'blocklyTreeIconClosed',
|
|
167
|
+
};
|
|
168
|
+
}
|
|
57
169
|
|
|
58
170
|
/**
|
|
59
|
-
*
|
|
60
|
-
*
|
|
171
|
+
* Parses the contents array depending on if the category is a dynamic
|
|
172
|
+
* category, or if its contents are meant to be shown in the flyout.
|
|
173
|
+
* @param {!toolbox.CategoryInfo} categoryDef The information needed
|
|
174
|
+
* to create a category.
|
|
61
175
|
* @protected
|
|
62
176
|
*/
|
|
63
|
-
|
|
177
|
+
parseContents_(categoryDef) {
|
|
178
|
+
const contents = categoryDef['contents'];
|
|
179
|
+
|
|
180
|
+
if (categoryDef['custom']) {
|
|
181
|
+
this.flyoutItems_ = categoryDef['custom'];
|
|
182
|
+
} else if (contents) {
|
|
183
|
+
for (let i = 0; i < contents.length; i++) {
|
|
184
|
+
const itemDef = contents[i];
|
|
185
|
+
const flyoutItem =
|
|
186
|
+
/** @type {toolbox.FlyoutItemInfo} */ (itemDef);
|
|
187
|
+
this.flyoutItems_.push(flyoutItem);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
64
191
|
|
|
65
192
|
/**
|
|
66
|
-
*
|
|
67
|
-
* @
|
|
193
|
+
* Parses the non-contents parts of the category def.
|
|
194
|
+
* @param {!toolbox.CategoryInfo} categoryDef The information needed to create
|
|
195
|
+
* a category.
|
|
68
196
|
* @protected
|
|
69
197
|
*/
|
|
70
|
-
|
|
198
|
+
parseCategoryDef_(categoryDef) {
|
|
199
|
+
this.name_ = parsing.replaceMessageReferences(categoryDef['name']);
|
|
200
|
+
this.colour_ = this.getColour_(categoryDef);
|
|
201
|
+
object.mixin(
|
|
202
|
+
this.cssConfig_, categoryDef['cssconfig'] || categoryDef['cssConfig']);
|
|
203
|
+
}
|
|
71
204
|
|
|
72
205
|
/**
|
|
73
|
-
*
|
|
74
|
-
* @
|
|
206
|
+
* Creates the DOM for the category.
|
|
207
|
+
* @return {!HTMLDivElement} The parent element for the category.
|
|
75
208
|
* @protected
|
|
76
209
|
*/
|
|
77
|
-
|
|
210
|
+
createDom_() {
|
|
211
|
+
this.htmlDiv_ = this.createContainer_();
|
|
212
|
+
aria.setRole(this.htmlDiv_, aria.Role.TREEITEM);
|
|
213
|
+
aria.setState(
|
|
214
|
+
/** @type {!HTMLDivElement} */ (this.htmlDiv_), aria.State.SELECTED,
|
|
215
|
+
false);
|
|
216
|
+
aria.setState(
|
|
217
|
+
/** @type {!HTMLDivElement} */ (this.htmlDiv_), aria.State.LEVEL,
|
|
218
|
+
this.level_);
|
|
219
|
+
|
|
220
|
+
this.rowDiv_ = this.createRowContainer_();
|
|
221
|
+
this.rowDiv_.style.pointerEvents = 'auto';
|
|
222
|
+
this.htmlDiv_.appendChild(this.rowDiv_);
|
|
223
|
+
|
|
224
|
+
this.rowContents_ = this.createRowContentsContainer_();
|
|
225
|
+
this.rowContents_.style.pointerEvents = 'none';
|
|
226
|
+
this.rowDiv_.appendChild(this.rowContents_);
|
|
227
|
+
|
|
228
|
+
this.iconDom_ = this.createIconDom_();
|
|
229
|
+
aria.setRole(this.iconDom_, aria.Role.PRESENTATION);
|
|
230
|
+
this.rowContents_.appendChild(this.iconDom_);
|
|
231
|
+
|
|
232
|
+
this.labelDom_ = this.createLabelDom_(this.name_);
|
|
233
|
+
this.rowContents_.appendChild(this.labelDom_);
|
|
234
|
+
aria.setState(
|
|
235
|
+
/** @type {!Element} */ (this.htmlDiv_), aria.State.LABELLEDBY,
|
|
236
|
+
this.labelDom_.getAttribute('id'));
|
|
237
|
+
|
|
238
|
+
this.addColourBorder_(this.colour_);
|
|
239
|
+
|
|
240
|
+
return this.htmlDiv_;
|
|
241
|
+
}
|
|
78
242
|
|
|
79
243
|
/**
|
|
80
|
-
*
|
|
81
|
-
* @
|
|
244
|
+
* Creates the container that holds the row and any subcategories.
|
|
245
|
+
* @return {!HTMLDivElement} The div that holds the icon and the label.
|
|
82
246
|
* @protected
|
|
83
247
|
*/
|
|
84
|
-
|
|
248
|
+
createContainer_() {
|
|
249
|
+
const container =
|
|
250
|
+
/** @type {!HTMLDivElement} */ (document.createElement('div'));
|
|
251
|
+
dom.addClass(container, this.cssConfig_['container']);
|
|
252
|
+
return container;
|
|
253
|
+
}
|
|
85
254
|
|
|
86
255
|
/**
|
|
87
|
-
*
|
|
88
|
-
*
|
|
256
|
+
* Creates the parent of the contents container. All clicks will happen on
|
|
257
|
+
* this div.
|
|
258
|
+
* @return {!HTMLDivElement} The div that holds the contents container.
|
|
89
259
|
* @protected
|
|
90
260
|
*/
|
|
91
|
-
|
|
261
|
+
createRowContainer_() {
|
|
262
|
+
const rowDiv =
|
|
263
|
+
/** @type {!HTMLDivElement} */ (document.createElement('div'));
|
|
264
|
+
dom.addClass(rowDiv, this.cssConfig_['row']);
|
|
265
|
+
let nestedPadding = ToolboxCategory.nestedPadding * this.getLevel();
|
|
266
|
+
nestedPadding = nestedPadding.toString() + 'px';
|
|
267
|
+
this.workspace_.RTL ? rowDiv.style.paddingRight = nestedPadding :
|
|
268
|
+
rowDiv.style.paddingLeft = nestedPadding;
|
|
269
|
+
return rowDiv;
|
|
270
|
+
}
|
|
92
271
|
|
|
93
272
|
/**
|
|
94
|
-
*
|
|
95
|
-
*
|
|
273
|
+
* Creates the container for the label and icon.
|
|
274
|
+
* This is necessary so we can set all subcategory pointer events to none.
|
|
275
|
+
* @return {!HTMLDivElement} The div that holds the icon and the label.
|
|
96
276
|
* @protected
|
|
97
277
|
*/
|
|
98
|
-
|
|
278
|
+
createRowContentsContainer_() {
|
|
279
|
+
const contentsContainer =
|
|
280
|
+
/** @type {!HTMLDivElement} */ (document.createElement('div'));
|
|
281
|
+
dom.addClass(contentsContainer, this.cssConfig_['rowcontentcontainer']);
|
|
282
|
+
return contentsContainer;
|
|
283
|
+
}
|
|
99
284
|
|
|
100
285
|
/**
|
|
101
|
-
*
|
|
102
|
-
* @
|
|
286
|
+
* Creates the span that holds the category icon.
|
|
287
|
+
* @return {!Element} The span that holds the category icon.
|
|
103
288
|
* @protected
|
|
104
289
|
*/
|
|
105
|
-
|
|
290
|
+
createIconDom_() {
|
|
291
|
+
const toolboxIcon = document.createElement('span');
|
|
292
|
+
if (!this.parentToolbox_.isHorizontal()) {
|
|
293
|
+
dom.addClass(toolboxIcon, this.cssConfig_['icon']);
|
|
294
|
+
}
|
|
106
295
|
|
|
107
|
-
|
|
108
|
-
|
|
296
|
+
toolboxIcon.style.display = 'inline-block';
|
|
297
|
+
return toolboxIcon;
|
|
298
|
+
}
|
|
109
299
|
|
|
110
300
|
/**
|
|
111
|
-
*
|
|
112
|
-
*
|
|
301
|
+
* Creates the span that holds the category label.
|
|
302
|
+
* This should have an ID for accessibility purposes.
|
|
303
|
+
* @param {string} name The name of the category.
|
|
304
|
+
* @return {!Element} The span that holds the category label.
|
|
113
305
|
* @protected
|
|
114
306
|
*/
|
|
115
|
-
|
|
307
|
+
createLabelDom_(name) {
|
|
308
|
+
const toolboxLabel = document.createElement('span');
|
|
309
|
+
toolboxLabel.setAttribute('id', this.getId() + '.label');
|
|
310
|
+
toolboxLabel.textContent = name;
|
|
311
|
+
dom.addClass(toolboxLabel, this.cssConfig_['label']);
|
|
312
|
+
return toolboxLabel;
|
|
313
|
+
}
|
|
116
314
|
|
|
117
315
|
/**
|
|
118
|
-
*
|
|
119
|
-
* @
|
|
120
|
-
* @protected
|
|
316
|
+
* Updates the colour for this category.
|
|
317
|
+
* @public
|
|
121
318
|
*/
|
|
122
|
-
|
|
319
|
+
refreshTheme() {
|
|
320
|
+
this.colour_ = this.getColour_(/** @type {toolbox.CategoryInfo} **/
|
|
321
|
+
(this.toolboxItemDef_));
|
|
322
|
+
this.addColourBorder_(this.colour_);
|
|
323
|
+
}
|
|
123
324
|
|
|
124
325
|
/**
|
|
125
|
-
*
|
|
126
|
-
* @
|
|
326
|
+
* Add the strip of colour to the toolbox category.
|
|
327
|
+
* @param {string} colour The category colour.
|
|
127
328
|
* @protected
|
|
128
329
|
*/
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
* row:(string|undefined),
|
|
141
|
-
* rowcontentcontainer:(string|undefined),
|
|
142
|
-
* icon:(string|undefined),
|
|
143
|
-
* label:(string|undefined),
|
|
144
|
-
* selected:(string|undefined),
|
|
145
|
-
* openicon:(string|undefined),
|
|
146
|
-
* closedicon:(string|undefined)
|
|
147
|
-
* }}
|
|
148
|
-
*/
|
|
149
|
-
ToolboxCategory.CssConfig;
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Name used for registering a toolbox category.
|
|
153
|
-
* @const {string}
|
|
154
|
-
*/
|
|
155
|
-
ToolboxCategory.registrationName = 'category';
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* The number of pixels to move the category over at each nested level.
|
|
159
|
-
* @type {number}
|
|
160
|
-
*/
|
|
161
|
-
ToolboxCategory.nestedPadding = 19;
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* The width in pixels of the strip of colour next to each category.
|
|
165
|
-
* @type {number}
|
|
166
|
-
*/
|
|
167
|
-
ToolboxCategory.borderWidth = 8;
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* The default colour of the category. This is used as the background colour of
|
|
171
|
-
* the category when it is selected.
|
|
172
|
-
* @type {string}
|
|
173
|
-
*/
|
|
174
|
-
ToolboxCategory.defaultBackgroundColour = '#57e';
|
|
330
|
+
addColourBorder_(colour) {
|
|
331
|
+
if (colour) {
|
|
332
|
+
const border =
|
|
333
|
+
ToolboxCategory.borderWidth + 'px solid ' + (colour || '#ddd');
|
|
334
|
+
if (this.workspace_.RTL) {
|
|
335
|
+
this.rowDiv_.style.borderRight = border;
|
|
336
|
+
} else {
|
|
337
|
+
this.rowDiv_.style.borderLeft = border;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
175
341
|
|
|
176
|
-
/**
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
'icon': 'blocklyTreeIcon',
|
|
188
|
-
'label': 'blocklyTreeLabel',
|
|
189
|
-
'contents': 'blocklyToolboxContents',
|
|
190
|
-
'selected': 'blocklyTreeSelected',
|
|
191
|
-
'openicon': 'blocklyTreeIconOpen',
|
|
192
|
-
'closedicon': 'blocklyTreeIconClosed',
|
|
193
|
-
};
|
|
194
|
-
};
|
|
342
|
+
/**
|
|
343
|
+
* Gets either the colour or the style for a category.
|
|
344
|
+
* @param {!toolbox.CategoryInfo} categoryDef The object holding
|
|
345
|
+
* information on the category.
|
|
346
|
+
* @return {string} The hex colour for the category.
|
|
347
|
+
* @protected
|
|
348
|
+
*/
|
|
349
|
+
getColour_(categoryDef) {
|
|
350
|
+
const styleName =
|
|
351
|
+
categoryDef['categorystyle'] || categoryDef['categoryStyle'];
|
|
352
|
+
const colour = categoryDef['colour'];
|
|
195
353
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
const contents = categoryDef['contents'];
|
|
205
|
-
|
|
206
|
-
if (categoryDef['custom']) {
|
|
207
|
-
this.flyoutItems_ = categoryDef['custom'];
|
|
208
|
-
} else if (contents) {
|
|
209
|
-
for (let i = 0; i < contents.length; i++) {
|
|
210
|
-
const itemDef = contents[i];
|
|
211
|
-
const flyoutItem =
|
|
212
|
-
/** @type {toolbox.FlyoutItemInfo} */ (itemDef);
|
|
213
|
-
this.flyoutItems_.push(flyoutItem);
|
|
354
|
+
if (colour && styleName) {
|
|
355
|
+
console.warn(
|
|
356
|
+
'Toolbox category "' + this.name_ +
|
|
357
|
+
'" must not have both a style and a colour');
|
|
358
|
+
} else if (styleName) {
|
|
359
|
+
return this.getColourfromStyle_(styleName);
|
|
360
|
+
} else {
|
|
361
|
+
return this.parseColour_(colour);
|
|
214
362
|
}
|
|
363
|
+
return '';
|
|
215
364
|
}
|
|
216
|
-
};
|
|
217
365
|
|
|
218
|
-
/**
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
366
|
+
/**
|
|
367
|
+
* Sets the colour for the category using the style name and returns the new
|
|
368
|
+
* colour as a hex string.
|
|
369
|
+
* @param {string} styleName Name of the style.
|
|
370
|
+
* @return {string} The hex colour for the category.
|
|
371
|
+
* @private
|
|
372
|
+
*/
|
|
373
|
+
getColourfromStyle_(styleName) {
|
|
374
|
+
const theme = this.workspace_.getTheme();
|
|
375
|
+
if (styleName && theme) {
|
|
376
|
+
const style = theme.categoryStyles[styleName];
|
|
377
|
+
if (style && style.colour) {
|
|
378
|
+
return this.parseColour_(style.colour);
|
|
379
|
+
} else {
|
|
380
|
+
console.warn(
|
|
381
|
+
'Style "' + styleName + '" must exist and contain a colour value');
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
return '';
|
|
225
385
|
}
|
|
226
|
-
};
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Creates the DOM for the category.
|
|
230
|
-
* @return {!Element} The parent element for the category.
|
|
231
|
-
* @protected
|
|
232
|
-
*/
|
|
233
|
-
ToolboxCategory.prototype.createDom_ = function() {
|
|
234
|
-
this.htmlDiv_ = this.createContainer_();
|
|
235
|
-
aria.setRole(this.htmlDiv_, aria.Role.TREEITEM);
|
|
236
|
-
aria.setState(
|
|
237
|
-
/** @type {!Element} */ (this.htmlDiv_), aria.State.SELECTED, false);
|
|
238
|
-
aria.setState(
|
|
239
|
-
/** @type {!Element} */ (this.htmlDiv_), aria.State.LEVEL, this.level_);
|
|
240
|
-
|
|
241
|
-
this.rowDiv_ = this.createRowContainer_();
|
|
242
|
-
this.rowDiv_.style.pointerEvents = 'auto';
|
|
243
|
-
this.htmlDiv_.appendChild(this.rowDiv_);
|
|
244
|
-
|
|
245
|
-
this.rowContents_ = this.createRowContentsContainer_();
|
|
246
|
-
this.rowContents_.style.pointerEvents = 'none';
|
|
247
|
-
this.rowDiv_.appendChild(this.rowContents_);
|
|
248
|
-
|
|
249
|
-
this.iconDom_ = this.createIconDom_();
|
|
250
|
-
aria.setRole(this.iconDom_, aria.Role.PRESENTATION);
|
|
251
|
-
this.rowContents_.appendChild(this.iconDom_);
|
|
252
|
-
|
|
253
|
-
this.labelDom_ = this.createLabelDom_(this.name_);
|
|
254
|
-
this.rowContents_.appendChild(this.labelDom_);
|
|
255
|
-
aria.setState(
|
|
256
|
-
/** @type {!Element} */ (this.htmlDiv_), aria.State.LABELLEDBY,
|
|
257
|
-
this.labelDom_.getAttribute('id'));
|
|
258
386
|
|
|
259
|
-
|
|
387
|
+
/**
|
|
388
|
+
* Gets the HTML element that is clickable.
|
|
389
|
+
* The parent toolbox element receives clicks. The parent toolbox will add an
|
|
390
|
+
* ID to this element so it can pass the onClick event to the correct
|
|
391
|
+
* toolboxItem.
|
|
392
|
+
* @return {!Element} The HTML element that receives clicks.
|
|
393
|
+
* @public
|
|
394
|
+
*/
|
|
395
|
+
getClickTarget() {
|
|
396
|
+
return /** @type {!Element} */ (this.rowDiv_);
|
|
397
|
+
}
|
|
260
398
|
|
|
261
|
-
|
|
262
|
-
|
|
399
|
+
/**
|
|
400
|
+
* Parses the colour on the category.
|
|
401
|
+
* @param {number|string} colourValue HSV hue value (0 to 360), #RRGGBB
|
|
402
|
+
* string, or a message reference string pointing to one of those two
|
|
403
|
+
* values.
|
|
404
|
+
* @return {string} The hex colour for the category.
|
|
405
|
+
* @private
|
|
406
|
+
*/
|
|
407
|
+
parseColour_(colourValue) {
|
|
408
|
+
// Decode the colour for any potential message references
|
|
409
|
+
// (eg. `%{BKY_MATH_HUE}`).
|
|
410
|
+
const colour = parsing.replaceMessageReferences(colourValue);
|
|
411
|
+
if (colour == null || colour === '') {
|
|
412
|
+
// No attribute. No colour.
|
|
413
|
+
return '';
|
|
414
|
+
} else {
|
|
415
|
+
const hue = Number(colour);
|
|
416
|
+
if (!isNaN(hue)) {
|
|
417
|
+
return colourUtils.hueToHex(hue);
|
|
418
|
+
} else {
|
|
419
|
+
const hex = colourUtils.parse(colour);
|
|
420
|
+
if (hex) {
|
|
421
|
+
return hex;
|
|
422
|
+
} else {
|
|
423
|
+
console.warn(
|
|
424
|
+
'Toolbox category "' + this.name_ +
|
|
425
|
+
'" has unrecognized colour attribute: ' + colour);
|
|
426
|
+
return '';
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
263
431
|
|
|
264
|
-
/**
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
432
|
+
/**
|
|
433
|
+
* Adds appropriate classes to display an open icon.
|
|
434
|
+
* @param {?Element} iconDiv The div that holds the icon.
|
|
435
|
+
* @protected
|
|
436
|
+
*/
|
|
437
|
+
openIcon_(iconDiv) {
|
|
438
|
+
if (!iconDiv) {
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
dom.removeClasses(iconDiv, this.cssConfig_['closedicon']);
|
|
442
|
+
dom.addClass(iconDiv, this.cssConfig_['openicon']);
|
|
443
|
+
}
|
|
274
444
|
|
|
275
|
-
/**
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
rowDiv.style.paddingLeft = nestedPadding;
|
|
288
|
-
return rowDiv;
|
|
289
|
-
};
|
|
445
|
+
/**
|
|
446
|
+
* Adds appropriate classes to display a closed icon.
|
|
447
|
+
* @param {?Element} iconDiv The div that holds the icon.
|
|
448
|
+
* @protected
|
|
449
|
+
*/
|
|
450
|
+
closeIcon_(iconDiv) {
|
|
451
|
+
if (!iconDiv) {
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
dom.removeClasses(iconDiv, this.cssConfig_['openicon']);
|
|
455
|
+
dom.addClass(iconDiv, this.cssConfig_['closedicon']);
|
|
456
|
+
}
|
|
290
457
|
|
|
291
|
-
/**
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
return contentsContainer;
|
|
301
|
-
};
|
|
458
|
+
/**
|
|
459
|
+
* Sets whether the category is visible or not.
|
|
460
|
+
* For a category to be visible its parent category must also be expanded.
|
|
461
|
+
* @param {boolean} isVisible True if category should be visible.
|
|
462
|
+
* @protected
|
|
463
|
+
*/
|
|
464
|
+
setVisible_(isVisible) {
|
|
465
|
+
this.htmlDiv_.style.display = isVisible ? 'block' : 'none';
|
|
466
|
+
this.isHidden_ = !isVisible;
|
|
302
467
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
* @protected
|
|
307
|
-
*/
|
|
308
|
-
ToolboxCategory.prototype.createIconDom_ = function() {
|
|
309
|
-
const toolboxIcon = document.createElement('span');
|
|
310
|
-
if (!this.parentToolbox_.isHorizontal()) {
|
|
311
|
-
dom.addClass(toolboxIcon, this.cssConfig_['icon']);
|
|
468
|
+
if (this.parentToolbox_.getSelectedItem() === this) {
|
|
469
|
+
this.parentToolbox_.clearSelection();
|
|
470
|
+
}
|
|
312
471
|
}
|
|
313
472
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
473
|
+
/**
|
|
474
|
+
* Hide the category.
|
|
475
|
+
*/
|
|
476
|
+
hide() {
|
|
477
|
+
this.setVisible_(false);
|
|
478
|
+
}
|
|
317
479
|
|
|
318
|
-
/**
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
ToolboxCategory.prototype.createLabelDom_ = function(name) {
|
|
326
|
-
const toolboxLabel = document.createElement('span');
|
|
327
|
-
toolboxLabel.setAttribute('id', this.getId() + '.label');
|
|
328
|
-
toolboxLabel.textContent = name;
|
|
329
|
-
dom.addClass(toolboxLabel, this.cssConfig_['label']);
|
|
330
|
-
return toolboxLabel;
|
|
331
|
-
};
|
|
480
|
+
/**
|
|
481
|
+
* Show the category. Category will only appear if its parent category is also
|
|
482
|
+
* expanded.
|
|
483
|
+
*/
|
|
484
|
+
show() {
|
|
485
|
+
this.setVisible_(true);
|
|
486
|
+
}
|
|
332
487
|
|
|
333
|
-
/**
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
488
|
+
/**
|
|
489
|
+
* Whether the category is visible.
|
|
490
|
+
* A category is only visible if all of its ancestors are expanded and
|
|
491
|
+
* isHidden_ is false.
|
|
492
|
+
* @return {boolean} True if the category is visible, false otherwise.
|
|
493
|
+
* @public
|
|
494
|
+
*/
|
|
495
|
+
isVisible() {
|
|
496
|
+
return !this.isHidden_ && this.allAncestorsExpanded_();
|
|
497
|
+
}
|
|
342
498
|
|
|
343
|
-
/**
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
499
|
+
/**
|
|
500
|
+
* Whether all ancestors of a category (parent and parent's parent, etc.) are
|
|
501
|
+
* expanded.
|
|
502
|
+
* @return {boolean} True only if every ancestor is expanded
|
|
503
|
+
* @protected
|
|
504
|
+
*/
|
|
505
|
+
allAncestorsExpanded_() {
|
|
506
|
+
let category = this;
|
|
507
|
+
while (category.getParent()) {
|
|
508
|
+
category = category.getParent();
|
|
509
|
+
if (!category.isExpanded()) {
|
|
510
|
+
return false;
|
|
511
|
+
}
|
|
356
512
|
}
|
|
513
|
+
return true;
|
|
357
514
|
}
|
|
358
|
-
};
|
|
359
|
-
|
|
360
|
-
/**
|
|
361
|
-
* Gets either the colour or the style for a category.
|
|
362
|
-
* @param {!toolbox.CategoryInfo} categoryDef The object holding
|
|
363
|
-
* information on the category.
|
|
364
|
-
* @return {string} The hex colour for the category.
|
|
365
|
-
* @protected
|
|
366
|
-
*/
|
|
367
|
-
ToolboxCategory.prototype.getColour_ = function(categoryDef) {
|
|
368
|
-
const styleName =
|
|
369
|
-
categoryDef['categorystyle'] || categoryDef['categoryStyle'];
|
|
370
|
-
const colour = categoryDef['colour'];
|
|
371
|
-
|
|
372
|
-
if (colour && styleName) {
|
|
373
|
-
console.warn(
|
|
374
|
-
'Toolbox category "' + this.name_ +
|
|
375
|
-
'" must not have both a style and a colour');
|
|
376
|
-
} else if (styleName) {
|
|
377
|
-
return this.getColourfromStyle_(styleName);
|
|
378
|
-
} else {
|
|
379
|
-
return this.parseColour_(colour);
|
|
380
|
-
}
|
|
381
|
-
return '';
|
|
382
|
-
};
|
|
383
515
|
|
|
384
|
-
/**
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
* @private
|
|
390
|
-
*/
|
|
391
|
-
ToolboxCategory.prototype.getColourfromStyle_ = function(styleName) {
|
|
392
|
-
const theme = this.workspace_.getTheme();
|
|
393
|
-
if (styleName && theme) {
|
|
394
|
-
const style = theme.categoryStyles[styleName];
|
|
395
|
-
if (style && style.colour) {
|
|
396
|
-
return this.parseColour_(style.colour);
|
|
397
|
-
} else {
|
|
398
|
-
console.warn(
|
|
399
|
-
'Style "' + styleName + '" must exist and contain a colour value');
|
|
400
|
-
}
|
|
516
|
+
/**
|
|
517
|
+
* @override
|
|
518
|
+
*/
|
|
519
|
+
isSelectable() {
|
|
520
|
+
return this.isVisible() && !this.isDisabled_;
|
|
401
521
|
}
|
|
402
|
-
return '';
|
|
403
|
-
};
|
|
404
522
|
|
|
405
|
-
/**
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
return /** @type {!Element} */ (this.rowDiv_);
|
|
414
|
-
};
|
|
523
|
+
/**
|
|
524
|
+
* Handles when the toolbox item is clicked.
|
|
525
|
+
* @param {!Event} _e Click event to handle.
|
|
526
|
+
* @public
|
|
527
|
+
*/
|
|
528
|
+
onClick(_e) {
|
|
529
|
+
// No-op
|
|
530
|
+
}
|
|
415
531
|
|
|
416
|
-
/**
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
// No attribute. No colour.
|
|
429
|
-
return '';
|
|
430
|
-
} else {
|
|
431
|
-
const hue = Number(colour);
|
|
432
|
-
if (!isNaN(hue)) {
|
|
433
|
-
return colourUtils.hueToHex(hue);
|
|
532
|
+
/**
|
|
533
|
+
* Sets the current category as selected.
|
|
534
|
+
* @param {boolean} isSelected True if this category is selected, false
|
|
535
|
+
* otherwise.
|
|
536
|
+
* @public
|
|
537
|
+
*/
|
|
538
|
+
setSelected(isSelected) {
|
|
539
|
+
if (isSelected) {
|
|
540
|
+
const defaultColour =
|
|
541
|
+
this.parseColour_(ToolboxCategory.defaultBackgroundColour);
|
|
542
|
+
this.rowDiv_.style.backgroundColor = this.colour_ || defaultColour;
|
|
543
|
+
dom.addClass(this.rowDiv_, this.cssConfig_['selected']);
|
|
434
544
|
} else {
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
return hex;
|
|
438
|
-
} else {
|
|
439
|
-
console.warn(
|
|
440
|
-
'Toolbox category "' + this.name_ +
|
|
441
|
-
'" has unrecognized colour attribute: ' + colour);
|
|
442
|
-
return '';
|
|
443
|
-
}
|
|
545
|
+
this.rowDiv_.style.backgroundColor = '';
|
|
546
|
+
dom.removeClass(this.rowDiv_, this.cssConfig_['selected']);
|
|
444
547
|
}
|
|
548
|
+
aria.setState(
|
|
549
|
+
/** @type {!Element} */ (this.htmlDiv_), aria.State.SELECTED,
|
|
550
|
+
isSelected);
|
|
445
551
|
}
|
|
446
|
-
};
|
|
447
552
|
|
|
448
|
-
/**
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
553
|
+
/**
|
|
554
|
+
* Sets whether the category is disabled.
|
|
555
|
+
* @param {boolean} isDisabled True to disable the category, false otherwise.
|
|
556
|
+
*/
|
|
557
|
+
setDisabled(isDisabled) {
|
|
558
|
+
this.isDisabled_ = isDisabled;
|
|
559
|
+
this.getDiv().setAttribute('disabled', isDisabled);
|
|
560
|
+
isDisabled ? this.getDiv().setAttribute('disabled', 'true') :
|
|
561
|
+
this.getDiv().removeAttribute('disabled');
|
|
456
562
|
}
|
|
457
|
-
dom.removeClasses(iconDiv, this.cssConfig_['closedicon']);
|
|
458
|
-
dom.addClass(iconDiv, this.cssConfig_['openicon']);
|
|
459
|
-
};
|
|
460
563
|
|
|
461
|
-
/**
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
return;
|
|
564
|
+
/**
|
|
565
|
+
* Gets the name of the category. Used for emitting events.
|
|
566
|
+
* @return {string} The name of the toolbox item.
|
|
567
|
+
* @public
|
|
568
|
+
*/
|
|
569
|
+
getName() {
|
|
570
|
+
return this.name_;
|
|
469
571
|
}
|
|
470
|
-
dom.removeClasses(iconDiv, this.cssConfig_['openicon']);
|
|
471
|
-
dom.addClass(iconDiv, this.cssConfig_['closedicon']);
|
|
472
|
-
};
|
|
473
572
|
|
|
474
|
-
/**
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
*/
|
|
480
|
-
ToolboxCategory.prototype.setVisible_ = function(isVisible) {
|
|
481
|
-
this.htmlDiv_.style.display = isVisible ? 'block' : 'none';
|
|
482
|
-
this.isHidden_ = !isVisible;
|
|
483
|
-
|
|
484
|
-
if (this.parentToolbox_.getSelectedItem() === this) {
|
|
485
|
-
this.parentToolbox_.clearSelection();
|
|
573
|
+
/**
|
|
574
|
+
* @override
|
|
575
|
+
*/
|
|
576
|
+
getParent() {
|
|
577
|
+
return this.parent_;
|
|
486
578
|
}
|
|
487
|
-
};
|
|
488
579
|
|
|
489
|
-
/**
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
}
|
|
580
|
+
/**
|
|
581
|
+
* @override
|
|
582
|
+
*/
|
|
583
|
+
getDiv() {
|
|
584
|
+
return this.htmlDiv_;
|
|
585
|
+
}
|
|
495
586
|
|
|
496
|
-
/**
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
587
|
+
/**
|
|
588
|
+
* Gets the contents of the category. These are items that are meant to be
|
|
589
|
+
* displayed in the flyout.
|
|
590
|
+
* @return {!toolbox.FlyoutItemInfoArray|string} The definition
|
|
591
|
+
* of items to be displayed in the flyout.
|
|
592
|
+
* @public
|
|
593
|
+
*/
|
|
594
|
+
getContents() {
|
|
595
|
+
return this.flyoutItems_;
|
|
596
|
+
}
|
|
503
597
|
|
|
504
|
-
/**
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
598
|
+
/**
|
|
599
|
+
* Updates the contents to be displayed in the flyout.
|
|
600
|
+
* If the flyout is open when the contents are updated, refreshSelection on
|
|
601
|
+
* the toolbox must also be called.
|
|
602
|
+
* @param {!toolbox.FlyoutDefinition|string} contents The contents
|
|
603
|
+
* to be displayed in the flyout. A string can be supplied to create a
|
|
604
|
+
* dynamic category.
|
|
605
|
+
* @public
|
|
606
|
+
*/
|
|
607
|
+
updateFlyoutContents(contents) {
|
|
608
|
+
this.flyoutItems_ = [];
|
|
514
609
|
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
let category = this;
|
|
523
|
-
while (category.getParent()) {
|
|
524
|
-
category = category.getParent();
|
|
525
|
-
if (!category.isExpanded()) {
|
|
526
|
-
return false;
|
|
610
|
+
if (typeof contents === 'string') {
|
|
611
|
+
this.toolboxItemDef_['custom'] = contents;
|
|
612
|
+
} else {
|
|
613
|
+
// Removes old custom field when contents is updated.
|
|
614
|
+
delete this.toolboxItemDef_['custom'];
|
|
615
|
+
this.toolboxItemDef_['contents'] =
|
|
616
|
+
toolbox.convertFlyoutDefToJsonArray(contents);
|
|
527
617
|
}
|
|
618
|
+
this.parseContents_(
|
|
619
|
+
/** @type {toolbox.CategoryInfo} */ (this.toolboxItemDef_));
|
|
528
620
|
}
|
|
529
|
-
return true;
|
|
530
|
-
};
|
|
531
|
-
|
|
532
|
-
/**
|
|
533
|
-
* @override
|
|
534
|
-
*/
|
|
535
|
-
ToolboxCategory.prototype.isSelectable = function() {
|
|
536
|
-
return this.isVisible() && !this.isDisabled_;
|
|
537
|
-
};
|
|
538
|
-
|
|
539
|
-
/**
|
|
540
|
-
* Handles when the toolbox item is clicked.
|
|
541
|
-
* @param {!Event} _e Click event to handle.
|
|
542
|
-
* @public
|
|
543
|
-
*/
|
|
544
|
-
ToolboxCategory.prototype.onClick = function(_e) {
|
|
545
|
-
// No-op
|
|
546
|
-
};
|
|
547
621
|
|
|
548
|
-
/**
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
if (isSelected) {
|
|
556
|
-
const defaultColour =
|
|
557
|
-
this.parseColour_(ToolboxCategory.defaultBackgroundColour);
|
|
558
|
-
this.rowDiv_.style.backgroundColor = this.colour_ || defaultColour;
|
|
559
|
-
dom.addClass(this.rowDiv_, this.cssConfig_['selected']);
|
|
560
|
-
} else {
|
|
561
|
-
this.rowDiv_.style.backgroundColor = '';
|
|
562
|
-
dom.removeClass(this.rowDiv_, this.cssConfig_['selected']);
|
|
563
|
-
}
|
|
564
|
-
aria.setState(
|
|
565
|
-
/** @type {!Element} */ (this.htmlDiv_), aria.State.SELECTED, isSelected);
|
|
566
|
-
};
|
|
567
|
-
|
|
568
|
-
/**
|
|
569
|
-
* Sets whether the category is disabled.
|
|
570
|
-
* @param {boolean} isDisabled True to disable the category, false otherwise.
|
|
571
|
-
*/
|
|
572
|
-
ToolboxCategory.prototype.setDisabled = function(isDisabled) {
|
|
573
|
-
this.isDisabled_ = isDisabled;
|
|
574
|
-
this.getDiv().setAttribute('disabled', isDisabled);
|
|
575
|
-
isDisabled ? this.getDiv().setAttribute('disabled', 'true') :
|
|
576
|
-
this.getDiv().removeAttribute('disabled');
|
|
577
|
-
};
|
|
578
|
-
|
|
579
|
-
/**
|
|
580
|
-
* Gets the name of the category. Used for emitting events.
|
|
581
|
-
* @return {string} The name of the toolbox item.
|
|
582
|
-
* @public
|
|
583
|
-
*/
|
|
584
|
-
ToolboxCategory.prototype.getName = function() {
|
|
585
|
-
return this.name_;
|
|
586
|
-
};
|
|
622
|
+
/**
|
|
623
|
+
* @override
|
|
624
|
+
*/
|
|
625
|
+
dispose() {
|
|
626
|
+
dom.removeNode(this.htmlDiv_);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
587
629
|
|
|
588
630
|
/**
|
|
589
|
-
*
|
|
631
|
+
* All the CSS class names that are used to create a category.
|
|
632
|
+
* @typedef {{
|
|
633
|
+
* container:(string|undefined),
|
|
634
|
+
* row:(string|undefined),
|
|
635
|
+
* rowcontentcontainer:(string|undefined),
|
|
636
|
+
* icon:(string|undefined),
|
|
637
|
+
* label:(string|undefined),
|
|
638
|
+
* selected:(string|undefined),
|
|
639
|
+
* openicon:(string|undefined),
|
|
640
|
+
* closedicon:(string|undefined)
|
|
641
|
+
* }}
|
|
590
642
|
*/
|
|
591
|
-
ToolboxCategory.
|
|
592
|
-
return this.parent_;
|
|
593
|
-
};
|
|
643
|
+
ToolboxCategory.CssConfig;
|
|
594
644
|
|
|
595
645
|
/**
|
|
596
|
-
*
|
|
646
|
+
* Name used for registering a toolbox category.
|
|
647
|
+
* @type {string}
|
|
597
648
|
*/
|
|
598
|
-
ToolboxCategory.
|
|
599
|
-
return this.htmlDiv_;
|
|
600
|
-
};
|
|
649
|
+
ToolboxCategory.registrationName = 'category';
|
|
601
650
|
|
|
602
651
|
/**
|
|
603
|
-
*
|
|
604
|
-
*
|
|
605
|
-
* @return {!toolbox.FlyoutItemInfoArray|string} The definition
|
|
606
|
-
* of items to be displayed in the flyout.
|
|
607
|
-
* @public
|
|
652
|
+
* The number of pixels to move the category over at each nested level.
|
|
653
|
+
* @type {number}
|
|
608
654
|
*/
|
|
609
|
-
ToolboxCategory.
|
|
610
|
-
return this.flyoutItems_;
|
|
611
|
-
};
|
|
655
|
+
ToolboxCategory.nestedPadding = 19;
|
|
612
656
|
|
|
613
657
|
/**
|
|
614
|
-
*
|
|
615
|
-
*
|
|
616
|
-
* toolbox must also be called.
|
|
617
|
-
* @param {!toolbox.FlyoutDefinition|string} contents The contents
|
|
618
|
-
* to be displayed in the flyout. A string can be supplied to create a
|
|
619
|
-
* dynamic category.
|
|
620
|
-
* @public
|
|
658
|
+
* The width in pixels of the strip of colour next to each category.
|
|
659
|
+
* @type {number}
|
|
621
660
|
*/
|
|
622
|
-
ToolboxCategory.
|
|
623
|
-
this.flyoutItems_ = [];
|
|
624
|
-
|
|
625
|
-
if (typeof contents === 'string') {
|
|
626
|
-
this.toolboxItemDef_['custom'] = contents;
|
|
627
|
-
} else {
|
|
628
|
-
// Removes old custom field when contents is updated.
|
|
629
|
-
delete this.toolboxItemDef_['custom'];
|
|
630
|
-
this.toolboxItemDef_['contents'] =
|
|
631
|
-
toolbox.convertFlyoutDefToJsonArray(contents);
|
|
632
|
-
}
|
|
633
|
-
this.parseContents_(
|
|
634
|
-
/** @type {toolbox.CategoryInfo} */ (this.toolboxItemDef_));
|
|
635
|
-
};
|
|
661
|
+
ToolboxCategory.borderWidth = 8;
|
|
636
662
|
|
|
637
663
|
/**
|
|
638
|
-
*
|
|
664
|
+
* The default colour of the category. This is used as the background colour of
|
|
665
|
+
* the category when it is selected.
|
|
666
|
+
* @type {string}
|
|
639
667
|
*/
|
|
640
|
-
ToolboxCategory.
|
|
641
|
-
dom.removeNode(this.htmlDiv_);
|
|
642
|
-
};
|
|
668
|
+
ToolboxCategory.defaultBackgroundColour = '#57e';
|
|
643
669
|
|
|
644
670
|
/**
|
|
645
671
|
* CSS for Toolbox. See css.js for use.
|
|
646
672
|
*/
|
|
647
673
|
Css.register(`
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
674
|
+
.blocklyTreeRow:not(.blocklyTreeSelected):hover {
|
|
675
|
+
background-color: rgba(255, 255, 255, .2);
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
.blocklyToolboxDiv[layout="h"] .blocklyToolboxCategory {
|
|
679
|
+
margin: 1px 5px 1px 0;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
.blocklyToolboxDiv[dir="RTL"][layout="h"] .blocklyToolboxCategory {
|
|
683
|
+
margin: 1px 0 1px 5px;
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
.blocklyTreeRow {
|
|
687
|
+
height: 22px;
|
|
688
|
+
line-height: 22px;
|
|
689
|
+
margin-bottom: 3px;
|
|
690
|
+
padding-right: 8px;
|
|
691
|
+
white-space: nowrap;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
.blocklyToolboxDiv[dir="RTL"] .blocklyTreeRow {
|
|
695
|
+
margin-left: 8px;
|
|
696
|
+
padding-right: 0;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
.blocklyTreeIcon {
|
|
700
|
+
background-image: url(<<<PATH>>>/sprites.png);
|
|
701
|
+
height: 16px;
|
|
702
|
+
vertical-align: middle;
|
|
703
|
+
visibility: hidden;
|
|
704
|
+
width: 16px;
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
.blocklyTreeIconClosed {
|
|
708
|
+
background-position: -32px -1px;
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
.blocklyToolboxDiv[dir="RTL"] .blocklyTreeIconClosed {
|
|
712
|
+
background-position: 0 -1px;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
.blocklyTreeSelected>.blocklyTreeIconClosed {
|
|
716
|
+
background-position: -32px -17px;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
.blocklyToolboxDiv[dir="RTL"] .blocklyTreeSelected>.blocklyTreeIconClosed {
|
|
720
|
+
background-position: 0 -17px;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
.blocklyTreeIconOpen {
|
|
724
|
+
background-position: -16px -1px;
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
.blocklyTreeSelected>.blocklyTreeIconOpen {
|
|
728
|
+
background-position: -16px -17px;
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
.blocklyTreeLabel {
|
|
732
|
+
cursor: default;
|
|
733
|
+
font: 16px sans-serif;
|
|
734
|
+
padding: 0 3px;
|
|
735
|
+
vertical-align: middle;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
.blocklyToolboxDelete .blocklyTreeLabel {
|
|
739
|
+
cursor: url("<<<PATH>>>/handdelete.cur"), auto;
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
.blocklyTreeSelected .blocklyTreeLabel {
|
|
743
|
+
color: #fff;
|
|
744
|
+
}
|
|
719
745
|
`);
|
|
720
746
|
|
|
721
747
|
registry.register(
|