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/comment.js
CHANGED
|
@@ -19,7 +19,6 @@ const Css = goog.require('Blockly.Css');
|
|
|
19
19
|
const browserEvents = goog.require('Blockly.browserEvents');
|
|
20
20
|
const dom = goog.require('Blockly.utils.dom');
|
|
21
21
|
const eventUtils = goog.require('Blockly.Events.utils');
|
|
22
|
-
const object = goog.require('Blockly.utils.object');
|
|
23
22
|
const userAgent = goog.require('Blockly.utils.userAgent');
|
|
24
23
|
/* eslint-disable-next-line no-unused-vars */
|
|
25
24
|
const {BlockSvg} = goog.requireType('Blockly.BlockSvg');
|
|
@@ -44,384 +43,406 @@ goog.require('Blockly.Warning');
|
|
|
44
43
|
|
|
45
44
|
/**
|
|
46
45
|
* Class for a comment.
|
|
47
|
-
* @param {!Block} block The block associated with this comment.
|
|
48
46
|
* @extends {Icon}
|
|
49
|
-
* @constructor
|
|
50
47
|
* @alias Blockly.Comment
|
|
51
48
|
*/
|
|
52
|
-
|
|
53
|
-
Comment.superClass_.constructor.call(this, block);
|
|
54
|
-
|
|
49
|
+
class Comment extends Icon {
|
|
55
50
|
/**
|
|
56
|
-
* The
|
|
57
|
-
* @type {!Block.CommentModel}
|
|
58
|
-
* @private
|
|
51
|
+
* @param {!BlockSvg} block The block associated with this comment.
|
|
59
52
|
*/
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
53
|
+
constructor(block) {
|
|
54
|
+
super(block);
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The model for this comment.
|
|
58
|
+
* @type {!Block.CommentModel}
|
|
59
|
+
* @private
|
|
60
|
+
*/
|
|
61
|
+
this.model_ = block.commentModel;
|
|
62
|
+
// If someone creates the comment directly instead of calling
|
|
63
|
+
// block.setCommentText we want to make sure the text is non-null;
|
|
64
|
+
this.model_.text = this.model_.text || '';
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* The model's text value at the start of an edit.
|
|
68
|
+
* Used to tell if an event should be fired at the end of an edit.
|
|
69
|
+
* @type {?string}
|
|
70
|
+
* @private
|
|
71
|
+
*/
|
|
72
|
+
this.cachedText_ = '';
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Mouse up event data.
|
|
76
|
+
* @type {?browserEvents.Data}
|
|
77
|
+
* @private
|
|
78
|
+
*/
|
|
79
|
+
this.onMouseUpWrapper_ = null;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Wheel event data.
|
|
83
|
+
* @type {?browserEvents.Data}
|
|
84
|
+
* @private
|
|
85
|
+
*/
|
|
86
|
+
this.onWheelWrapper_ = null;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Change event data.
|
|
90
|
+
* @type {?browserEvents.Data}
|
|
91
|
+
* @private
|
|
92
|
+
*/
|
|
93
|
+
this.onChangeWrapper_ = null;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Input event data.
|
|
97
|
+
* @type {?browserEvents.Data}
|
|
98
|
+
* @private
|
|
99
|
+
*/
|
|
100
|
+
this.onInputWrapper_ = null;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* The SVG element that contains the text edit area, or null if not created.
|
|
104
|
+
* @type {?SVGForeignObjectElement}
|
|
105
|
+
* @private
|
|
106
|
+
*/
|
|
107
|
+
this.foreignObject_ = null;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* The editable text area, or null if not created.
|
|
111
|
+
* @type {?Element}
|
|
112
|
+
* @private
|
|
113
|
+
*/
|
|
114
|
+
this.textarea_ = null;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* The top-level node of the comment text, or null if not created.
|
|
118
|
+
* @type {?SVGTextElement}
|
|
119
|
+
* @private
|
|
120
|
+
*/
|
|
121
|
+
this.paragraphElement_ = null;
|
|
122
|
+
|
|
123
|
+
this.createIcon();
|
|
124
|
+
}
|
|
64
125
|
|
|
65
126
|
/**
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
* @
|
|
69
|
-
* @private
|
|
127
|
+
* Draw the comment icon.
|
|
128
|
+
* @param {!Element} group The icon group.
|
|
129
|
+
* @protected
|
|
70
130
|
*/
|
|
71
|
-
|
|
131
|
+
drawIcon_(group) {
|
|
132
|
+
// Circle.
|
|
133
|
+
dom.createSvgElement(
|
|
134
|
+
Svg.CIRCLE,
|
|
135
|
+
{'class': 'blocklyIconShape', 'r': '8', 'cx': '8', 'cy': '8'}, group);
|
|
136
|
+
// Can't use a real '?' text character since different browsers and
|
|
137
|
+
// operating systems render it differently. Body of question mark.
|
|
138
|
+
dom.createSvgElement(
|
|
139
|
+
Svg.PATH, {
|
|
140
|
+
'class': 'blocklyIconSymbol',
|
|
141
|
+
'd': 'm6.8,10h2c0.003,-0.617 0.271,-0.962 0.633,-1.266 2.875,-2.405' +
|
|
142
|
+
'0.607,-5.534 -3.765,-3.874v1.7c3.12,-1.657 3.698,0.118 2.336,1.25' +
|
|
143
|
+
'-1.201,0.998 -1.201,1.528 -1.204,2.19z',
|
|
144
|
+
},
|
|
145
|
+
group);
|
|
146
|
+
// Dot of question mark.
|
|
147
|
+
dom.createSvgElement(
|
|
148
|
+
Svg.RECT, {
|
|
149
|
+
'class': 'blocklyIconSymbol',
|
|
150
|
+
'x': '6.8',
|
|
151
|
+
'y': '10.78',
|
|
152
|
+
'height': '2',
|
|
153
|
+
'width': '2',
|
|
154
|
+
},
|
|
155
|
+
group);
|
|
156
|
+
}
|
|
72
157
|
|
|
73
158
|
/**
|
|
74
|
-
*
|
|
75
|
-
* @
|
|
159
|
+
* Create the editor for the comment's bubble.
|
|
160
|
+
* @return {!SVGElement} The top-level node of the editor.
|
|
76
161
|
* @private
|
|
77
162
|
*/
|
|
78
|
-
|
|
163
|
+
createEditor_() {
|
|
164
|
+
/* Create the editor. Here's the markup that will be generated in
|
|
165
|
+
* editable mode:
|
|
166
|
+
<foreignObject x="8" y="8" width="164" height="164">
|
|
167
|
+
<body xmlns="http://www.w3.org/1999/xhtml" class="blocklyMinimalBody">
|
|
168
|
+
<textarea xmlns="http://www.w3.org/1999/xhtml"
|
|
169
|
+
class="blocklyCommentTextarea"
|
|
170
|
+
style="height: 164px; width: 164px;"></textarea>
|
|
171
|
+
</body>
|
|
172
|
+
</foreignObject>
|
|
173
|
+
* For non-editable mode see Warning.textToDom_.
|
|
174
|
+
*/
|
|
175
|
+
|
|
176
|
+
this.foreignObject_ = dom.createSvgElement(
|
|
177
|
+
Svg.FOREIGNOBJECT, {'x': Bubble.BORDER_WIDTH, 'y': Bubble.BORDER_WIDTH},
|
|
178
|
+
null);
|
|
179
|
+
|
|
180
|
+
const body = document.createElementNS(dom.HTML_NS, 'body');
|
|
181
|
+
body.setAttribute('xmlns', dom.HTML_NS);
|
|
182
|
+
body.className = 'blocklyMinimalBody';
|
|
183
|
+
|
|
184
|
+
this.textarea_ = document.createElementNS(dom.HTML_NS, 'textarea');
|
|
185
|
+
const textarea = this.textarea_;
|
|
186
|
+
textarea.className = 'blocklyCommentTextarea';
|
|
187
|
+
textarea.setAttribute('dir', this.block_.RTL ? 'RTL' : 'LTR');
|
|
188
|
+
textarea.value = this.model_.text;
|
|
189
|
+
this.resizeTextarea_();
|
|
190
|
+
|
|
191
|
+
body.appendChild(textarea);
|
|
192
|
+
this.foreignObject_.appendChild(body);
|
|
193
|
+
|
|
194
|
+
// Ideally this would be hooked to the focus event for the comment.
|
|
195
|
+
// However doing so in Firefox swallows the cursor for unknown reasons.
|
|
196
|
+
// So this is hooked to mouseup instead. No big deal.
|
|
197
|
+
this.onMouseUpWrapper_ = browserEvents.conditionalBind(
|
|
198
|
+
textarea, 'mouseup', this, this.startEdit_, true, true);
|
|
199
|
+
// Don't zoom with mousewheel.
|
|
200
|
+
this.onWheelWrapper_ =
|
|
201
|
+
browserEvents.conditionalBind(textarea, 'wheel', this, function(e) {
|
|
202
|
+
e.stopPropagation();
|
|
203
|
+
});
|
|
204
|
+
this.onChangeWrapper_ = browserEvents.conditionalBind(
|
|
205
|
+
textarea, 'change', this,
|
|
206
|
+
/**
|
|
207
|
+
* @this {Comment}
|
|
208
|
+
* @param {Event} _e Unused event parameter.
|
|
209
|
+
*/
|
|
210
|
+
function(_e) {
|
|
211
|
+
if (this.cachedText_ !== this.model_.text) {
|
|
212
|
+
eventUtils.fire(new (eventUtils.get(eventUtils.BLOCK_CHANGE))(
|
|
213
|
+
this.block_, 'comment', null, this.cachedText_,
|
|
214
|
+
this.model_.text));
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
this.onInputWrapper_ = browserEvents.conditionalBind(
|
|
218
|
+
textarea, 'input', this,
|
|
219
|
+
/**
|
|
220
|
+
* @this {Comment}
|
|
221
|
+
* @param {Event} _e Unused event parameter.
|
|
222
|
+
*/
|
|
223
|
+
function(_e) {
|
|
224
|
+
this.model_.text = textarea.value;
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
setTimeout(textarea.focus.bind(textarea), 0);
|
|
228
|
+
|
|
229
|
+
return this.foreignObject_;
|
|
230
|
+
}
|
|
79
231
|
|
|
80
232
|
/**
|
|
81
|
-
*
|
|
82
|
-
* @
|
|
83
|
-
* @private
|
|
233
|
+
* Add or remove editability of the comment.
|
|
234
|
+
* @override
|
|
84
235
|
*/
|
|
85
|
-
|
|
236
|
+
updateEditable() {
|
|
237
|
+
super.updateEditable();
|
|
238
|
+
if (this.isVisible()) {
|
|
239
|
+
// Recreate the bubble with the correct UI.
|
|
240
|
+
this.disposeBubble_();
|
|
241
|
+
this.createBubble_();
|
|
242
|
+
}
|
|
243
|
+
}
|
|
86
244
|
|
|
87
245
|
/**
|
|
88
|
-
*
|
|
89
|
-
*
|
|
246
|
+
* Callback function triggered when the bubble has resized.
|
|
247
|
+
* Resize the text area accordingly.
|
|
90
248
|
* @private
|
|
91
249
|
*/
|
|
92
|
-
|
|
250
|
+
onBubbleResize_() {
|
|
251
|
+
if (!this.isVisible()) {
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
this.model_.size = this.bubble_.getBubbleSize();
|
|
255
|
+
this.resizeTextarea_();
|
|
256
|
+
}
|
|
93
257
|
|
|
94
258
|
/**
|
|
95
|
-
*
|
|
96
|
-
*
|
|
259
|
+
* Resizes the text area to match the size defined on the model (which is
|
|
260
|
+
* the size of the bubble).
|
|
97
261
|
* @private
|
|
98
262
|
*/
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
*/
|
|
110
|
-
Comment.prototype.drawIcon_ = function(group) {
|
|
111
|
-
// Circle.
|
|
112
|
-
dom.createSvgElement(
|
|
113
|
-
Svg.CIRCLE, {'class': 'blocklyIconShape', 'r': '8', 'cx': '8', 'cy': '8'},
|
|
114
|
-
group);
|
|
115
|
-
// Can't use a real '?' text character since different browsers and operating
|
|
116
|
-
// systems render it differently.
|
|
117
|
-
// Body of question mark.
|
|
118
|
-
dom.createSvgElement(
|
|
119
|
-
Svg.PATH, {
|
|
120
|
-
'class': 'blocklyIconSymbol',
|
|
121
|
-
'd': 'm6.8,10h2c0.003,-0.617 0.271,-0.962 0.633,-1.266 2.875,-2.405' +
|
|
122
|
-
'0.607,-5.534 -3.765,-3.874v1.7c3.12,-1.657 3.698,0.118 2.336,1.25' +
|
|
123
|
-
'-1.201,0.998 -1.201,1.528 -1.204,2.19z',
|
|
124
|
-
},
|
|
125
|
-
group);
|
|
126
|
-
// Dot of question mark.
|
|
127
|
-
dom.createSvgElement(
|
|
128
|
-
Svg.RECT, {
|
|
129
|
-
'class': 'blocklyIconSymbol',
|
|
130
|
-
'x': '6.8',
|
|
131
|
-
'y': '10.78',
|
|
132
|
-
'height': '2',
|
|
133
|
-
'width': '2',
|
|
134
|
-
},
|
|
135
|
-
group);
|
|
136
|
-
};
|
|
263
|
+
resizeTextarea_() {
|
|
264
|
+
const size = this.model_.size;
|
|
265
|
+
const doubleBorderWidth = 2 * Bubble.BORDER_WIDTH;
|
|
266
|
+
const widthMinusBorder = size.width - doubleBorderWidth;
|
|
267
|
+
const heightMinusBorder = size.height - doubleBorderWidth;
|
|
268
|
+
this.foreignObject_.setAttribute('width', widthMinusBorder);
|
|
269
|
+
this.foreignObject_.setAttribute('height', heightMinusBorder);
|
|
270
|
+
this.textarea_.style.width = (widthMinusBorder - 4) + 'px';
|
|
271
|
+
this.textarea_.style.height = (heightMinusBorder - 4) + 'px';
|
|
272
|
+
}
|
|
137
273
|
|
|
138
|
-
/**
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
* @private
|
|
142
|
-
*/
|
|
143
|
-
Comment.prototype.createEditor_ = function() {
|
|
144
|
-
/* Create the editor. Here's the markup that will be generated in
|
|
145
|
-
* editable mode:
|
|
146
|
-
<foreignObject x="8" y="8" width="164" height="164">
|
|
147
|
-
<body xmlns="http://www.w3.org/1999/xhtml" class="blocklyMinimalBody">
|
|
148
|
-
<textarea xmlns="http://www.w3.org/1999/xhtml"
|
|
149
|
-
class="blocklyCommentTextarea"
|
|
150
|
-
style="height: 164px; width: 164px;"></textarea>
|
|
151
|
-
</body>
|
|
152
|
-
</foreignObject>
|
|
153
|
-
* For non-editable mode see Warning.textToDom_.
|
|
274
|
+
/**
|
|
275
|
+
* Show or hide the comment bubble.
|
|
276
|
+
* @param {boolean} visible True if the bubble should be visible.
|
|
154
277
|
*/
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
textarea.setAttribute('dir', this.block_.RTL ? 'RTL' : 'LTR');
|
|
168
|
-
textarea.value = this.model_.text;
|
|
169
|
-
this.resizeTextarea_();
|
|
170
|
-
|
|
171
|
-
body.appendChild(textarea);
|
|
172
|
-
this.foreignObject_.appendChild(body);
|
|
173
|
-
|
|
174
|
-
// Ideally this would be hooked to the focus event for the comment.
|
|
175
|
-
// However doing so in Firefox swallows the cursor for unknown reasons.
|
|
176
|
-
// So this is hooked to mouseup instead. No big deal.
|
|
177
|
-
this.onMouseUpWrapper_ = browserEvents.conditionalBind(
|
|
178
|
-
textarea, 'mouseup', this, this.startEdit_, true, true);
|
|
179
|
-
// Don't zoom with mousewheel.
|
|
180
|
-
this.onWheelWrapper_ =
|
|
181
|
-
browserEvents.conditionalBind(textarea, 'wheel', this, function(e) {
|
|
182
|
-
e.stopPropagation();
|
|
183
|
-
});
|
|
184
|
-
this.onChangeWrapper_ = browserEvents.conditionalBind(
|
|
185
|
-
textarea, 'change', this,
|
|
186
|
-
/**
|
|
187
|
-
* @this {Comment}
|
|
188
|
-
* @param {Event} _e Unused event parameter.
|
|
189
|
-
*/
|
|
190
|
-
function(_e) {
|
|
191
|
-
if (this.cachedText_ !== this.model_.text) {
|
|
192
|
-
eventUtils.fire(new (eventUtils.get(eventUtils.BLOCK_CHANGE))(
|
|
193
|
-
this.block_, 'comment', null, this.cachedText_,
|
|
194
|
-
this.model_.text));
|
|
195
|
-
}
|
|
196
|
-
});
|
|
197
|
-
this.onInputWrapper_ = browserEvents.conditionalBind(
|
|
198
|
-
textarea, 'input', this,
|
|
199
|
-
/**
|
|
200
|
-
* @this {Comment}
|
|
201
|
-
* @param {Event} _e Unused event parameter.
|
|
202
|
-
*/
|
|
203
|
-
function(_e) {
|
|
204
|
-
this.model_.text = textarea.value;
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
setTimeout(textarea.focus.bind(textarea), 0);
|
|
208
|
-
|
|
209
|
-
return this.foreignObject_;
|
|
210
|
-
};
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Add or remove editability of the comment.
|
|
214
|
-
* @override
|
|
215
|
-
*/
|
|
216
|
-
Comment.prototype.updateEditable = function() {
|
|
217
|
-
Comment.superClass_.updateEditable.call(this);
|
|
218
|
-
if (this.isVisible()) {
|
|
219
|
-
// Recreate the bubble with the correct UI.
|
|
220
|
-
this.disposeBubble_();
|
|
221
|
-
this.createBubble_();
|
|
278
|
+
setVisible(visible) {
|
|
279
|
+
if (visible === this.isVisible()) {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
eventUtils.fire(new (eventUtils.get(eventUtils.BUBBLE_OPEN))(
|
|
283
|
+
this.block_, visible, 'comment'));
|
|
284
|
+
this.model_.pinned = visible;
|
|
285
|
+
if (visible) {
|
|
286
|
+
this.createBubble_();
|
|
287
|
+
} else {
|
|
288
|
+
this.disposeBubble_();
|
|
289
|
+
}
|
|
222
290
|
}
|
|
223
|
-
};
|
|
224
291
|
|
|
225
|
-
/**
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
292
|
+
/**
|
|
293
|
+
* Show the bubble. Handles deciding if it should be editable or not.
|
|
294
|
+
* @private
|
|
295
|
+
*/
|
|
296
|
+
createBubble_() {
|
|
297
|
+
if (!this.block_.isEditable() || userAgent.IE) {
|
|
298
|
+
// MSIE does not support foreignobject; textareas are impossible.
|
|
299
|
+
// https://docs.microsoft.com/en-us/openspecs/ie_standards/ms-svg/56e6e04c-7c8c-44dd-8100-bd745ee42034
|
|
300
|
+
// Always treat comments in IE as uneditable.
|
|
301
|
+
this.createNonEditableBubble_();
|
|
302
|
+
} else {
|
|
303
|
+
this.createEditableBubble_();
|
|
304
|
+
}
|
|
233
305
|
}
|
|
234
|
-
this.model_.size = this.bubble_.getBubbleSize();
|
|
235
|
-
this.resizeTextarea_();
|
|
236
|
-
};
|
|
237
306
|
|
|
238
|
-
/**
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
};
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* Show or hide the comment bubble.
|
|
256
|
-
* @param {boolean} visible True if the bubble should be visible.
|
|
257
|
-
*/
|
|
258
|
-
Comment.prototype.setVisible = function(visible) {
|
|
259
|
-
if (visible === this.isVisible()) {
|
|
260
|
-
return;
|
|
261
|
-
}
|
|
262
|
-
eventUtils.fire(new (eventUtils.get(eventUtils.BUBBLE_OPEN))(
|
|
263
|
-
this.block_, visible, 'comment'));
|
|
264
|
-
this.model_.pinned = visible;
|
|
265
|
-
if (visible) {
|
|
266
|
-
this.createBubble_();
|
|
267
|
-
} else {
|
|
268
|
-
this.disposeBubble_();
|
|
307
|
+
/**
|
|
308
|
+
* Show an editable bubble.
|
|
309
|
+
* @private
|
|
310
|
+
*/
|
|
311
|
+
createEditableBubble_() {
|
|
312
|
+
this.bubble_ = new Bubble(
|
|
313
|
+
/** @type {!WorkspaceSvg} */ (this.block_.workspace),
|
|
314
|
+
this.createEditor_(), this.block_.pathObject.svgPath,
|
|
315
|
+
/** @type {!Coordinate} */ (this.iconXY_), this.model_.size.width,
|
|
316
|
+
this.model_.size.height);
|
|
317
|
+
// Expose this comment's block's ID on its top-level SVG group.
|
|
318
|
+
this.bubble_.setSvgId(this.block_.id);
|
|
319
|
+
this.bubble_.registerResizeEvent(this.onBubbleResize_.bind(this));
|
|
320
|
+
this.applyColour();
|
|
269
321
|
}
|
|
270
|
-
};
|
|
271
322
|
|
|
272
|
-
/**
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
//
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
this.
|
|
323
|
+
/**
|
|
324
|
+
* Show a non-editable bubble.
|
|
325
|
+
* @private
|
|
326
|
+
* @suppress {checkTypes} Suppress `this` type mismatch.
|
|
327
|
+
*/
|
|
328
|
+
createNonEditableBubble_() {
|
|
329
|
+
// TODO (#2917): It would be great if the comment could support line breaks.
|
|
330
|
+
this.paragraphElement_ = Bubble.textToDom(this.block_.getCommentText());
|
|
331
|
+
this.bubble_ = Bubble.createNonEditableBubble(
|
|
332
|
+
this.paragraphElement_, /** @type {!BlockSvg} */ (this.block_),
|
|
333
|
+
/** @type {!Coordinate} */ (this.iconXY_));
|
|
334
|
+
this.applyColour();
|
|
284
335
|
}
|
|
285
|
-
};
|
|
286
|
-
|
|
287
|
-
/**
|
|
288
|
-
* Show an editable bubble.
|
|
289
|
-
* @private
|
|
290
|
-
*/
|
|
291
|
-
Comment.prototype.createEditableBubble_ = function() {
|
|
292
|
-
this.bubble_ = new Bubble(
|
|
293
|
-
/** @type {!WorkspaceSvg} */ (this.block_.workspace),
|
|
294
|
-
this.createEditor_(), this.block_.pathObject.svgPath,
|
|
295
|
-
/** @type {!Coordinate} */ (this.iconXY_), this.model_.size.width,
|
|
296
|
-
this.model_.size.height);
|
|
297
|
-
// Expose this comment's block's ID on its top-level SVG group.
|
|
298
|
-
this.bubble_.setSvgId(this.block_.id);
|
|
299
|
-
this.bubble_.registerResizeEvent(this.onBubbleResize_.bind(this));
|
|
300
|
-
this.applyColour();
|
|
301
|
-
};
|
|
302
|
-
|
|
303
|
-
/**
|
|
304
|
-
* Show a non-editable bubble.
|
|
305
|
-
* @private
|
|
306
|
-
* @suppress {checkTypes} Suppress `this` type mismatch.
|
|
307
|
-
*/
|
|
308
|
-
Comment.prototype.createNonEditableBubble_ = function() {
|
|
309
|
-
// TODO (#2917): It would be great if the comment could support line breaks.
|
|
310
|
-
this.paragraphElement_ = Bubble.textToDom(this.block_.getCommentText());
|
|
311
|
-
this.bubble_ = Bubble.createNonEditableBubble(
|
|
312
|
-
this.paragraphElement_, /** @type {!BlockSvg} */ (this.block_),
|
|
313
|
-
/** @type {!Coordinate} */ (this.iconXY_));
|
|
314
|
-
this.applyColour();
|
|
315
|
-
};
|
|
316
336
|
|
|
317
|
-
/**
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
337
|
+
/**
|
|
338
|
+
* Dispose of the bubble.
|
|
339
|
+
* @private
|
|
340
|
+
* @suppress {checkTypes} Suppress `this` type mismatch.
|
|
341
|
+
*/
|
|
342
|
+
disposeBubble_() {
|
|
343
|
+
if (this.onMouseUpWrapper_) {
|
|
344
|
+
browserEvents.unbind(this.onMouseUpWrapper_);
|
|
345
|
+
this.onMouseUpWrapper_ = null;
|
|
346
|
+
}
|
|
347
|
+
if (this.onWheelWrapper_) {
|
|
348
|
+
browserEvents.unbind(this.onWheelWrapper_);
|
|
349
|
+
this.onWheelWrapper_ = null;
|
|
350
|
+
}
|
|
351
|
+
if (this.onChangeWrapper_) {
|
|
352
|
+
browserEvents.unbind(this.onChangeWrapper_);
|
|
353
|
+
this.onChangeWrapper_ = null;
|
|
354
|
+
}
|
|
355
|
+
if (this.onInputWrapper_) {
|
|
356
|
+
browserEvents.unbind(this.onInputWrapper_);
|
|
357
|
+
this.onInputWrapper_ = null;
|
|
358
|
+
}
|
|
359
|
+
this.bubble_.dispose();
|
|
360
|
+
this.bubble_ = null;
|
|
361
|
+
this.textarea_ = null;
|
|
362
|
+
this.foreignObject_ = null;
|
|
363
|
+
this.paragraphElement_ = null;
|
|
338
364
|
}
|
|
339
|
-
this.bubble_.dispose();
|
|
340
|
-
this.bubble_ = null;
|
|
341
|
-
this.textarea_ = null;
|
|
342
|
-
this.foreignObject_ = null;
|
|
343
|
-
this.paragraphElement_ = null;
|
|
344
|
-
};
|
|
345
365
|
|
|
346
|
-
/**
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
366
|
+
/**
|
|
367
|
+
* Callback fired when an edit starts.
|
|
368
|
+
*
|
|
369
|
+
* Bring the comment to the top of the stack when clicked on. Also cache the
|
|
370
|
+
* current text so it can be used to fire a change event.
|
|
371
|
+
* @param {!Event} _e Mouse up event.
|
|
372
|
+
* @private
|
|
373
|
+
*/
|
|
374
|
+
startEdit_(_e) {
|
|
375
|
+
if (this.bubble_.promote()) {
|
|
376
|
+
// Since the act of moving this node within the DOM causes a loss of
|
|
377
|
+
// focus, we need to reapply the focus.
|
|
378
|
+
this.textarea_.focus();
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
this.cachedText_ = this.model_.text;
|
|
359
382
|
}
|
|
360
383
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
Comment.prototype.getBubbleSize = function() {
|
|
369
|
-
return this.model_.size;
|
|
370
|
-
};
|
|
384
|
+
/**
|
|
385
|
+
* Get the dimensions of this comment's bubble.
|
|
386
|
+
* @return {Size} Object with width and height properties.
|
|
387
|
+
*/
|
|
388
|
+
getBubbleSize() {
|
|
389
|
+
return this.model_.size;
|
|
390
|
+
}
|
|
371
391
|
|
|
372
|
-
/**
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
392
|
+
/**
|
|
393
|
+
* Size this comment's bubble.
|
|
394
|
+
* @param {number} width Width of the bubble.
|
|
395
|
+
* @param {number} height Height of the bubble.
|
|
396
|
+
*/
|
|
397
|
+
setBubbleSize(width, height) {
|
|
398
|
+
if (this.bubble_) {
|
|
399
|
+
this.bubble_.setBubbleSize(width, height);
|
|
400
|
+
} else {
|
|
401
|
+
this.model_.size.width = width;
|
|
402
|
+
this.model_.size.height = height;
|
|
403
|
+
}
|
|
383
404
|
}
|
|
384
|
-
};
|
|
385
405
|
|
|
386
|
-
/**
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
406
|
+
/**
|
|
407
|
+
* Update the comment's view to match the model.
|
|
408
|
+
* @package
|
|
409
|
+
*/
|
|
410
|
+
updateText() {
|
|
411
|
+
if (this.textarea_) {
|
|
412
|
+
this.textarea_.value = this.model_.text;
|
|
413
|
+
} else if (this.paragraphElement_) {
|
|
414
|
+
// Non-Editable mode.
|
|
415
|
+
// TODO (#2917): If 2917 gets added this will probably need to be updated.
|
|
416
|
+
this.paragraphElement_.firstChild.textContent = this.model_.text;
|
|
417
|
+
}
|
|
397
418
|
}
|
|
398
|
-
};
|
|
399
419
|
|
|
400
|
-
/**
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
}
|
|
420
|
+
/**
|
|
421
|
+
* Dispose of this comment.
|
|
422
|
+
*
|
|
423
|
+
* If you want to receive a comment "delete" event (newValue: null), then this
|
|
424
|
+
* should not be called directly. Instead call block.setCommentText(null);
|
|
425
|
+
*/
|
|
426
|
+
dispose() {
|
|
427
|
+
this.block_.comment = null;
|
|
428
|
+
Icon.prototype.dispose.call(this);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
410
431
|
|
|
411
432
|
/**
|
|
412
433
|
* CSS for block comment. See css.js for use.
|
|
413
434
|
*/
|
|
414
435
|
Css.register(`
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
436
|
+
.blocklyCommentTextarea {
|
|
437
|
+
background-color: #fef49c;
|
|
438
|
+
border: 0;
|
|
439
|
+
display: block;
|
|
440
|
+
margin: 0;
|
|
441
|
+
outline: 0;
|
|
442
|
+
padding: 3px;
|
|
443
|
+
resize: none;
|
|
444
|
+
text-overflow: hidden;
|
|
445
|
+
}
|
|
425
446
|
`);
|
|
426
447
|
|
|
427
448
|
exports.Comment = Comment;
|