scratch-blocks 0.1.0-prerelease.20211005172512

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (243) hide show
  1. package/LICENSE +177 -0
  2. package/README.md +23 -0
  3. package/TRADEMARK +1 -0
  4. package/blockly_compressed_horizontal.js +2253 -0
  5. package/blockly_compressed_vertical.js +2281 -0
  6. package/blockly_uncompressed_horizontal.js +1210 -0
  7. package/blockly_uncompressed_vertical.js +1210 -0
  8. package/blocks_common/colour.js +61 -0
  9. package/blocks_common/math.js +154 -0
  10. package/blocks_common/matrix.js +54 -0
  11. package/blocks_common/note.js +57 -0
  12. package/blocks_common/text.js +56 -0
  13. package/blocks_compressed.js +36 -0
  14. package/blocks_compressed_horizontal.js +58 -0
  15. package/blocks_compressed_vertical.js +207 -0
  16. package/blocks_horizontal/control.js +207 -0
  17. package/blocks_horizontal/default_toolbox.js +139 -0
  18. package/blocks_horizontal/event.js +185 -0
  19. package/blocks_horizontal/wedo.js +316 -0
  20. package/blocks_vertical/control.js +531 -0
  21. package/blocks_vertical/data.js +670 -0
  22. package/blocks_vertical/default_toolbox.js +564 -0
  23. package/blocks_vertical/event.js +328 -0
  24. package/blocks_vertical/extensions.js +294 -0
  25. package/blocks_vertical/looks.js +589 -0
  26. package/blocks_vertical/motion.js +584 -0
  27. package/blocks_vertical/operators.js +470 -0
  28. package/blocks_vertical/procedures.js +971 -0
  29. package/blocks_vertical/sensing.js +539 -0
  30. package/blocks_vertical/sound.js +245 -0
  31. package/blocks_vertical/vertical_extensions.js +264 -0
  32. package/build/gen_blocks.js +1 -0
  33. package/build/test_expect.js +1 -0
  34. package/build/test_input.js +1 -0
  35. package/build.py +630 -0
  36. package/cleanup.sh +101 -0
  37. package/core/block.js +1811 -0
  38. package/core/block_animations.js +107 -0
  39. package/core/block_drag_surface.js +299 -0
  40. package/core/block_dragger.js +421 -0
  41. package/core/block_events.js +531 -0
  42. package/core/block_render_svg_horizontal.js +890 -0
  43. package/core/block_render_svg_vertical.js +1732 -0
  44. package/core/block_svg.js +1314 -0
  45. package/core/blockly.js +622 -0
  46. package/core/blocks.js +37 -0
  47. package/core/bubble.js +664 -0
  48. package/core/bubble_dragger.js +285 -0
  49. package/core/colours.js +147 -0
  50. package/core/comment.js +293 -0
  51. package/core/comment_events.js +539 -0
  52. package/core/connection.js +766 -0
  53. package/core/connection_db.js +300 -0
  54. package/core/constants.js +387 -0
  55. package/core/contextmenu.js +519 -0
  56. package/core/css.js +1350 -0
  57. package/core/data_category.js +490 -0
  58. package/core/dragged_connection_manager.js +260 -0
  59. package/core/dropdowndiv.js +408 -0
  60. package/core/events.js +429 -0
  61. package/core/events_abstract.js +113 -0
  62. package/core/extensions.js +450 -0
  63. package/core/field.js +807 -0
  64. package/core/field_angle.js +398 -0
  65. package/core/field_checkbox.js +133 -0
  66. package/core/field_colour.js +253 -0
  67. package/core/field_colour_slider.js +386 -0
  68. package/core/field_date.js +353 -0
  69. package/core/field_dropdown.js +483 -0
  70. package/core/field_iconmenu.js +307 -0
  71. package/core/field_image.js +193 -0
  72. package/core/field_label.js +136 -0
  73. package/core/field_label_serializable.js +125 -0
  74. package/core/field_matrix.js +566 -0
  75. package/core/field_note.js +850 -0
  76. package/core/field_number.js +366 -0
  77. package/core/field_numberdropdown.js +77 -0
  78. package/core/field_textdropdown.js +164 -0
  79. package/core/field_textinput.js +675 -0
  80. package/core/field_textinput_removable.js +105 -0
  81. package/core/field_variable.js +385 -0
  82. package/core/field_variable_getter.js +185 -0
  83. package/core/field_vertical_separator.js +161 -0
  84. package/core/flyout_base.js +923 -0
  85. package/core/flyout_button.js +322 -0
  86. package/core/flyout_dragger.js +83 -0
  87. package/core/flyout_extension_category_header.js +159 -0
  88. package/core/flyout_horizontal.js +475 -0
  89. package/core/flyout_vertical.js +770 -0
  90. package/core/generator.js +426 -0
  91. package/core/gesture.js +1011 -0
  92. package/core/grid.js +227 -0
  93. package/core/icon.js +205 -0
  94. package/core/inject.js +491 -0
  95. package/core/input.js +285 -0
  96. package/core/insertion_marker_manager.js +678 -0
  97. package/core/msg.js +62 -0
  98. package/core/mutator.js +426 -0
  99. package/core/names.js +198 -0
  100. package/core/options.js +244 -0
  101. package/core/procedures.js +577 -0
  102. package/core/rendered_connection.js +417 -0
  103. package/core/scratch_block_comment.js +653 -0
  104. package/core/scratch_blocks_utils.js +244 -0
  105. package/core/scratch_bubble.js +696 -0
  106. package/core/scratch_events.js +131 -0
  107. package/core/scratch_msgs.js +85 -0
  108. package/core/scrollbar.js +875 -0
  109. package/core/toolbox.js +801 -0
  110. package/core/tooltip.js +337 -0
  111. package/core/touch.js +226 -0
  112. package/core/trashcan.js +343 -0
  113. package/core/ui_events.js +91 -0
  114. package/core/ui_menu_utils.js +68 -0
  115. package/core/utils.js +948 -0
  116. package/core/variable_events.js +259 -0
  117. package/core/variable_map.js +415 -0
  118. package/core/variable_model.js +116 -0
  119. package/core/variables.js +674 -0
  120. package/core/warning.js +199 -0
  121. package/core/widgetdiv.js +344 -0
  122. package/core/workspace.js +673 -0
  123. package/core/workspace_audio.js +170 -0
  124. package/core/workspace_comment.js +432 -0
  125. package/core/workspace_comment_render_svg.js +723 -0
  126. package/core/workspace_comment_svg.js +611 -0
  127. package/core/workspace_drag_surface_svg.js +195 -0
  128. package/core/workspace_dragger.js +132 -0
  129. package/core/workspace_svg.js +2267 -0
  130. package/core/xml.js +919 -0
  131. package/core/zoom_controls.js +301 -0
  132. package/dist/horizontal.js +222 -0
  133. package/dist/vertical.js +222 -0
  134. package/dist/web/horizontal.js +232 -0
  135. package/dist/web/vertical.js +232 -0
  136. package/i18n/common.py +234 -0
  137. package/i18n/create_messages.py +165 -0
  138. package/i18n/create_scratch_msgs.js +69 -0
  139. package/i18n/dedup_json.py +73 -0
  140. package/i18n/js_to_json.js +46 -0
  141. package/i18n/js_to_json.py +136 -0
  142. package/i18n/json_to_js.js +52 -0
  143. package/i18n/json_to_js.py +185 -0
  144. package/i18n/sync_translations.sh +17 -0
  145. package/i18n/sync_tx_translations.js +121 -0
  146. package/i18n/test_scratch_msgs.js +87 -0
  147. package/i18n/tests.py +47 -0
  148. package/i18n/xliff_to_json.py +232 -0
  149. package/local_build.sh +70 -0
  150. package/media/1x1.gif +0 -0
  151. package/media/click.mp3 +0 -0
  152. package/media/click.ogg +0 -0
  153. package/media/click.wav +0 -0
  154. package/media/comment-arrow-down.svg +10 -0
  155. package/media/comment-arrow-up.svg +10 -0
  156. package/media/delete-x.svg +10 -0
  157. package/media/delete.mp3 +0 -0
  158. package/media/delete.ogg +0 -0
  159. package/media/delete.wav +0 -0
  160. package/media/dropdown-arrow-dark.svg +1 -0
  161. package/media/dropdown-arrow.svg +1 -0
  162. package/media/extensions/microbit-block-icon.svg +130 -0
  163. package/media/extensions/music-block-icon.svg +17 -0
  164. package/media/extensions/pen-block-icon.svg +19 -0
  165. package/media/extensions/wedo2-block-icon.svg +36 -0
  166. package/media/eyedropper.svg +22 -0
  167. package/media/green-flag.svg +17 -0
  168. package/media/handclosed.cur +0 -0
  169. package/media/handdelete.cur +0 -0
  170. package/media/handopen.cur +0 -0
  171. package/media/icons/arrow.svg +12 -0
  172. package/media/icons/arrow_button.svg +1 -0
  173. package/media/icons/control_forever.svg +1 -0
  174. package/media/icons/control_repeat.svg +1 -0
  175. package/media/icons/control_stop.svg +1 -0
  176. package/media/icons/control_wait.svg +1 -0
  177. package/media/icons/event_broadcast_blue.svg +1 -0
  178. package/media/icons/event_broadcast_coral.svg +1 -0
  179. package/media/icons/event_broadcast_green.svg +1 -0
  180. package/media/icons/event_broadcast_magenta.svg +1 -0
  181. package/media/icons/event_broadcast_orange.svg +1 -0
  182. package/media/icons/event_broadcast_purple.svg +1 -0
  183. package/media/icons/event_when-broadcast-received_blue.svg +1 -0
  184. package/media/icons/event_when-broadcast-received_coral.svg +1 -0
  185. package/media/icons/event_when-broadcast-received_green.svg +1 -0
  186. package/media/icons/event_when-broadcast-received_magenta.svg +1 -0
  187. package/media/icons/event_when-broadcast-received_orange.svg +1 -0
  188. package/media/icons/event_when-broadcast-received_purple.svg +1 -0
  189. package/media/icons/event_whenflagclicked.svg +1 -0
  190. package/media/icons/remove.svg +19 -0
  191. package/media/icons/set-led_blue.svg +1 -0
  192. package/media/icons/set-led_coral.svg +1 -0
  193. package/media/icons/set-led_green.svg +1 -0
  194. package/media/icons/set-led_magenta.svg +1 -0
  195. package/media/icons/set-led_mystery.svg +1 -0
  196. package/media/icons/set-led_orange.svg +1 -0
  197. package/media/icons/set-led_purple.svg +1 -0
  198. package/media/icons/set-led_white.svg +1 -0
  199. package/media/icons/set-led_yellow.svg +1 -0
  200. package/media/icons/wedo_motor-clockwise.svg +1 -0
  201. package/media/icons/wedo_motor-counterclockwise.svg +1 -0
  202. package/media/icons/wedo_motor-speed_fast.svg +1 -0
  203. package/media/icons/wedo_motor-speed_med.svg +1 -0
  204. package/media/icons/wedo_motor-speed_slow.svg +1 -0
  205. package/media/icons/wedo_when-distance_close.svg +1 -0
  206. package/media/icons/wedo_when-tilt-backward.svg +1 -0
  207. package/media/icons/wedo_when-tilt-forward.svg +1 -0
  208. package/media/icons/wedo_when-tilt-left.svg +1 -0
  209. package/media/icons/wedo_when-tilt-right.svg +1 -0
  210. package/media/icons/wedo_when-tilt.svg +1 -0
  211. package/media/repeat.svg +18 -0
  212. package/media/rotate-left.svg +1 -0
  213. package/media/rotate-right.svg +1 -0
  214. package/media/sprites.png +0 -0
  215. package/media/sprites.svg +74 -0
  216. package/media/status-not-ready.svg +13 -0
  217. package/media/status-ready.svg +13 -0
  218. package/media/zoom-in.svg +1 -0
  219. package/media/zoom-out.svg +1 -0
  220. package/media/zoom-reset.svg +1 -0
  221. package/msg/js/en.js +290 -0
  222. package/msg/json/en.json +285 -0
  223. package/msg/messages.js +353 -0
  224. package/msg/scratch_msgs.js +21247 -0
  225. package/package.json +52 -0
  226. package/pull_from_blockly.sh +151 -0
  227. package/renovate.json5 +15 -0
  228. package/shim/blockly_compressed_horizontal-blocks_compressed.js +1 -0
  229. package/shim/blockly_compressed_horizontal.Blockly.js +1 -0
  230. package/shim/blockly_compressed_horizontal.goog.js +1 -0
  231. package/shim/blockly_compressed_horizontal.js +1 -0
  232. package/shim/blockly_compressed_vertical-blocks_compressed.js +1 -0
  233. package/shim/blockly_compressed_vertical.Blockly.js +1 -0
  234. package/shim/blockly_compressed_vertical.goog.js +1 -0
  235. package/shim/blockly_compressed_vertical.js +1 -0
  236. package/shim/blocks_compressed_horizontal-blockly_compressed_horizontal-messages.js +1 -0
  237. package/shim/blocks_compressed_horizontal.js +1 -0
  238. package/shim/blocks_compressed_vertical-blockly_compressed_vertical-messages.js +1 -0
  239. package/shim/blocks_compressed_vertical.js +1 -0
  240. package/shim/gh-pages.js +1 -0
  241. package/shim/horizontal.js +1 -0
  242. package/shim/index.js +17 -0
  243. package/shim/vertical.js +1 -0
@@ -0,0 +1,611 @@
1
+ /**
2
+ * @license
3
+ * Visual Blocks Editor
4
+ *
5
+ * Copyright 2017 Google Inc.
6
+ * https://developers.google.com/blockly/
7
+ *
8
+ * Licensed under the Apache License, Version 2.0 (the "License");
9
+ * you may not use this file except in compliance with the License.
10
+ * You may obtain a copy of the License at
11
+ *
12
+ * http://www.apache.org/licenses/LICENSE-2.0
13
+ *
14
+ * Unless required by applicable law or agreed to in writing, software
15
+ * distributed under the License is distributed on an "AS IS" BASIS,
16
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ * See the License for the specific language governing permissions and
18
+ * limitations under the License.
19
+ */
20
+
21
+ /**
22
+ * @fileoverview Object representing a code comment on a rendered workspace.
23
+ * @author fenichel@google.com (Rachel Fenichel)
24
+ */
25
+ 'use strict';
26
+
27
+ goog.provide('Blockly.WorkspaceCommentSvg');
28
+
29
+ goog.require('Blockly.Events.CommentCreate');
30
+ goog.require('Blockly.Events.CommentDelete');
31
+ goog.require('Blockly.Events.CommentMove');
32
+ goog.require('Blockly.WorkspaceComment');
33
+
34
+
35
+ /**
36
+ * Class for a workspace comment's SVG representation.
37
+ * @param {!Blockly.Workspace} workspace The block's workspace.
38
+ * @param {string} content The content of this workspace comment.
39
+ * @param {number} height Height of the comment.
40
+ * @param {number} width Width of the comment.
41
+ * @param {boolean} minimized Whether this comment is minimized.
42
+ * @param {string=} opt_id Optional ID. Use this ID if provided, otherwise
43
+ * create a new ID.
44
+ * @extends {Blockly.WorkspaceComment}
45
+ * @constructor
46
+ */
47
+ Blockly.WorkspaceCommentSvg = function(workspace, content, height, width, minimized,
48
+ opt_id) {
49
+ // Create core elements for the block.
50
+ /**
51
+ * @type {SVGElement}
52
+ * @private
53
+ */
54
+ this.svgGroup_ = Blockly.utils.createSvgElement(
55
+ 'g', {}, null);
56
+ this.svgGroup_.translate_ = '';
57
+
58
+ this.svgRect_ = Blockly.utils.createSvgElement(
59
+ 'rect',
60
+ {
61
+ 'class': 'scratchCommentRect scratchWorkspaceCommentBorder',
62
+ 'x': 0,
63
+ 'y': 0,
64
+ 'rx': 4 * Blockly.WorkspaceCommentSvg.BORDER_WIDTH,
65
+ 'ry': 4 * Blockly.WorkspaceCommentSvg.BORDER_WIDTH
66
+ });
67
+ this.svgGroup_.appendChild(this.svgRect_);
68
+
69
+
70
+ /**
71
+ * Whether the comment is rendered onscreen and is a part of the DOM.
72
+ * @type {boolean}
73
+ * @private
74
+ */
75
+ this.rendered_ = false;
76
+
77
+ /**
78
+ * Whether to move the comment to the drag surface when it is dragged.
79
+ * True if it should move, false if it should be translated directly.
80
+ * @type {boolean}
81
+ * @private
82
+ */
83
+ this.useDragSurface_ =
84
+ Blockly.utils.is3dSupported() && !!workspace.blockDragSurface_;
85
+
86
+ Blockly.WorkspaceCommentSvg.superClass_.constructor.call(this,
87
+ workspace, content, height, width, minimized, opt_id);
88
+
89
+ this.render();
90
+ }; goog.inherits(Blockly.WorkspaceCommentSvg, Blockly.WorkspaceComment);
91
+
92
+ /**
93
+ * The width and height to use to size a workspace comment when it is first
94
+ * added, before it has been edited by the user.
95
+ * @type {number}
96
+ * @package
97
+ */
98
+ Blockly.WorkspaceCommentSvg.DEFAULT_SIZE = 200;
99
+
100
+ /**
101
+ * Dispose of this comment.
102
+ * @package
103
+ */
104
+ Blockly.WorkspaceCommentSvg.prototype.dispose = function() {
105
+ if (!this.workspace) {
106
+ // The comment has already been deleted.
107
+ return;
108
+ }
109
+ // If this comment is being deleted, unlink the mouse events.
110
+ if (Blockly.selected == this) {
111
+ this.unselect();
112
+ this.workspace.cancelCurrentGesture();
113
+ }
114
+
115
+ if (Blockly.Events.isEnabled()) {
116
+ Blockly.Events.fire(new Blockly.Events.CommentDelete(this));
117
+ }
118
+
119
+ goog.dom.removeNode(this.svgGroup_);
120
+ // Sever JavaScript to DOM connections.
121
+ this.svgGroup_ = null;
122
+ this.svgRect_ = null;
123
+ // Dispose of any rendered components
124
+ this.disposeInternal_();
125
+
126
+ Blockly.Events.disable();
127
+ Blockly.WorkspaceCommentSvg.superClass_.dispose.call(this);
128
+ Blockly.Events.enable();
129
+ };
130
+
131
+ /**
132
+ * Create and initialize the SVG representation of a workspace comment.
133
+ * May be called more than once.
134
+ * @package
135
+ */
136
+ Blockly.WorkspaceCommentSvg.prototype.initSvg = function() {
137
+ goog.asserts.assert(this.workspace.rendered, 'Workspace is headless.');
138
+ if (!this.workspace.options.readOnly && !this.eventsInit_) {
139
+ Blockly.bindEventWithChecks_(
140
+ this.svgRectTarget_, 'mousedown', this, this.pathMouseDown_);
141
+ Blockly.bindEventWithChecks_(
142
+ this.svgHandleTarget_, 'mousedown', this, this.pathMouseDown_);
143
+ }
144
+ this.eventsInit_ = true;
145
+
146
+ this.updateMovable();
147
+ if (!this.getSvgRoot().parentNode) {
148
+ this.workspace.getBubbleCanvas().appendChild(this.getSvgRoot());
149
+ }
150
+ };
151
+
152
+ /**
153
+ * Handle a mouse-down on an SVG comment.
154
+ * @param {!Event} e Mouse down event or touch start event.
155
+ * @private
156
+ */
157
+ Blockly.WorkspaceCommentSvg.prototype.pathMouseDown_ = function(e) {
158
+ var gesture = this.workspace.getGesture(e);
159
+ if (gesture) {
160
+ gesture.handleBubbleStart(e, this);
161
+ }
162
+ };
163
+
164
+ /**
165
+ * Show the context menu for this workspace comment.
166
+ * @param {!Event} e Mouse event.
167
+ * @private
168
+ */
169
+ Blockly.WorkspaceCommentSvg.prototype.showContextMenu_ = function(e) {
170
+ if (this.workspace.options.readOnly) {
171
+ return;
172
+ }
173
+ // Save the current workspace comment in a variable for use in closures.
174
+ var comment = this;
175
+ var menuOptions = [];
176
+
177
+ if (this.isDeletable() && this.isMovable()) {
178
+ menuOptions.push(Blockly.ContextMenu.commentDuplicateOption(comment));
179
+ menuOptions.push(Blockly.ContextMenu.commentDeleteOption(comment));
180
+ }
181
+
182
+ Blockly.ContextMenu.show(e, menuOptions, this.RTL);
183
+ };
184
+
185
+ /**
186
+ * Select this comment. Highlight it visually.
187
+ * @package
188
+ */
189
+ Blockly.WorkspaceCommentSvg.prototype.select = function() {
190
+ if (Blockly.selected == this) {
191
+ return;
192
+ }
193
+ var oldId = null;
194
+ if (Blockly.selected) {
195
+ oldId = Blockly.selected.id;
196
+ // Unselect any previously selected block or comment.
197
+ Blockly.Events.disable();
198
+ try {
199
+ Blockly.selected.unselect();
200
+ } finally {
201
+ Blockly.Events.enable();
202
+ }
203
+ }
204
+ var event = new Blockly.Events.Ui(null, 'selected', oldId, this.id);
205
+ event.workspaceId = this.workspace.id;
206
+ Blockly.Events.fire(event);
207
+ Blockly.selected = this;
208
+ this.addSelect();
209
+ };
210
+
211
+ /**
212
+ * Unselect this comment. Remove its highlighting.
213
+ * @package
214
+ */
215
+ Blockly.WorkspaceCommentSvg.prototype.unselect = function() {
216
+ if (Blockly.selected != this) {
217
+ return;
218
+ }
219
+ var event = new Blockly.Events.Ui(null, 'selected', this.id, null);
220
+ event.workspaceId = this.workspace.id;
221
+ Blockly.Events.fire(event);
222
+ Blockly.selected = null;
223
+ this.removeSelect();
224
+ };
225
+
226
+ /**
227
+ * Select this comment. Highlight it visually.
228
+ * @package
229
+ */
230
+ Blockly.WorkspaceCommentSvg.prototype.addSelect = function() {
231
+ Blockly.utils.addClass(
232
+ /** @type {!Element} */ (this.svgGroup_), 'blocklySelected');
233
+ this.setFocus();
234
+ };
235
+
236
+ /**
237
+ * Unselect this comment. Remove its highlighting.
238
+ * @package
239
+ */
240
+ Blockly.WorkspaceCommentSvg.prototype.removeSelect = function() {
241
+ Blockly.utils.removeClass(
242
+ /** @type {!Element} */ (this.svgGroup_), 'blocklySelected');
243
+ this.blurFocus();
244
+ };
245
+
246
+ /**
247
+ * Focus this comment. Highlight it visually.
248
+ * @package
249
+ */
250
+ Blockly.WorkspaceCommentSvg.prototype.addFocus = function() {
251
+ Blockly.utils.addClass(
252
+ /** @type {!Element} */ (this.svgGroup_), 'blocklyFocused');
253
+ };
254
+
255
+ /**
256
+ * Unfocus this comment. Remove its highlighting.
257
+ * @package
258
+ */
259
+ Blockly.WorkspaceCommentSvg.prototype.removeFocus = function() {
260
+ Blockly.utils.removeClass(
261
+ /** @type {!Element} */ (this.svgGroup_), 'blocklyFocused');
262
+ };
263
+
264
+ /**
265
+ * Return the coordinates of the top-left corner of this comment relative to the
266
+ * drawing surface's origin (0,0), in workspace units.
267
+ * If the comment is on the workspace, (0, 0) is the origin of the workspace
268
+ * coordinate system.
269
+ * This does not change with workspace scale.
270
+ * @return {!goog.math.Coordinate} Object with .x and .y properties in
271
+ * workspace coordinates.
272
+ * @package
273
+ */
274
+ Blockly.WorkspaceCommentSvg.prototype.getRelativeToSurfaceXY = function() {
275
+ var x = 0;
276
+ var y = 0;
277
+
278
+ var dragSurfaceGroup = this.useDragSurface_ ?
279
+ this.workspace.blockDragSurface_.getGroup() : null;
280
+
281
+ var element = this.getSvgRoot();
282
+ if (element) {
283
+ do {
284
+ // Loop through this comment and every parent.
285
+ var xy = Blockly.utils.getRelativeXY(element);
286
+ x += xy.x;
287
+ y += xy.y;
288
+ // If this element is the current element on the drag surface, include
289
+ // the translation of the drag surface itself.
290
+ if (this.useDragSurface_ &&
291
+ this.workspace.blockDragSurface_.getCurrentBlock() == element) {
292
+ var surfaceTranslation =
293
+ this.workspace.blockDragSurface_.getSurfaceTranslation();
294
+ x += surfaceTranslation.x;
295
+ y += surfaceTranslation.y;
296
+ }
297
+ element = element.parentNode;
298
+ } while (element && element != this.workspace.getBubbleCanvas() &&
299
+ element != dragSurfaceGroup);
300
+ }
301
+ this.xy_ = new goog.math.Coordinate(x, y);
302
+ return this.xy_;
303
+ };
304
+
305
+ /**
306
+ * Move a comment by a relative offset.
307
+ * @param {number} dx Horizontal offset, in workspace units.
308
+ * @param {number} dy Vertical offset, in workspace units.
309
+ * @package
310
+ */
311
+ Blockly.WorkspaceCommentSvg.prototype.moveBy = function(dx, dy) {
312
+ var event = new Blockly.Events.CommentMove(this);
313
+ // TODO: Do I need to look up the relative to surface XY position here?
314
+ var xy = this.getRelativeToSurfaceXY();
315
+ this.translate(xy.x + dx, xy.y + dy);
316
+ event.recordNew();
317
+ Blockly.Events.fire(event);
318
+ this.workspace.resizeContents();
319
+ };
320
+
321
+ /**
322
+ * Transforms a comment by setting the translation on the transform attribute
323
+ * of the block's SVG.
324
+ * @param {number} x The x coordinate of the translation in workspace units.
325
+ * @param {number} y The y coordinate of the translation in workspace units.
326
+ * @package
327
+ */
328
+ Blockly.WorkspaceCommentSvg.prototype.translate = function(x, y) {
329
+ this.xy_ = new goog.math.Coordinate(x, y);
330
+ this.getSvgRoot().setAttribute('transform',
331
+ 'translate(' + x + ',' + y + ')');
332
+ };
333
+
334
+ /**
335
+ * Move this comment to its workspace's drag surface, accounting for positioning.
336
+ * Generally should be called at the same time as setDragging(true).
337
+ * Does nothing if useDragSurface_ is false.
338
+ * @private
339
+ */
340
+ Blockly.WorkspaceCommentSvg.prototype.moveToDragSurface_ = function() {
341
+ if (!this.useDragSurface_) {
342
+ return;
343
+ }
344
+ // The translation for drag surface blocks,
345
+ // is equal to the current relative-to-surface position,
346
+ // to keep the position in sync as it move on/off the surface.
347
+ // This is in workspace coordinates.
348
+ var xy = this.getRelativeToSurfaceXY();
349
+ this.clearTransformAttributes_();
350
+ this.workspace.blockDragSurface_.translateSurface(xy.x, xy.y);
351
+ // Execute the move on the top-level SVG component
352
+ this.workspace.blockDragSurface_.setBlocksAndShow(this.getSvgRoot());
353
+ };
354
+
355
+ /**
356
+ * Move this comment back to the workspace block canvas.
357
+ * Generally should be called at the same time as setDragging(false).
358
+ * Does nothing if useDragSurface_ is false.
359
+ * @param {!goog.math.Coordinate} newXY The position the comment should take on
360
+ * on the workspace canvas, in workspace coordinates.
361
+ * @private
362
+ */
363
+ Blockly.WorkspaceCommentSvg.prototype.moveOffDragSurface_ = function(newXY) {
364
+ if (!this.useDragSurface_) {
365
+ return;
366
+ }
367
+ // Translate to current position, turning off 3d.
368
+ this.translate(newXY.x, newXY.y);
369
+ this.workspace.blockDragSurface_.clearAndHide(this.workspace.getCanvas());
370
+ };
371
+
372
+ /**
373
+ * Move this comment during a drag, taking into account whether we are using a
374
+ * drag surface to translate blocks.
375
+ * @param {?Blockly.BlockDragSurfaceSvg} dragSurface The surface that carries
376
+ * rendered items during a drag, or null if no drag surface is in use.
377
+ * @param {!goog.math.Coordinate} newLoc The location to translate to, in
378
+ * workspace coordinates.
379
+ * @package
380
+ */
381
+ Blockly.WorkspaceCommentSvg.prototype.moveDuringDrag = function(dragSurface, newLoc) {
382
+ if (dragSurface) {
383
+ dragSurface.translateSurface(newLoc.x, newLoc.y);
384
+ } else {
385
+ this.svgGroup_.translate_ = 'translate(' + newLoc.x + ',' + newLoc.y + ')';
386
+ this.svgGroup_.setAttribute('transform',
387
+ this.svgGroup_.translate_ + this.svgGroup_.skew_);
388
+ }
389
+ };
390
+
391
+ /**
392
+ * Move the bubble group to the specified location in workspace coordinates.
393
+ * @param {number} x The x position to move to.
394
+ * @param {number} y The y position to move to.
395
+ * @package
396
+ */
397
+ Blockly.WorkspaceCommentSvg.prototype.moveTo = function(x, y) {
398
+ this.translate(x, y);
399
+ };
400
+
401
+ /**
402
+ * Clear the comment of transform="..." attributes.
403
+ * Used when the comment is switching from 3d to 2d transform or vice versa.
404
+ * @private
405
+ */
406
+ Blockly.WorkspaceCommentSvg.prototype.clearTransformAttributes_ = function() {
407
+ Blockly.utils.removeAttribute(this.getSvgRoot(), 'transform');
408
+ };
409
+
410
+ /**
411
+ * Return the rendered size of the comment or the stored size if the comment is
412
+ * not rendered. This differs from getHeightWidth in the behavior of rendered
413
+ * minimized comments. This function reports the actual size of the minimized
414
+ * comment instead of the full sized comment height/width.
415
+ * @return {!{height: number, width: number}} Object with height and width
416
+ * properties in workspace units.
417
+ * @package
418
+ */
419
+ Blockly.WorkspaceCommentSvg.prototype.getBubbleSize = function() {
420
+ if (this.rendered_) {
421
+ return {
422
+ width: parseInt(this.svgRect_.getAttribute('width')),
423
+ height: parseInt(this.svgRect_.getAttribute('height'))
424
+ };
425
+ } else {
426
+ this.getHeightWidth();
427
+ }
428
+ };
429
+
430
+ /**
431
+ * Returns the coordinates of a bounding box describing the dimensions of this
432
+ * comment.
433
+ * Coordinate system: workspace coordinates.
434
+ * @return {!{topLeft: goog.math.Coordinate, bottomRight: goog.math.Coordinate}}
435
+ * Object with top left and bottom right coordinates of the bounding box.
436
+ * @package
437
+ */
438
+ Blockly.WorkspaceCommentSvg.prototype.getBoundingRectangle = function() {
439
+ var blockXY = this.getRelativeToSurfaceXY();
440
+ var commentBounds = this.getHeightWidth();
441
+ var topLeft;
442
+ var bottomRight;
443
+ if (this.RTL) {
444
+ topLeft = new goog.math.Coordinate(blockXY.x - (commentBounds.width),
445
+ blockXY.y);
446
+ // Add the width of the tab/puzzle piece knob to the x coordinate
447
+ // since X is the corner of the rectangle, not the whole puzzle piece.
448
+ bottomRight = new goog.math.Coordinate(blockXY.x,
449
+ blockXY.y + commentBounds.height);
450
+ } else {
451
+ // Subtract the width of the tab/puzzle piece knob to the x coordinate
452
+ // since X is the corner of the rectangle, not the whole puzzle piece.
453
+ topLeft = new goog.math.Coordinate(blockXY.x, blockXY.y);
454
+ bottomRight = new goog.math.Coordinate(blockXY.x + commentBounds.width,
455
+ blockXY.y + commentBounds.height);
456
+ }
457
+ return {topLeft: topLeft, bottomRight: bottomRight};
458
+ };
459
+
460
+ /**
461
+ * Add or remove the UI indicating if this comment is movable or not.
462
+ * @package
463
+ */
464
+ Blockly.WorkspaceCommentSvg.prototype.updateMovable = function() {
465
+ if (this.isMovable()) {
466
+ Blockly.utils.addClass(
467
+ /** @type {!Element} */ (this.svgGroup_), 'blocklyDraggable');
468
+ } else {
469
+ Blockly.utils.removeClass(
470
+ /** @type {!Element} */ (this.svgGroup_), 'blocklyDraggable');
471
+ }
472
+ };
473
+
474
+ /**
475
+ * Set whether this comment is movable or not.
476
+ * @param {boolean} movable True if movable.
477
+ * @package
478
+ */
479
+ Blockly.WorkspaceCommentSvg.prototype.setMovable = function(movable) {
480
+ Blockly.WorkspaceCommentSvg.superClass_.setMovable.call(this, movable);
481
+ this.updateMovable();
482
+ };
483
+
484
+ /**
485
+ * Recursively adds or removes the dragging class to this node and its children.
486
+ * @param {boolean} adding True if adding, false if removing.
487
+ * @package
488
+ */
489
+ Blockly.WorkspaceCommentSvg.prototype.setDragging = function(adding) {
490
+ if (adding) {
491
+ var group = this.getSvgRoot();
492
+ group.translate_ = '';
493
+ group.skew_ = '';
494
+ Blockly.utils.addClass(
495
+ /** @type {!Element} */ (this.svgGroup_), 'blocklyDragging');
496
+ } else {
497
+ Blockly.utils.removeClass(
498
+ /** @type {!Element} */ (this.svgGroup_), 'blocklyDragging');
499
+ }
500
+ };
501
+
502
+ /**
503
+ * Return the root node of the SVG or null if none exists.
504
+ * @return {Element} The root SVG node (probably a group).
505
+ * @package
506
+ */
507
+ Blockly.WorkspaceCommentSvg.prototype.getSvgRoot = function() {
508
+ return this.svgGroup_;
509
+ };
510
+
511
+ /**
512
+ * Returns this comment's text.
513
+ * @return {string} Comment text.
514
+ * @package
515
+ */
516
+ Blockly.WorkspaceCommentSvg.prototype.getText = function() {
517
+ return this.textarea_ ? this.textarea_.value : this.content_;
518
+ };
519
+
520
+ /**
521
+ * Set this comment's text.
522
+ * @param {string} text Comment text.
523
+ * @package
524
+ */
525
+ Blockly.WorkspaceCommentSvg.prototype.setText = function(text) {
526
+ Blockly.WorkspaceCommentSvg.superClass_.setText.call(this, text);
527
+ if (this.textarea_) {
528
+ this.textarea_.value = text;
529
+ }
530
+ };
531
+
532
+ /**
533
+ * Update the cursor over this comment by adding or removing a class.
534
+ * @param {boolean} enable True if the delete cursor should be shown, false
535
+ * otherwise.
536
+ * @package
537
+ */
538
+ Blockly.WorkspaceCommentSvg.prototype.setDeleteStyle = function(enable) {
539
+ if (enable) {
540
+ Blockly.utils.addClass(
541
+ /** @type {!Element} */ (this.svgGroup_), 'blocklyDraggingDelete');
542
+ } else {
543
+ Blockly.utils.removeClass(
544
+ /** @type {!Element} */ (this.svgGroup_), 'blocklyDraggingDelete');
545
+ }
546
+ };
547
+
548
+ Blockly.WorkspaceCommentSvg.prototype.setAutoLayout = function() {
549
+ // NOP for compatibility with the bubble dragger.
550
+ };
551
+
552
+ /**
553
+ * Decode an XML comment tag and create a rendered comment on the workspace.
554
+ * @param {!Element} xmlComment XML comment element.
555
+ * @param {!Blockly.Workspace} workspace The workspace.
556
+ * @param {number=} opt_wsWidth The width of the workspace, which is used to
557
+ * position comments correctly in RTL.
558
+ * @return {!Blockly.WorkspaceCommentSvg} The created workspace comment.
559
+ * @package
560
+ */
561
+ Blockly.WorkspaceCommentSvg.fromXml = function(xmlComment, workspace,
562
+ opt_wsWidth) {
563
+ Blockly.Events.disable();
564
+ try {
565
+ var info = Blockly.WorkspaceComment.parseAttributes(xmlComment);
566
+
567
+ var comment = new Blockly.WorkspaceCommentSvg(workspace,
568
+ info.content, info.h, info.w, info.minimized, info.id);
569
+ if (workspace.rendered) {
570
+ comment.initSvg();
571
+ comment.render(false);
572
+ }
573
+ // Position the comment correctly, taking into account the width of a
574
+ // rendered RTL workspace.
575
+ if (!isNaN(info.x) && !isNaN(info.y)) {
576
+ if (workspace.RTL) {
577
+ var wsWidth = opt_wsWidth || workspace.getWidth();
578
+ comment.moveBy(wsWidth - info.x, info.y);
579
+ } else {
580
+ comment.moveBy(info.x, info.y);
581
+ }
582
+ }
583
+ } finally {
584
+ Blockly.Events.enable();
585
+ }
586
+ Blockly.WorkspaceComment.fireCreateEvent(comment);
587
+
588
+ return comment;
589
+ };
590
+
591
+ /**
592
+ * Encode a comment subtree as XML with XY coordinates.
593
+ * @param {boolean=} opt_noId True if the encoder should skip the comment id.
594
+ * @return {!Element} Tree of XML elements.
595
+ * @package
596
+ */
597
+ Blockly.WorkspaceCommentSvg.prototype.toXmlWithXY = function(opt_noId) {
598
+ var width; // Not used in LTR.
599
+ if (this.workspace.RTL) {
600
+ // Here be performance dragons: This calls getMetrics().
601
+ width = this.workspace.getWidth();
602
+ }
603
+ var element = this.toXml(opt_noId);
604
+ var xy = this.getRelativeToSurfaceXY();
605
+ element.setAttribute('x',
606
+ Math.round(this.workspace.RTL ? width - xy.x : xy.x));
607
+ element.setAttribute('y', Math.round(xy.y));
608
+ element.setAttribute('h', this.getHeight());
609
+ element.setAttribute('w', this.getWidth());
610
+ return element;
611
+ };