@blockdia/scratch-blocks 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (243) hide show
  1. package/.nvmrc +1 -0
  2. package/LICENSE +674 -0
  3. package/README.md +57 -0
  4. package/TRADEMARK +1 -0
  5. package/blockly_compressed_horizontal.js +2268 -0
  6. package/blockly_compressed_vertical.js +2296 -0
  7. package/blockly_uncompressed_horizontal.js +1212 -0
  8. package/blockly_uncompressed_vertical.js +1212 -0
  9. package/blocks_common/colour.js +61 -0
  10. package/blocks_common/math.js +159 -0
  11. package/blocks_common/matrix.js +54 -0
  12. package/blocks_common/note.js +58 -0
  13. package/blocks_common/text.js +57 -0
  14. package/blocks_compressed.js +37 -0
  15. package/blocks_compressed_horizontal.js +68 -0
  16. package/blocks_compressed_vertical.js +216 -0
  17. package/blocks_horizontal/control.js +212 -0
  18. package/blocks_horizontal/default_toolbox.js +139 -0
  19. package/blocks_horizontal/event.js +190 -0
  20. package/blocks_horizontal/wedo.js +325 -0
  21. package/blocks_vertical/control.js +532 -0
  22. package/blocks_vertical/data.js +666 -0
  23. package/blocks_vertical/default_toolbox.js +571 -0
  24. package/blocks_vertical/event.js +329 -0
  25. package/blocks_vertical/extensions.js +294 -0
  26. package/blocks_vertical/looks.js +591 -0
  27. package/blocks_vertical/motion.js +587 -0
  28. package/blocks_vertical/operators.js +470 -0
  29. package/blocks_vertical/procedures.js +1051 -0
  30. package/blocks_vertical/sensing.js +555 -0
  31. package/blocks_vertical/sound.js +246 -0
  32. package/blocks_vertical/vertical_extensions.js +289 -0
  33. package/build/gen_blocks.js +1 -0
  34. package/build/test_expect.js +1 -0
  35. package/build/test_input.js +1 -0
  36. package/build.py +647 -0
  37. package/cleanup.sh +101 -0
  38. package/core/block.js +1837 -0
  39. package/core/block_animations.js +107 -0
  40. package/core/block_drag_surface.js +299 -0
  41. package/core/block_dragger.js +424 -0
  42. package/core/block_events.js +531 -0
  43. package/core/block_render_svg_horizontal.js +892 -0
  44. package/core/block_render_svg_vertical.js +1734 -0
  45. package/core/block_svg.js +1355 -0
  46. package/core/blockly.js +620 -0
  47. package/core/blocks.js +37 -0
  48. package/core/bubble.js +664 -0
  49. package/core/bubble_dragger.js +285 -0
  50. package/core/colours.js +177 -0
  51. package/core/comment.js +293 -0
  52. package/core/comment_events.js +539 -0
  53. package/core/connection.js +776 -0
  54. package/core/connection_db.js +300 -0
  55. package/core/constants.js +408 -0
  56. package/core/contextmenu.js +534 -0
  57. package/core/css.js +1354 -0
  58. package/core/data_category.js +490 -0
  59. package/core/dragged_connection_manager.js +260 -0
  60. package/core/dropdowndiv.js +408 -0
  61. package/core/events.js +429 -0
  62. package/core/events_abstract.js +113 -0
  63. package/core/extensions.js +450 -0
  64. package/core/field.js +810 -0
  65. package/core/field_angle.js +410 -0
  66. package/core/field_checkbox.js +133 -0
  67. package/core/field_colour.js +253 -0
  68. package/core/field_colour_slider.js +387 -0
  69. package/core/field_date.js +353 -0
  70. package/core/field_dropdown.js +447 -0
  71. package/core/field_iconmenu.js +309 -0
  72. package/core/field_image.js +200 -0
  73. package/core/field_label.js +136 -0
  74. package/core/field_label_serializable.js +125 -0
  75. package/core/field_matrix.js +566 -0
  76. package/core/field_note.js +850 -0
  77. package/core/field_number.js +366 -0
  78. package/core/field_numberdropdown.js +77 -0
  79. package/core/field_textdropdown.js +164 -0
  80. package/core/field_textinput.js +675 -0
  81. package/core/field_textinput_removable.js +105 -0
  82. package/core/field_variable.js +385 -0
  83. package/core/field_variable_getter.js +185 -0
  84. package/core/field_vertical_separator.js +161 -0
  85. package/core/flyout_base.js +935 -0
  86. package/core/flyout_button.js +324 -0
  87. package/core/flyout_dragger.js +83 -0
  88. package/core/flyout_extension_category_header.js +159 -0
  89. package/core/flyout_horizontal.js +475 -0
  90. package/core/flyout_vertical.js +770 -0
  91. package/core/generator.js +426 -0
  92. package/core/gesture.js +1010 -0
  93. package/core/grid.js +227 -0
  94. package/core/icon.js +205 -0
  95. package/core/inject.js +496 -0
  96. package/core/input.js +285 -0
  97. package/core/insertion_marker_manager.js +678 -0
  98. package/core/intersection_observer.js +102 -0
  99. package/core/msg.js +62 -0
  100. package/core/mutator.js +426 -0
  101. package/core/names.js +198 -0
  102. package/core/options.js +244 -0
  103. package/core/procedures.js +739 -0
  104. package/core/rendered_connection.js +417 -0
  105. package/core/scratch_block_comment.js +646 -0
  106. package/core/scratch_blocks_utils.js +246 -0
  107. package/core/scratch_bubble.js +699 -0
  108. package/core/scratch_events.js +131 -0
  109. package/core/scratch_msgs.js +85 -0
  110. package/core/scrollbar.js +875 -0
  111. package/core/toolbox.js +803 -0
  112. package/core/tooltip.js +337 -0
  113. package/core/touch.js +226 -0
  114. package/core/trashcan.js +343 -0
  115. package/core/ui_events.js +91 -0
  116. package/core/ui_menu_utils.js +68 -0
  117. package/core/utils.js +825 -0
  118. package/core/variable_events.js +259 -0
  119. package/core/variable_map.js +415 -0
  120. package/core/variable_model.js +116 -0
  121. package/core/variables.js +674 -0
  122. package/core/warning.js +199 -0
  123. package/core/widgetdiv.js +344 -0
  124. package/core/workspace.js +673 -0
  125. package/core/workspace_audio.js +170 -0
  126. package/core/workspace_comment.js +426 -0
  127. package/core/workspace_comment_render_svg.js +706 -0
  128. package/core/workspace_comment_svg.js +609 -0
  129. package/core/workspace_drag_surface_svg.js +195 -0
  130. package/core/workspace_dragger.js +132 -0
  131. package/core/workspace_svg.js +2382 -0
  132. package/core/xml.js +930 -0
  133. package/core/zoom_controls.js +301 -0
  134. package/dist/horizontal.js +222 -0
  135. package/dist/vertical.js +222 -0
  136. package/dist/web/horizontal.js +232 -0
  137. package/dist/web/vertical.js +232 -0
  138. package/i18n/common.py +234 -0
  139. package/i18n/create_messages.py +162 -0
  140. package/i18n/create_scratch_msgs.js +69 -0
  141. package/i18n/dedup_json.py +73 -0
  142. package/i18n/js_to_json.js +46 -0
  143. package/i18n/js_to_json.py +136 -0
  144. package/i18n/json_to_js.js +52 -0
  145. package/i18n/json_to_js.py +185 -0
  146. package/i18n/sync_tx_translations.js +111 -0
  147. package/i18n/test_scratch_msgs.js +87 -0
  148. package/i18n/tests.py +47 -0
  149. package/i18n/xliff_to_json.py +232 -0
  150. package/local_build.sh +70 -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/status-not-ready.svg +13 -0
  216. package/media/status-ready.svg +13 -0
  217. package/media/zoom-in.svg +1 -0
  218. package/media/zoom-out.svg +1 -0
  219. package/media/zoom-reset.svg +1 -0
  220. package/msg/js/en.js +290 -0
  221. package/msg/json/en.json +285 -0
  222. package/msg/messages.js +359 -0
  223. package/msg/scratch_msgs.js +22969 -0
  224. package/package.json +60 -0
  225. package/pull_from_blockly.sh +151 -0
  226. package/renovate.json5 +15 -0
  227. package/shim/blockly_compressed_horizontal-blocks_compressed.js +1 -0
  228. package/shim/blockly_compressed_horizontal.Blockly.js +1 -0
  229. package/shim/blockly_compressed_horizontal.goog.js +1 -0
  230. package/shim/blockly_compressed_horizontal.js +1 -0
  231. package/shim/blockly_compressed_vertical-blocks_compressed.js +1 -0
  232. package/shim/blockly_compressed_vertical.Blockly.js +1 -0
  233. package/shim/blockly_compressed_vertical.goog.js +1 -0
  234. package/shim/blockly_compressed_vertical.js +1 -0
  235. package/shim/blocks_compressed_horizontal-blockly_compressed_horizontal-messages.js +1 -0
  236. package/shim/blocks_compressed_horizontal.js +1 -0
  237. package/shim/blocks_compressed_vertical-blockly_compressed_vertical-messages.js +1 -0
  238. package/shim/blocks_compressed_vertical.js +1 -0
  239. package/shim/gh-pages.js +1 -0
  240. package/shim/horizontal.js +1 -0
  241. package/shim/index.js +17 -0
  242. package/shim/vertical.js +1 -0
  243. package/universal-python.js +82 -0
@@ -0,0 +1,539 @@
1
+ /**
2
+ * @license
3
+ * Visual Blocks Editor
4
+ *
5
+ * Copyright 2018 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 Classes for all comment events.
23
+ * @author fenichel@google.com (Rachel Fenichel)
24
+ */
25
+ 'use strict';
26
+
27
+ goog.provide('Blockly.Events.CommentBase');
28
+ goog.provide('Blockly.Events.CommentChange');
29
+ goog.provide('Blockly.Events.CommentCreate');
30
+ goog.provide('Blockly.Events.CommentDelete');
31
+ goog.provide('Blockly.Events.CommentMove');
32
+
33
+ goog.require('Blockly.Events');
34
+ goog.require('Blockly.Events.Abstract');
35
+
36
+ goog.require('goog.math.Coordinate');
37
+
38
+
39
+ /**
40
+ * Abstract class for a comment event.
41
+ * @param {Blockly.WorkspaceComment | Blockly.ScratchBlockComment} comment
42
+ * The comment this event corresponds to.
43
+ * @extends {Blockly.Events.Abstract}
44
+ * @constructor
45
+ */
46
+ Blockly.Events.CommentBase = function(comment) {
47
+ /**
48
+ * The ID of the comment this event pertains to.
49
+ * @type {string}
50
+ */
51
+ this.commentId = comment.id;
52
+
53
+ /**
54
+ * The workspace identifier for this event.
55
+ * @type {string}
56
+ */
57
+ this.workspaceId = comment.workspace.id;
58
+
59
+ /**
60
+ * The ID of the block this comment belongs to or null if it is not a block
61
+ * comment.
62
+ * @type {string}
63
+ */
64
+ this.blockId = comment.blockId || null;
65
+
66
+ /**
67
+ * The event group id for the group this event belongs to. Groups define
68
+ * events that should be treated as an single action from the user's
69
+ * perspective, and should be undone together.
70
+ * @type {string}
71
+ */
72
+ this.group = Blockly.Events.group_;
73
+
74
+ /**
75
+ * Sets whether the event should be added to the undo stack.
76
+ * @type {boolean}
77
+ */
78
+ this.recordUndo = Blockly.Events.recordUndo;
79
+ };
80
+ goog.inherits(Blockly.Events.CommentBase, Blockly.Events.Abstract);
81
+
82
+ /**
83
+ * Encode the event as JSON.
84
+ * @return {!Object} JSON representation.
85
+ */
86
+ Blockly.Events.CommentBase.prototype.toJson = function() {
87
+ var json = {
88
+ 'type': this.type
89
+ };
90
+ if (this.group) {
91
+ json['group'] = this.group;
92
+ }
93
+ if (this.commentId) {
94
+ json['commentId'] = this.commentId;
95
+ }
96
+ if (this.blockId) {
97
+ json['blockId'] = this.blockId;
98
+ }
99
+ return json;
100
+ };
101
+
102
+ /**
103
+ * Decode the JSON event.
104
+ * @param {!Object} json JSON representation.
105
+ */
106
+ Blockly.Events.CommentBase.prototype.fromJson = function(json) {
107
+ this.commentId = json['commentId'];
108
+ this.group = json['group'];
109
+ this.blockId = json['blockId'];
110
+ };
111
+
112
+ /**
113
+ * Helper function for finding the comment this event pertains to.
114
+ * @return {?(Blockly.WorkspaceComment | Blockly.ScratchBlockComment)}
115
+ * The comment this event pertains to, or null if it no longer exists.
116
+ * @private
117
+ */
118
+ Blockly.Events.CommentBase.prototype.getComment_ = function() {
119
+ var workspace = this.getEventWorkspace_();
120
+ return workspace.getCommentById(this.commentId);
121
+ };
122
+
123
+ /**
124
+ * Class for a comment change event.
125
+ * @param {Blockly.WorkspaceComment | Blockly.ScratchBlockComment} comment
126
+ * The comment that is being changed. Null for a blank event.
127
+ * @param {!object} oldContents Object containing previous state of a comment's
128
+ * properties. The possible properties can be: 'minimized', 'text', or
129
+ * 'width' and 'height' together. Must contain the same property (or in the
130
+ * case of 'width' and 'height' properties) as the 'newContents' param.
131
+ * @param {!object} newContents Object containing the new state of a comment's
132
+ * properties. The possible properties can be: 'minimized', 'text', or
133
+ * 'width' and 'height' together. Must contain the same property (or in the
134
+ * case of 'width' and 'height' properties) as the 'oldContents' param.
135
+ * @extends {Blockly.Events.CommentBase}
136
+ * @constructor
137
+ */
138
+ Blockly.Events.CommentChange = function(comment, oldContents, newContents) {
139
+ if (!comment) {
140
+ return; // Blank event to be populated by fromJson.
141
+ }
142
+ Blockly.Events.CommentChange.superClass_.constructor.call(this, comment);
143
+ this.oldContents_ = oldContents;
144
+ this.newContents_ = newContents;
145
+ };
146
+ goog.inherits(Blockly.Events.CommentChange, Blockly.Events.CommentBase);
147
+
148
+ /**
149
+ * Type of this event.
150
+ * @type {string}
151
+ */
152
+ Blockly.Events.CommentChange.prototype.type = Blockly.Events.COMMENT_CHANGE;
153
+
154
+ /**
155
+ * Encode the event as JSON.
156
+ * @return {!Object} JSON representation.
157
+ */
158
+ Blockly.Events.CommentChange.prototype.toJson = function() {
159
+ var json = Blockly.Events.CommentChange.superClass_.toJson.call(this);
160
+ json['newContents'] = this.newContents_;
161
+ return json;
162
+ };
163
+
164
+ /**
165
+ * Decode the JSON event.
166
+ * @param {!Object} json JSON representation.
167
+ */
168
+ Blockly.Events.CommentChange.prototype.fromJson = function(json) {
169
+ Blockly.Events.CommentChange.superClass_.fromJson.call(this, json);
170
+ this.newContents_ = json['newValue'];
171
+ };
172
+
173
+ /**
174
+ * Does this event record any change of state?
175
+ * @return {boolean} False if something changed.
176
+ */
177
+ Blockly.Events.CommentChange.prototype.isNull = function() {
178
+ return this.oldContents_ == this.newContents_;
179
+ };
180
+
181
+ /**
182
+ * Run a change event.
183
+ * @param {boolean} forward True if run forward, false if run backward (undo).
184
+ */
185
+ Blockly.Events.CommentChange.prototype.run = function(forward) {
186
+ var comment = this.getComment_();
187
+ if (!comment) {
188
+ console.warn('Can\'t change non-existent comment: ' + this.commentId);
189
+ return;
190
+ }
191
+ var contents = forward ? this.newContents_ : this.oldContents_;
192
+
193
+ if (contents.hasOwnProperty('minimized')) {
194
+ comment.setMinimized(contents.minimized);
195
+ }
196
+ if (contents.hasOwnProperty('width') && contents.hasOwnProperty('height')) {
197
+ comment.setSize(contents.width, contents.height);
198
+ }
199
+ if (contents.hasOwnProperty('text')) {
200
+ comment.setText(contents.text);
201
+ }
202
+ };
203
+
204
+ /**
205
+ * Class for a comment creation event.
206
+ * @param {Blockly.WorkspaceComment | Blockly.ScratchBlockComment} comment
207
+ * The created comment. Null for a blank event.
208
+ * @param {string=} opt_blockId Optional id for the block this comment belongs
209
+ * to, if it is a block comment.
210
+ * @extends {Blockly.Events.CommentBase}
211
+ * @constructor
212
+ */
213
+ Blockly.Events.CommentCreate = function(comment) {
214
+ if (!comment) {
215
+ return; // Blank event to be populated by fromJson.
216
+ }
217
+ Blockly.Events.CommentCreate.superClass_.constructor.call(this, comment);
218
+
219
+ /**
220
+ * The text content of this comment.
221
+ * @type {string}
222
+ */
223
+ this.text = comment.getText();
224
+
225
+ /**
226
+ * The XY position of this comment on the workspace.
227
+ * @type {goog.math.Coordinate}
228
+ */
229
+ this.xy = comment.getXY();
230
+
231
+ var hw = comment.getHeightWidth();
232
+
233
+ /**
234
+ * The width of this comment when it is full size.
235
+ * @type {number}
236
+ */
237
+ this.width = hw.width;
238
+
239
+ /**
240
+ * The height of this comment when it is full size.
241
+ * @type {number}
242
+ */
243
+ this.height = hw.height;
244
+
245
+ /**
246
+ * Whether or not this comment is minimized.
247
+ * @type {boolean}
248
+ */
249
+ this.minimized = comment.isMinimized() || false;
250
+
251
+ this.xml = comment.toXmlWithXY();
252
+ };
253
+ goog.inherits(Blockly.Events.CommentCreate, Blockly.Events.CommentBase);
254
+
255
+ /**
256
+ * Type of this event.
257
+ * @type {string}
258
+ */
259
+ Blockly.Events.CommentCreate.prototype.type = Blockly.Events.COMMENT_CREATE;
260
+
261
+ /**
262
+ * Encode the event as JSON.
263
+ * TODO (github.com/google/blockly/issues/1266): "Full" and "minimal"
264
+ * serialization.
265
+ * @return {!Object} JSON representation.
266
+ */
267
+ Blockly.Events.CommentCreate.prototype.toJson = function() {
268
+ var json = Blockly.Events.CommentCreate.superClass_.toJson.call(this);
269
+ json['xml'] = Blockly.Xml.domToText(this.xml);
270
+ return json;
271
+ };
272
+
273
+ /**
274
+ * Decode the JSON event.
275
+ * @param {!Object} json JSON representation.
276
+ */
277
+ Blockly.Events.CommentCreate.prototype.fromJson = function(json) {
278
+ Blockly.Events.CommentCreate.superClass_.fromJson.call(this, json);
279
+ this.xml = Blockly.Xml.textToDom('<xml>' + json['xml'] + '</xml>').firstChild;
280
+ };
281
+
282
+ /**
283
+ * Run a creation event.
284
+ * @param {boolean} forward True if run forward, false if run backward (undo).
285
+ */
286
+ Blockly.Events.CommentCreate.prototype.run = function(forward) {
287
+ if (forward) {
288
+ var workspace = this.getEventWorkspace_();
289
+ if (this.blockId) {
290
+ var block = workspace.getBlockById(this.blockId);
291
+ if (block) {
292
+ block.setCommentText('', this.commentId, this.xy.x, this.xy.y, this.minimized);
293
+ }
294
+ } else {
295
+ var xml = goog.dom.createDom('xml');
296
+ xml.appendChild(this.xml);
297
+ Blockly.Xml.domToWorkspace(xml, workspace);
298
+ }
299
+ } else {
300
+ var comment = this.getComment_();
301
+ if (comment) {
302
+ comment.dispose(false, false);
303
+ } else {
304
+ // Only complain about root-level block.
305
+ console.warn("Can't uncreate non-existent comment: " + this.commentId);
306
+ }
307
+ }
308
+ };
309
+
310
+ /**
311
+ * Class for a comment deletion event.
312
+ * @param {Blockly.WorkspaceComment | Blockly.ScratchBlockComment} comment
313
+ * The deleted comment. Null for a blank event.
314
+ * @extends {Blockly.Events.CommentBase}
315
+ * @constructor
316
+ */
317
+ Blockly.Events.CommentDelete = function(comment) {
318
+ if (!comment) {
319
+ return; // Blank event to be populated by fromJson.
320
+ }
321
+ Blockly.Events.CommentDelete.superClass_.constructor.call(this, comment);
322
+ this.xy = comment.getXY();
323
+ this.minimized = comment.isMinimized() || false;
324
+ this.text = comment.getText();
325
+ var hw = comment.getHeightWidth();
326
+ this.height = hw.height;
327
+ this.width = hw.width;
328
+
329
+ this.xml = comment.toXmlWithXY();
330
+ };
331
+ goog.inherits(Blockly.Events.CommentDelete, Blockly.Events.CommentBase);
332
+
333
+ /**
334
+ * Type of this event.
335
+ * @type {string}
336
+ */
337
+ Blockly.Events.CommentDelete.prototype.type = Blockly.Events.COMMENT_DELETE;
338
+
339
+ /**
340
+ * Encode the event as JSON.
341
+ * TODO (github.com/google/blockly/issues/1266): "Full" and "minimal"
342
+ * serialization.
343
+ * @return {!Object} JSON representation.
344
+ */
345
+ Blockly.Events.CommentDelete.prototype.toJson = function() {
346
+ var json = Blockly.Events.CommentDelete.superClass_.toJson.call(this);
347
+ return json;
348
+ };
349
+
350
+ /**
351
+ * Decode the JSON event.
352
+ * @param {!Object} json JSON representation.
353
+ */
354
+ Blockly.Events.CommentDelete.prototype.fromJson = function(json) {
355
+ Blockly.Events.CommentDelete.superClass_.fromJson.call(this, json);
356
+ };
357
+
358
+ /**
359
+ * Run a creation event.
360
+ * @param {boolean} forward True if run forward, false if run backward (undo).
361
+ */
362
+ Blockly.Events.CommentDelete.prototype.run = function(forward) {
363
+ if (forward) {
364
+ var comment = this.getComment_();
365
+ if (comment) {
366
+ comment.dispose(false, false);
367
+ } else {
368
+ // Only complain about root-level block.
369
+ console.warn("Can't delete non-existent comment: " + this.commentId);
370
+ }
371
+ } else {
372
+ var workspace = this.getEventWorkspace_();
373
+ if (this.blockId) {
374
+ var block = workspace.getBlockById(this.blockId);
375
+ block.setCommentText(this.text, this.commentId, this.xy.x, this.xy.y, this.minimized);
376
+ block.comment.setSize(this.width, this.height);
377
+ } else {
378
+ var xml = goog.dom.createDom('xml');
379
+ xml.appendChild(this.xml);
380
+ Blockly.Xml.domToWorkspace(xml, workspace);
381
+ }
382
+ }
383
+ };
384
+
385
+ /**
386
+ * Class for a comment move event. Created before the move.
387
+ * @param {Blockly.WorkspaceComment | Blockly.ScratchBlockComment} comment
388
+ * The comment that is being moved. Null for a blank event.
389
+ * @extends {Blockly.Events.CommentBase}
390
+ * @constructor
391
+ */
392
+ Blockly.Events.CommentMove = function(comment) {
393
+ if (!comment) {
394
+ return; // Blank event to be populated by fromJson.
395
+ }
396
+ Blockly.Events.CommentMove.superClass_.constructor.call(this, comment);
397
+
398
+ /**
399
+ * The comment that is being moved. Will be cleared after recording the new
400
+ * location.
401
+ * @type {?Blockly.WorkspaceComment | Blockly.ScratchBlockComment}
402
+ */
403
+ this.comment_ = comment;
404
+
405
+ this.workspaceWidth_ = comment.workspace.getWidth();
406
+ /**
407
+ * The location before the move, in workspace coordinates.
408
+ * @type {!goog.math.Coordinate}
409
+ */
410
+ this.oldCoordinate_ = this.currentLocation_();
411
+
412
+ /**
413
+ * The location after the move, in workspace coordinates.
414
+ * @type {!goog.math.Coordinate}
415
+ */
416
+ this.newCoordinate_ = null;
417
+ };
418
+ goog.inherits(Blockly.Events.CommentMove, Blockly.Events.CommentBase);
419
+
420
+ /**
421
+ * Calculate the current, language agnostic location of the comment.
422
+ * This value should not report different numbers in LTR vs. RTL.
423
+ * @return {goog.math.Coordinate} The location of the comment.
424
+ * @private
425
+ */
426
+ Blockly.Events.CommentMove.prototype.currentLocation_ = function() {
427
+ var xy = this.comment_.getXY();
428
+ if (!this.comment_.workspace.RTL) {
429
+ return xy;
430
+ }
431
+
432
+ var rtlAwareX;
433
+ if (this.comment_ instanceof Blockly.ScratchBlockComment) {
434
+ var commentWidth = this.comment_.getBubbleSize().width;
435
+ rtlAwareX = this.workspaceWidth_ - xy.x - commentWidth;
436
+ } else {
437
+ rtlAwareX = this.workspaceWidth_ - xy.x;
438
+ }
439
+ return new goog.math.Coordinate(rtlAwareX, xy.y);
440
+ };
441
+
442
+ /**
443
+ * Record the comment's new location. Called after the move. Can only be
444
+ * called once.
445
+ */
446
+ Blockly.Events.CommentMove.prototype.recordNew = function() {
447
+ if (!this.comment_) {
448
+ throw new Error('Tried to record the new position of a comment on the ' +
449
+ 'same event twice.');
450
+ }
451
+ this.newCoordinate_ = this.currentLocation_();
452
+ this.comment_ = null;
453
+ };
454
+
455
+ /**
456
+ * Type of this event.
457
+ * @type {string}
458
+ */
459
+ Blockly.Events.CommentMove.prototype.type = Blockly.Events.COMMENT_MOVE;
460
+
461
+ /**
462
+ * Override the location before the move. Use this if you don't create the
463
+ * event until the end of the move, but you know the original location.
464
+ * @param {!goog.math.Coordinate} xy The location before the move, in workspace
465
+ * coordinates.
466
+ */
467
+ Blockly.Events.CommentMove.prototype.setOldCoordinate = function(xy) {
468
+ this.oldCoordinate_ = new goog.math.Coordinate(this.comment_.workspace.RTL ?
469
+ this.workspaceWidth_ - xy.x : xy.x, xy.y);
470
+ };
471
+
472
+ /**
473
+ * Encode the event as JSON.
474
+ * TODO (github.com/google/blockly/issues/1266): "Full" and "minimal"
475
+ * serialization.
476
+ * @return {!Object} JSON representation.
477
+ */
478
+ Blockly.Events.CommentMove.prototype.toJson = function() {
479
+ var json = Blockly.Events.CommentMove.superClass_.toJson.call(this);
480
+ if (this.newCoordinate_) {
481
+ json['newCoordinate'] = Math.round(this.newCoordinate_.x) + ',' +
482
+ Math.round(this.newCoordinate_.y);
483
+ }
484
+ return json;
485
+ };
486
+
487
+ /**
488
+ * Decode the JSON event.
489
+ * @param {!Object} json JSON representation.
490
+ */
491
+ Blockly.Events.CommentMove.prototype.fromJson = function(json) {
492
+ Blockly.Events.CommentMove.superClass_.fromJson.call(this, json);
493
+
494
+ if (json['newCoordinate']) {
495
+ var xy = json['newCoordinate'].split(',');
496
+ this.newCoordinate_ =
497
+ new goog.math.Coordinate(parseFloat(xy[0]), parseFloat(xy[1]));
498
+ }
499
+ };
500
+
501
+ /**
502
+ * Does this event record any change of state?
503
+ * @return {boolean} False if something changed.
504
+ */
505
+ Blockly.Events.CommentMove.prototype.isNull = function() {
506
+ return goog.math.Coordinate.equals(this.oldCoordinate_, this.newCoordinate_);
507
+ };
508
+
509
+ /**
510
+ * Run a move event.
511
+ * @param {boolean} forward True if run forward, false if run backward (undo).
512
+ */
513
+ Blockly.Events.CommentMove.prototype.run = function(forward) {
514
+ var comment = this.getComment_();
515
+ if (!comment) {
516
+ console.warn('Can\'t move non-existent comment: ' + this.commentId);
517
+ return;
518
+ }
519
+
520
+ var target = forward ? this.newCoordinate_ : this.oldCoordinate_;
521
+
522
+ if (comment instanceof Blockly.ScratchBlockComment) {
523
+ if (comment.workspace.RTL) {
524
+ comment.moveTo(this.workspaceWidth_ - target.x, target.y);
525
+ } else {
526
+ comment.moveTo(target.x, target.y);
527
+ }
528
+ } else {
529
+ // TODO: Check if the comment is being dragged, and give up if so.
530
+ var current = comment.getXY();
531
+ if (comment.workspace.RTL) {
532
+ var deltaX = target.x - (this.workspaceWidth_ - current.x);
533
+ comment.moveBy(-deltaX, target.y - current.y);
534
+ } else {
535
+ comment.moveBy(target.x - current.x, target.y - current.y);
536
+ }
537
+
538
+ }
539
+ };