@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,105 @@
1
+ /**
2
+ * @license
3
+ * Visual Blocks Editor
4
+ *
5
+ * Copyright 2016 Massachusetts Institute of Technology
6
+ * All rights reserved.
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 Text input field with floating "remove" button.
23
+ * @author pkaplan@media.mit.edu (Paul Kaplan)
24
+ */
25
+ 'use strict';
26
+
27
+ goog.provide('Blockly.FieldTextInputRemovable');
28
+
29
+ goog.require('Blockly.BlockSvg.render');
30
+ goog.require('Blockly.Colours');
31
+ goog.require('Blockly.FieldTextInput');
32
+ goog.require('Blockly.Msg');
33
+ goog.require('Blockly.utils');
34
+ goog.require('goog.dom');
35
+ goog.require('goog.dom.TagName');
36
+
37
+ /**
38
+ * Class for an editable text field displaying a deletion icon when selected.
39
+ * @param {string} text The initial content of the field.
40
+ * @param {Function=} opt_validator An optional function that is called
41
+ * to validate any constraints on what the user entered. Takes the new
42
+ * text as an argument and returns either the accepted text, a replacement
43
+ * text, or null to abort the change.
44
+ * @param {RegExp=} opt_restrictor An optional regular expression to restrict
45
+ * typed text to. Text that doesn't match the restrictor will never show
46
+ * in the text field.
47
+ * @extends {Blockly.FieldTextInput}
48
+ * @constructor
49
+ */
50
+ Blockly.FieldTextInputRemovable = function(text, opt_validator, opt_restrictor) {
51
+ Blockly.FieldTextInputRemovable.superClass_.constructor.call(this, text,
52
+ opt_validator, opt_restrictor);
53
+ };
54
+ goog.inherits(Blockly.FieldTextInputRemovable, Blockly.FieldTextInput);
55
+
56
+ /**
57
+ * Show the inline free-text editor on top of the text with the remove button.
58
+ * @private
59
+ */
60
+ Blockly.FieldTextInputRemovable.prototype.showEditor_ = function() {
61
+ Blockly.FieldTextInputRemovable.superClass_.showEditor_.call(this);
62
+
63
+ var div = Blockly.WidgetDiv.DIV;
64
+ div.className += ' removableTextInput';
65
+ var removeButton =
66
+ goog.dom.createDom(goog.dom.TagName.IMG, 'blocklyTextRemoveIcon');
67
+ removeButton.setAttribute('src',
68
+ Blockly.mainWorkspace.options.pathToMedia + 'icons/remove.svg');
69
+ this.removeButtonMouseWrapper_ = Blockly.bindEvent_(removeButton,
70
+ 'mousedown', this, this.removeCallback_);
71
+ div.appendChild(removeButton);
72
+ };
73
+
74
+ /**
75
+ * Function to call when remove button is called. Checks for removeFieldCallback
76
+ * on sourceBlock and calls it if possible.
77
+ * @private
78
+ */
79
+ Blockly.FieldTextInputRemovable.prototype.removeCallback_ = function() {
80
+ if (this.sourceBlock_ && this.sourceBlock_.removeFieldCallback) {
81
+ this.sourceBlock_.removeFieldCallback(this);
82
+ } else {
83
+ console.warn('Expected a source block with removeFieldCallback');
84
+ }
85
+ };
86
+
87
+ /**
88
+ * Helper function to construct a FieldTextInputRemovable from a JSON arg object,
89
+ * dereferencing any string table references.
90
+ * @param {!Object} options A JSON object with options (text, class, and
91
+ * spellcheck).
92
+ * @returns {!Blockly.FieldTextInputRemovable} The new text input.
93
+ * @public
94
+ */
95
+ Blockly.FieldTextInputRemovable.fromJson = function(options) {
96
+ var text = Blockly.utils.replaceMessageReferences(options['text']);
97
+ var field = new Blockly.FieldTextInputRemovable(text, options['class']);
98
+ if (typeof options['spellcheck'] == 'boolean') {
99
+ field.setSpellcheck(options['spellcheck']);
100
+ }
101
+ return field;
102
+ };
103
+
104
+ Blockly.Field.register(
105
+ 'field_input_removable', Blockly.FieldTextInputRemovable);
@@ -0,0 +1,385 @@
1
+ /**
2
+ * @license
3
+ * Visual Blocks Editor
4
+ *
5
+ * Copyright 2012 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 Variable input field.
23
+ * @author fraser@google.com (Neil Fraser)
24
+ */
25
+ 'use strict';
26
+
27
+ goog.provide('Blockly.FieldVariable');
28
+
29
+ goog.require('Blockly.FieldDropdown');
30
+ goog.require('Blockly.Msg');
31
+ goog.require('Blockly.VariableModel');
32
+ goog.require('Blockly.Variables');
33
+ goog.require('goog.asserts');
34
+ goog.require('goog.string');
35
+
36
+
37
+ /**
38
+ * Class for a variable's dropdown field.
39
+ * @param {?string} varname The default name for the variable. If null,
40
+ * a unique variable name will be generated.
41
+ * @param {Function=} opt_validator A function that is executed when a new
42
+ * option is selected. Its sole argument is the new option value.
43
+ * @param {Array.<string>} opt_variableTypes A list of the types of variables to
44
+ * include in the dropdown.
45
+ * @extends {Blockly.FieldDropdown}
46
+ * @constructor
47
+ */
48
+ Blockly.FieldVariable = function(varname, opt_validator, opt_variableTypes) {
49
+ // The FieldDropdown constructor would call setValue, which might create a
50
+ // spurious variable. Just do the relevant parts of the constructor.
51
+ this.menuGenerator_ = Blockly.FieldVariable.dropdownCreate;
52
+ this.size_ = new goog.math.Size(Blockly.BlockSvg.FIELD_WIDTH,
53
+ Blockly.BlockSvg.FIELD_HEIGHT);
54
+ this.setValidator(opt_validator);
55
+ // TODO (blockly #1499): Add opt_default_type to match default value.
56
+ // If not set, ''.
57
+ this.defaultVariableName = (varname || '');
58
+ var hasSingleVarType = opt_variableTypes && (opt_variableTypes.length == 1);
59
+ this.defaultType_ = hasSingleVarType ? opt_variableTypes[0] : '';
60
+ this.variableTypes = opt_variableTypes;
61
+ this.addArgType('variable');
62
+
63
+ this.value_ = null;
64
+ };
65
+ goog.inherits(Blockly.FieldVariable, Blockly.FieldDropdown);
66
+
67
+ /**
68
+ * Construct a FieldVariable from a JSON arg object,
69
+ * dereferencing any string table references.
70
+ * @param {!Object} options A JSON object with options (variable,
71
+ * variableTypes, and defaultType).
72
+ * @returns {!Blockly.FieldVariable} The new field instance.
73
+ * @package
74
+ * @nocollapse
75
+ */
76
+ Blockly.FieldVariable.fromJson = function(options) {
77
+ var varname = Blockly.utils.replaceMessageReferences(options['variable']);
78
+ var variableTypes = options['variableTypes'];
79
+ return new Blockly.FieldVariable(varname, null, variableTypes);
80
+ };
81
+
82
+ /**
83
+ * Initialize everything needed to render this field. This includes making sure
84
+ * that the field's value is valid.
85
+ * @public
86
+ */
87
+ Blockly.FieldVariable.prototype.init = function() {
88
+ if (this.fieldGroup_) {
89
+ // Dropdown has already been initialized once.
90
+ return;
91
+ }
92
+ Blockly.FieldVariable.superClass_.init.call(this);
93
+
94
+ // TODO (blockly #1010): Change from init/initModel to initView/initModel
95
+ this.initModel();
96
+ };
97
+
98
+ /**
99
+ * Initialize the model for this field if it has not already been initialized.
100
+ * If the value has not been set to a variable by the first render, we make up a
101
+ * variable rather than let the value be invalid.
102
+ * @package
103
+ */
104
+ Blockly.FieldVariable.prototype.initModel = function() {
105
+ if (this.variable_) {
106
+ return; // Initialization already happened.
107
+ }
108
+ this.workspace_ = this.sourceBlock_.workspace;
109
+ // Initialize this field if it's in a broadcast block in the flyout
110
+ var variable = this.initFlyoutBroadcast_(this.workspace_);
111
+ if (!variable) {
112
+ var variable = Blockly.Variables.getOrCreateVariablePackage(
113
+ this.workspace_, null, this.defaultVariableName, this.defaultType_);
114
+ }
115
+ // Don't fire a change event for this setValue. It would have null as the
116
+ // old value, which is not valid.
117
+ Blockly.Events.disable();
118
+ try {
119
+ this.setValue(variable.getId());
120
+ } finally {
121
+ Blockly.Events.enable();
122
+ }
123
+ };
124
+
125
+ /**
126
+ * Initialize broadcast blocks in the flyout.
127
+ * Implicit deletion of broadcast messages from the scratch vm may cause
128
+ * broadcast blocks in the flyout to change which variable they display as the
129
+ * selected option when the workspace is refreshed.
130
+ * Re-sort the broadcast messages by name, and set the field value to the id
131
+ * of the variable that comes first in sorted order.
132
+ * @param {!Blockly.Workspace} workspace The flyout workspace containing the
133
+ * broadcast block.
134
+ * @return {string} The variable of type 'broadcast_msg' that comes
135
+ * first in sorted order.
136
+ */
137
+ Blockly.FieldVariable.prototype.initFlyoutBroadcast_ = function(workspace) {
138
+ // Using shorter name for this constant
139
+ var broadcastMsgType = Blockly.BROADCAST_MESSAGE_VARIABLE_TYPE;
140
+ var broadcastVars = workspace.getVariablesOfType(broadcastMsgType);
141
+ if(workspace.isFlyout && this.defaultType_ == broadcastMsgType &&
142
+ broadcastVars.length != 0) {
143
+ broadcastVars.sort(Blockly.VariableModel.compareByName);
144
+ return broadcastVars[0];
145
+ }
146
+ };
147
+
148
+ /**
149
+ * Dispose of this field.
150
+ * @public
151
+ */
152
+ Blockly.FieldVariable.dispose = function() {
153
+ Blockly.FieldVariable.superClass_.dispose.call(this);
154
+ this.workspace_ = null;
155
+ this.variableMap_ = null;
156
+ };
157
+
158
+ /**
159
+ * Attach this field to a block.
160
+ * @param {!Blockly.Block} block The block containing this field.
161
+ */
162
+ Blockly.FieldVariable.prototype.setSourceBlock = function(block) {
163
+ goog.asserts.assert(!block.isShadow(),
164
+ 'Variable fields are not allowed to exist on shadow blocks.');
165
+ Blockly.FieldVariable.superClass_.setSourceBlock.call(this, block);
166
+ };
167
+
168
+ /**
169
+ * Get the variable's ID.
170
+ * @return {string} Current variable's ID.
171
+ */
172
+ Blockly.FieldVariable.prototype.getValue = function() {
173
+ return this.variable_ ? this.variable_.getId() : null;
174
+ };
175
+
176
+ /**
177
+ * Get the text from this field, which is the selected variable's name.
178
+ * @return {string} The selected variable's name, or the empty string if no
179
+ * variable is selected.
180
+ */
181
+ Blockly.FieldVariable.prototype.getText = function() {
182
+ return this.variable_ ? this.variable_.name : '';
183
+ };
184
+
185
+ /**
186
+ * Get the variable model for the selected variable.
187
+ * Not guaranteed to be in the variable map on the workspace (e.g. if accessed
188
+ * after the variable has been deleted).
189
+ * @return {?Blockly.VariableModel} the selected variable, or null if none was
190
+ * selected.
191
+ * @package
192
+ */
193
+ Blockly.FieldVariable.prototype.getVariable = function() {
194
+ return this.variable_;
195
+ };
196
+
197
+ /**
198
+ * Set the variable ID.
199
+ * @param {string} id New variable ID, which must reference an existing
200
+ * variable.
201
+ */
202
+ Blockly.FieldVariable.prototype.setValue = function(id) {
203
+ var workspace = this.sourceBlock_.workspace;
204
+ var variable = Blockly.Variables.getVariable(workspace, id);
205
+
206
+ if (!variable) {
207
+ throw new Error('Variable id doesn\'t point to a real variable! ID was ' +
208
+ id);
209
+ }
210
+ // Type checks!
211
+ var type = variable.type;
212
+ if (!this.typeIsAllowed_(type)) {
213
+ throw new Error('Variable type doesn\'t match this field! Type was ' +
214
+ type);
215
+ }
216
+ if (this.sourceBlock_ && Blockly.Events.isEnabled()) {
217
+ var oldValue = this.variable_ ? this.variable_.getId() : null;
218
+ Blockly.Events.fire(new Blockly.Events.BlockChange(
219
+ this.sourceBlock_, 'field', this.name, oldValue, id));
220
+ }
221
+ this.variable_ = variable;
222
+ this.value_ = id;
223
+ this.setText(variable.name);
224
+ };
225
+
226
+ /**
227
+ * Check whether the given variable type is allowed on this field.
228
+ * @param {string} type The type to check.
229
+ * @return {boolean} True if the type is in the list of allowed types.
230
+ * @private
231
+ */
232
+ Blockly.FieldVariable.prototype.typeIsAllowed_ = function(type) {
233
+ var typeList = this.getVariableTypes_();
234
+ if (!typeList) {
235
+ return true; // If it's null, all types are valid.
236
+ }
237
+ for (var i = 0; i < typeList.length; i++) {
238
+ if (type == typeList[i]) {
239
+ return true;
240
+ }
241
+ }
242
+ return false;
243
+ };
244
+
245
+ /**
246
+ * Return a list of variable types to include in the dropdown.
247
+ * @return {!Array.<string>} Array of variable types.
248
+ * @throws {Error} if variableTypes is an empty array.
249
+ * @private
250
+ */
251
+ Blockly.FieldVariable.prototype.getVariableTypes_ = function() {
252
+ // TODO (#1513): Try to avoid calling this every time the field is edited.
253
+ var variableTypes = this.variableTypes;
254
+ if (variableTypes === null) {
255
+ // If variableTypes is null, return all variable types.
256
+ if (this.sourceBlock_) {
257
+ var workspace = this.sourceBlock_.workspace;
258
+ return workspace.getVariableTypes();
259
+ }
260
+ }
261
+ variableTypes = variableTypes || [''];
262
+ if (variableTypes.length == 0) {
263
+ // Throw an error if variableTypes is an empty list.
264
+ var name = this.getText();
265
+ throw new Error('\'variableTypes\' of field variable ' +
266
+ name + ' was an empty list');
267
+ }
268
+ return variableTypes;
269
+ };
270
+
271
+ /**
272
+ * Return a sorted list of variable names for variable dropdown menus.
273
+ * Include a special option at the end for creating a new variable name.
274
+ * @return {!Array.<string>} Array of variable names.
275
+ * @this {Blockly.FieldVariable}
276
+ */
277
+ Blockly.FieldVariable.dropdownCreate = function() {
278
+ if (!this.variable_) {
279
+ throw new Error('Tried to call dropdownCreate on a variable field with no' +
280
+ ' variable selected.');
281
+ }
282
+ var variableModelList = [];
283
+ var name = this.getText();
284
+ var workspace = null;
285
+ if (this.sourceBlock_) {
286
+ workspace = this.sourceBlock_.workspace;
287
+ }
288
+ if (workspace) {
289
+ var variableTypes = this.getVariableTypes_();
290
+ var variableModelList = [];
291
+ // Get a copy of the list, so that adding rename and new variable options
292
+ // doesn't modify the workspace's list.
293
+ for (var i = 0; i < variableTypes.length; i++) {
294
+ var variableType = variableTypes[i];
295
+ var variables = workspace.getVariablesOfType(variableType);
296
+ variableModelList = variableModelList.concat(variables);
297
+
298
+ var potentialVarMap = workspace.getPotentialVariableMap();
299
+ if (potentialVarMap) {
300
+ var potentialVars = potentialVarMap.getVariablesOfType(variableType);
301
+ variableModelList = variableModelList.concat(potentialVars);
302
+ }
303
+ }
304
+ }
305
+ variableModelList.sort(Blockly.VariableModel.compareByName);
306
+
307
+ var options = [];
308
+ for (var i = 0; i < variableModelList.length; i++) {
309
+ // Set the uuid as the internal representation of the variable.
310
+ options[i] = [variableModelList[i].name, variableModelList[i].getId()];
311
+ }
312
+ if (this.defaultType_ == Blockly.BROADCAST_MESSAGE_VARIABLE_TYPE) {
313
+ options.unshift(
314
+ [Blockly.Msg.NEW_BROADCAST_MESSAGE, Blockly.NEW_BROADCAST_MESSAGE_ID]);
315
+ } else {
316
+ // Scalar variables and lists have the same backing action, but the option
317
+ // text is different.
318
+ if (this.defaultType_ == Blockly.LIST_VARIABLE_TYPE) {
319
+ var renameText = Blockly.Msg.RENAME_LIST;
320
+ var deleteText = Blockly.Msg.DELETE_LIST;
321
+ } else {
322
+ var renameText = Blockly.Msg.RENAME_VARIABLE;
323
+ var deleteText = Blockly.Msg.DELETE_VARIABLE;
324
+ }
325
+ options.push([renameText, Blockly.RENAME_VARIABLE_ID]);
326
+ if (deleteText) {
327
+ options.push(
328
+ [
329
+ deleteText.replace('%1', name),
330
+ Blockly.DELETE_VARIABLE_ID
331
+ ]);
332
+ }
333
+ }
334
+
335
+ return options;
336
+ };
337
+
338
+ /**
339
+ * Handle the selection of an item in the variable dropdown menu.
340
+ * Special case the 'Rename variable...', 'Delete variable...',
341
+ * and 'New message...' options.
342
+ * In the rename case, prompt the user for a new name.
343
+ * @param {!goog.ui.Menu} menu The Menu component clicked.
344
+ * @param {!goog.ui.MenuItem} menuItem The MenuItem selected within menu.
345
+ */
346
+ Blockly.FieldVariable.prototype.onItemSelected = function(menu, menuItem) {
347
+ var id = menuItem.getValue();
348
+ if (this.sourceBlock_ && this.sourceBlock_.workspace) {
349
+ var workspace = this.sourceBlock_.workspace;
350
+ if (id == Blockly.RENAME_VARIABLE_ID) {
351
+ // Rename variable.
352
+ Blockly.Variables.renameVariable(workspace, this.variable_);
353
+ return;
354
+ } else if (id == Blockly.DELETE_VARIABLE_ID) {
355
+ // Delete variable.
356
+ workspace.deleteVariableById(this.variable_.getId());
357
+ return;
358
+ } else if (id == Blockly.NEW_BROADCAST_MESSAGE_ID) {
359
+ var thisField = this;
360
+ var updateField = function(varId) {
361
+ if (varId) {
362
+ thisField.setValue(varId);
363
+ }
364
+ };
365
+ Blockly.Variables.createVariable(workspace, updateField,
366
+ Blockly.BROADCAST_MESSAGE_VARIABLE_TYPE);
367
+ return;
368
+ }
369
+
370
+ // TODO (blockly #1529): Call any validation function, and allow it to override.
371
+ }
372
+ this.setValue(id);
373
+ };
374
+
375
+ /**
376
+ * Overrides referencesVariables(), indicating this field refers to a variable.
377
+ * @return {boolean} True.
378
+ * @package
379
+ * @override
380
+ */
381
+ Blockly.FieldVariable.prototype.referencesVariables = function() {
382
+ return true;
383
+ };
384
+
385
+ Blockly.Field.register('field_variable', Blockly.FieldVariable);
@@ -0,0 +1,185 @@
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 Variable getter field. Appears as a label but has a variable
23
+ * picker in the right-click menu.
24
+ * @author fenichel@google.com (Rachel Fenichel)
25
+ */
26
+ 'use strict';
27
+
28
+ goog.provide('Blockly.FieldVariableGetter');
29
+
30
+ goog.require('Blockly.Field');
31
+
32
+
33
+ /**
34
+ * Class for a variable getter field.
35
+ * @param {string} text The initial content of the field.
36
+ * @param {string} name Optional CSS class for the field's text.
37
+ * @param {string} opt_varType The type of variable this field is associated with.
38
+ * @extends {Blockly.FieldLabel}
39
+ * @constructor
40
+ *
41
+ */
42
+ Blockly.FieldVariableGetter = function(text, name, opt_varType) {
43
+ this.size_ = new goog.math.Size(Blockly.BlockSvg.FIELD_WIDTH,
44
+ Blockly.BlockSvg.FIELD_HEIGHT);
45
+ this.text_ = text;
46
+
47
+ /**
48
+ * Maximum characters of text to display before adding an ellipsis.
49
+ * Same for strings and numbers.
50
+ * @type {number}
51
+ */
52
+ this.maxDisplayLength = Blockly.BlockSvg.MAX_DISPLAY_LENGTH;
53
+
54
+ this.name_ = name;
55
+ this.variableType_ = opt_varType ? opt_varType : '';
56
+ };
57
+ goog.inherits(Blockly.FieldVariableGetter, Blockly.Field);
58
+
59
+ /**
60
+ * Construct a FieldVariableGetter from a JSON arg object,
61
+ * dereferencing any string table references.
62
+ * @param {!Object} options A JSON object with options (variable,
63
+ * variableTypes, and defaultType).
64
+ * @returns {!Blockly.FieldVariableGetter} The new field instance.
65
+ * @package
66
+ * @nocollapse
67
+ */
68
+ Blockly.FieldVariableGetter.fromJson = function(options) {
69
+ var varname = Blockly.utils.replaceMessageReferences(options['text']);
70
+ return new Blockly.FieldVariableGetter(varname, options['name'],
71
+ options['class'], options['variableType']);
72
+ };
73
+
74
+ /**
75
+ * Editable fields usually show some sort of UI for the user to change them.
76
+ * This field should be serialized, but only edited programmatically.
77
+ * @type {boolean}
78
+ * @public
79
+ */
80
+ Blockly.FieldVariableGetter.prototype.EDITABLE = false;
81
+
82
+ /**
83
+ * Serializable fields are saved by the XML renderer, non-serializable fields
84
+ * are not. This field should be serialized, but only edited programmatically.
85
+ * @type {boolean}
86
+ * @public
87
+ */
88
+ Blockly.FieldVariableGetter.prototype.SERIALIZABLE = true;
89
+
90
+ /**
91
+ * Install this field on a block.
92
+ */
93
+ Blockly.FieldVariableGetter.prototype.init = function() {
94
+ if (this.fieldGroup_) {
95
+ // Field has already been initialized once.
96
+ return;
97
+ }
98
+ Blockly.FieldVariableGetter.superClass_.init.call(this);
99
+ if (this.variable_) {
100
+ return; // Initialization already happened.
101
+ }
102
+ this.workspace_ = this.sourceBlock_.workspace;
103
+ var variable = Blockly.Variables.getOrCreateVariablePackage(
104
+ this.workspace_, null, this.text_, this.variableType_);
105
+ this.setValue(variable.getId());
106
+ };
107
+
108
+ /**
109
+ * Get the variable's ID.
110
+ * @return {string} Current variable's ID.
111
+ */
112
+ Blockly.FieldVariableGetter.prototype.getValue = function() {
113
+ return this.variable_ ? this.variable_.getId() : '';
114
+ };
115
+
116
+ /**
117
+ * Get the text from this field.
118
+ * @return {string} Current text.
119
+ */
120
+ Blockly.FieldVariableGetter.prototype.getText = function() {
121
+ return this.variable_ ? this.variable_.name : '';
122
+ };
123
+
124
+ /**
125
+ * Get the variable model for the variable associated with this field.
126
+ * Not guaranteed to be in the variable map on the workspace (e.g. if accessed
127
+ * after the variable has been deleted).
128
+ * @return {?Blockly.VariableModel} the selected variable, or null if none was
129
+ * selected.
130
+ * @package
131
+ */
132
+ Blockly.FieldVariableGetter.prototype.getVariable = function() {
133
+ return this.variable_;
134
+ };
135
+
136
+ Blockly.FieldVariableGetter.prototype.setValue = function(id) {
137
+ // What do I do when id is null? That happens when undoing a change event
138
+ // for the first time the value was set.
139
+ var workspace = this.sourceBlock_.workspace;
140
+ var variable = Blockly.Variables.getVariable(workspace, id);
141
+
142
+ if (!variable) {
143
+ throw new Error('Variable id doesn\'t point to a real variable! ID was ' +
144
+ id);
145
+ }
146
+
147
+ if (this.sourceBlock_ && Blockly.Events.isEnabled()) {
148
+ var oldValue = this.variable_ ? this.variable_.getId() : null;
149
+ Blockly.Events.fire(new Blockly.Events.BlockChange(
150
+ this.sourceBlock_, 'field', this.name, oldValue, variable.getId()));
151
+ }
152
+ this.variable_ = variable;
153
+ this.value_ = id;
154
+ this.setText(variable.name);
155
+ };
156
+
157
+ /**
158
+ * This field is editable, but only through the right-click menu.
159
+ * @private
160
+ */
161
+ Blockly.FieldVariableGetter.prototype.showEditor_ = function() {
162
+ // nop.
163
+ };
164
+
165
+ /**
166
+ * Add or remove the UI indicating if this field is editable or not.
167
+ * This field is editable, but only through the right-click menu.
168
+ * Suppress default editable behaviour.
169
+ */
170
+ Blockly.FieldVariableGetter.prototype.updateEditable = function() {
171
+ // nop.
172
+ };
173
+
174
+ /**
175
+ * Whether this field references any Blockly variables. If true it may need to
176
+ * be handled differently during serialization and deserialization. Subclasses
177
+ * may override this.
178
+ * @return {boolean} True if this field has any variable references.
179
+ * @package
180
+ */
181
+ Blockly.FieldVariableGetter.prototype.referencesVariables = function() {
182
+ return true;
183
+ };
184
+
185
+ Blockly.Field.register('field_variable_getter', Blockly.FieldVariableGetter);