@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,309 @@
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 Icon picker input field.
23
+ * This is primarily for use in Scratch Horizontal blocks.
24
+ * Pops open a drop-down with icons; when an icon is selected, it replaces
25
+ * the icon (image field) in the original block.
26
+ * @author tmickel@mit.edu (Tim Mickel)
27
+ */
28
+ 'use strict';
29
+
30
+ goog.provide('Blockly.FieldIconMenu');
31
+
32
+ goog.require('Blockly.DropDownDiv');
33
+
34
+ /**
35
+ * Class for an icon menu field.
36
+ * @param {Object} icons List of icons. These take the same options as an Image Field.
37
+ * @extends {Blockly.Field}
38
+ * @constructor
39
+ */
40
+ Blockly.FieldIconMenu = function(icons) {
41
+ /** @type {object} */
42
+ this.icons_ = icons;
43
+ // Example:
44
+ // [{src: '...', width: 20, height: 20, alt: '...', value: 'machine_value'}, ...]
45
+ // First icon provides the default values.
46
+ var defaultValue = icons[0].value;
47
+ Blockly.FieldIconMenu.superClass_.constructor.call(this, defaultValue);
48
+ this.addArgType('iconmenu');
49
+ };
50
+ goog.inherits(Blockly.FieldIconMenu, Blockly.Field);
51
+
52
+ /**
53
+ * Construct a FieldIconMenu from a JSON arg object.
54
+ * @param {!Object} element A JSON object with options.
55
+ * @returns {!Blockly.FieldIconMenu} The new field instance.
56
+ * @package
57
+ * @nocollapse
58
+ */
59
+ Blockly.FieldIconMenu.fromJson = function(element) {
60
+ return new Blockly.FieldIconMenu(element['options']);
61
+ };
62
+
63
+ /**
64
+ * Fixed width of the drop-down, in px. Icon buttons will flow inside this width.
65
+ * @type {number}
66
+ * @const
67
+ */
68
+ Blockly.FieldIconMenu.DROPDOWN_WIDTH = 168;
69
+
70
+ /**
71
+ * Save the primary colour of the source block while the menu is open, for reset.
72
+ * @type {number|string}
73
+ * @private
74
+ */
75
+ Blockly.FieldIconMenu.savedPrimary_ = null;
76
+
77
+ /**
78
+ * Called when the field is placed on a block.
79
+ * @param {Block} block The owning block.
80
+ */
81
+ Blockly.FieldIconMenu.prototype.init = function(block) {
82
+ if (this.fieldGroup_) {
83
+ // Icon menu has already been initialized once.
84
+ return;
85
+ }
86
+ // Render the arrow icon
87
+ // Fixed sizes in px. Saved for creating the flip transform of the menu renders above the button.
88
+ var arrowSize = 12;
89
+ /** @type {Number} */
90
+ this.arrowX_ = 18;
91
+ /** @type {Number} */
92
+ this.arrowY_ = 10;
93
+ if (block.RTL) {
94
+ // In RTL, the icon position is flipped and rendered from the right (offset by width)
95
+ this.arrowX_ = -this.arrowX_ - arrowSize;
96
+ }
97
+ /** @type {Element} */
98
+ this.arrowIcon_ = Blockly.utils.createSvgElement('image', {
99
+ 'height': arrowSize + 'px',
100
+ 'width': arrowSize + 'px',
101
+ 'transform': 'translate(' + this.arrowX_ + ',' + this.arrowY_ + ')'
102
+ });
103
+ this.arrowIcon_.setAttributeNS('http://www.w3.org/1999/xlink',
104
+ 'xlink:href', Blockly.mainWorkspace.options.pathToMedia + 'dropdown-arrow.svg');
105
+ block.getSvgRoot().appendChild(this.arrowIcon_);
106
+ Blockly.FieldIconMenu.superClass_.init.call(this, block);
107
+ };
108
+
109
+ /**
110
+ * Mouse cursor style when over the hotspot that initiates the editor.
111
+ * @const
112
+ */
113
+ Blockly.FieldIconMenu.prototype.CURSOR = 'default';
114
+
115
+ /**
116
+ * Set the language-neutral value for this icon drop-down menu.
117
+ * @param {?string} newValue New value.
118
+ * @override
119
+ */
120
+ Blockly.FieldIconMenu.prototype.setValue = function(newValue) {
121
+ if (newValue === null || newValue === this.value_) {
122
+ return; // No change
123
+ }
124
+ if (this.sourceBlock_ && Blockly.Events.isEnabled()) {
125
+ Blockly.Events.fire(new Blockly.Events.Change(
126
+ this.sourceBlock_, 'field', this.name, this.value_, newValue));
127
+ }
128
+ this.value_ = newValue;
129
+ // Find the relevant icon in this.icons_ to get the image src.
130
+ this.setParentFieldImage(this.getSrcForValue(this.value_));
131
+ };
132
+
133
+ /**
134
+ * Find the parent block's FieldImage and set its src.
135
+ * @param {?string} src New src for the parent block FieldImage.
136
+ * @private
137
+ */
138
+ Blockly.FieldIconMenu.prototype.setParentFieldImage = function(src) {
139
+ // Only attempt if we have a set sourceBlock_ and parentBlock_
140
+ // It's possible that this function could be called before
141
+ // a parent block is set; in that case, fail silently.
142
+ if (this.sourceBlock_ && this.sourceBlock_.parentBlock_) {
143
+ var parentBlock = this.sourceBlock_.parentBlock_;
144
+ // Loop through all inputs' fields to find the first FieldImage
145
+ for (var i = 0, input; input = parentBlock.inputList[i]; i++) {
146
+ for (var j = 0, field; field = input.fieldRow[j]; j++) {
147
+ if (field instanceof Blockly.FieldImage) {
148
+ // Src for a FieldImage is stored in its value.
149
+ field.setValue(src);
150
+ return;
151
+ }
152
+ }
153
+ }
154
+ }
155
+ };
156
+
157
+ /**
158
+ * Get the language-neutral value from this drop-down menu.
159
+ * @return {string} Current language-neutral value.
160
+ */
161
+ Blockly.FieldIconMenu.prototype.getValue = function() {
162
+ return this.value_;
163
+ };
164
+
165
+ /**
166
+ * For a language-neutral value, get the src for the image that represents it.
167
+ * @param {string} value Language-neutral value to look up.
168
+ * @return {string} Src to image representing value
169
+ */
170
+ Blockly.FieldIconMenu.prototype.getSrcForValue = function(value) {
171
+ for (var i = 0, icon; icon = this.icons_[i]; i++) {
172
+ if (icon.value === value) {
173
+ return icon.src;
174
+ }
175
+ }
176
+ };
177
+
178
+ /**
179
+ * Show the drop-down menu for editing this field.
180
+ * @private
181
+ */
182
+ Blockly.FieldIconMenu.prototype.showEditor_ = function() {
183
+ // If there is an existing drop-down we own, this is a request to hide the drop-down.
184
+ if (Blockly.DropDownDiv.hideIfOwner(this)) {
185
+ return;
186
+ }
187
+ // If there is an existing drop-down someone else owns, hide it immediately and clear it.
188
+ Blockly.DropDownDiv.hideWithoutAnimation();
189
+ Blockly.DropDownDiv.clearContent();
190
+ // Populate the drop-down with the icons for this field.
191
+ var contentDiv = Blockly.DropDownDiv.getContentDiv();
192
+ // Accessibility properties
193
+ contentDiv.setAttribute('role', 'menu');
194
+ contentDiv.setAttribute('aria-haspopup', 'true');
195
+ for (var i = 0, icon; icon = this.icons_[i]; i++) {
196
+ // Icons with the type property placeholder take up space but don't have any functionality
197
+ // Use for special-case layouts
198
+ if (icon.type == 'placeholder') {
199
+ var placeholder = document.createElement('span');
200
+ placeholder.setAttribute('class', 'blocklyDropDownPlaceholder');
201
+ placeholder.style.width = icon.width + 'px';
202
+ placeholder.style.height = icon.height + 'px';
203
+ contentDiv.appendChild(placeholder);
204
+ continue;
205
+ }
206
+ var button = document.createElement('button');
207
+ button.setAttribute('id', ':' + i); // For aria-activedescendant
208
+ button.setAttribute('role', 'menuitem');
209
+ button.setAttribute('class', 'blocklyDropDownButton');
210
+ button.title = icon.alt;
211
+ button.style.width = icon.width + 'px';
212
+ button.style.height = icon.height + 'px';
213
+ var backgroundColor = this.sourceBlock_.getColour();
214
+ if (icon.value == this.getValue()) {
215
+ // This icon is selected, show it in a different colour
216
+ backgroundColor = this.sourceBlock_.getColourTertiary();
217
+ button.setAttribute('aria-selected', 'true');
218
+ }
219
+ button.style.backgroundColor = backgroundColor;
220
+ button.style.borderColor = this.sourceBlock_.getColourTertiary();
221
+ Blockly.bindEvent_(button, 'click', this, this.buttonClick_);
222
+ Blockly.bindEvent_(button, 'mouseup', this, this.buttonClick_);
223
+ // These are applied manually instead of using the :hover pseudoclass
224
+ // because Android has a bad long press "helper" menu and green highlight
225
+ // that we must prevent with ontouchstart preventDefault
226
+ Blockly.bindEvent_(button, 'mousedown', button, function(e) {
227
+ this.setAttribute('class', 'blocklyDropDownButton blocklyDropDownButtonHover');
228
+ e.preventDefault();
229
+ });
230
+ Blockly.bindEvent_(button, 'mouseover', button, function() {
231
+ this.setAttribute('class', 'blocklyDropDownButton blocklyDropDownButtonHover');
232
+ contentDiv.setAttribute('aria-activedescendant', this.id);
233
+ });
234
+ Blockly.bindEvent_(button, 'mouseout', button, function() {
235
+ this.setAttribute('class', 'blocklyDropDownButton');
236
+ contentDiv.removeAttribute('aria-activedescendant');
237
+ });
238
+ var buttonImg = document.createElement('img');
239
+ buttonImg.src = icon.src;
240
+ //buttonImg.alt = icon.alt;
241
+ // Upon click/touch, we will be able to get the clicked element as e.target
242
+ // Store a data attribute on all possible click targets so we can match it to the icon.
243
+ button.setAttribute('data-value', icon.value);
244
+ buttonImg.setAttribute('data-value', icon.value);
245
+ button.appendChild(buttonImg);
246
+ contentDiv.appendChild(button);
247
+ }
248
+ contentDiv.style.width = Blockly.FieldIconMenu.DROPDOWN_WIDTH + 'px';
249
+
250
+ Blockly.DropDownDiv.setColour(this.sourceBlock_.getColour(), this.sourceBlock_.getColourTertiary());
251
+ Blockly.DropDownDiv.setCategory(this.sourceBlock_.parentBlock_.getCategory());
252
+
253
+ // Update source block colour to look selected
254
+ this.savedPrimary_ = this.sourceBlock_.getColour();
255
+ this.sourceBlock_.setColour(this.sourceBlock_.getColourSecondary(),
256
+ this.sourceBlock_.getColourSecondary(),
257
+ this.sourceBlock_.getColourTertiary(),
258
+ this.sourceBlock_.getColourQuaternary());
259
+
260
+ var scale = this.sourceBlock_.workspace.scale;
261
+ // Offset for icon-type horizontal blocks.
262
+ var secondaryYOffset = (
263
+ -(Blockly.BlockSvg.MIN_BLOCK_Y * scale) - (Blockly.BlockSvg.FIELD_Y_OFFSET * scale)
264
+ );
265
+ var renderedPrimary = Blockly.DropDownDiv.showPositionedByBlock(
266
+ this, this.sourceBlock_, this.onHide_.bind(this), secondaryYOffset);
267
+ if (!renderedPrimary) {
268
+ // Adjust for rotation
269
+ var arrowX = this.arrowX_ + Blockly.DropDownDiv.ARROW_SIZE / 1.5 + 1;
270
+ var arrowY = this.arrowY_ + Blockly.DropDownDiv.ARROW_SIZE / 1.5;
271
+ // Flip the arrow on the button
272
+ this.arrowIcon_.setAttribute('transform',
273
+ 'translate(' + arrowX + ',' + arrowY + ') rotate(180)');}
274
+ };
275
+
276
+ /**
277
+ * Callback for when a button is clicked inside the drop-down.
278
+ * Should be bound to the FieldIconMenu.
279
+ * @param {Event} e DOM event for the click/touch
280
+ * @private
281
+ */
282
+ Blockly.FieldIconMenu.prototype.buttonClick_ = function(e) {
283
+ var value = e.target.getAttribute('data-value');
284
+ this.setValue(value);
285
+ Blockly.DropDownDiv.hide();
286
+ };
287
+
288
+ /**
289
+ * Callback for when the drop-down is hidden.
290
+ */
291
+ Blockly.FieldIconMenu.prototype.onHide_ = function() {
292
+ // Reset the button colour and clear accessibility properties
293
+ // Only attempt to do this reset if sourceBlock_ is not disposed.
294
+ // It could become disposed before an onHide_, for example,
295
+ // when a block is dragged from the flyout.
296
+ if (this.sourceBlock_) {
297
+ this.sourceBlock_.setColour(this.savedPrimary_,
298
+ this.sourceBlock_.getColourSecondary(),
299
+ this.sourceBlock_.getColourTertiary(),
300
+ this.sourceBlock_.getColourQuaternary());
301
+ }
302
+ Blockly.DropDownDiv.content_.removeAttribute('role');
303
+ Blockly.DropDownDiv.content_.removeAttribute('aria-haspopup');
304
+ Blockly.DropDownDiv.content_.removeAttribute('aria-activedescendant');
305
+ // Unflip the arrow if appropriate
306
+ this.arrowIcon_.setAttribute('transform', 'translate(' + this.arrowX_ + ',' + this.arrowY_ + ')');
307
+ };
308
+
309
+ Blockly.Field.register('field_iconmenu', Blockly.FieldIconMenu);
@@ -0,0 +1,200 @@
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 Image field. Used for pictures, icons, etc.
23
+ * @author fraser@google.com (Neil Fraser)
24
+ */
25
+ 'use strict';
26
+
27
+ goog.provide('Blockly.FieldImage');
28
+
29
+ goog.require('Blockly.Field');
30
+ goog.require('goog.dom');
31
+ goog.require('goog.math.Size');
32
+ goog.require('goog.userAgent');
33
+
34
+
35
+ /**
36
+ * Class for an image on a block.
37
+ * @param {string} src The URL of the image.
38
+ * @param {number} width Width of the image.
39
+ * @param {number} height Height of the image.
40
+ * @param {string=} opt_alt Optional alt text for when block is collapsed.
41
+ * @param {boolean} flip_rtl Whether to flip the icon in RTL
42
+ * @extends {Blockly.Field}
43
+ * @constructor
44
+ */
45
+ Blockly.FieldImage = function(src, width, height, opt_alt, flip_rtl) {
46
+ this.sourceBlock_ = null;
47
+
48
+ // Ensure height and width are numbers. Strings are bad at math.
49
+ this.height_ = Number(height);
50
+ this.width_ = Number(width);
51
+ this.size_ = new goog.math.Size(this.width_, this.height_);
52
+ this.text_ = opt_alt || '';
53
+ this.flipRTL_ = flip_rtl;
54
+ this.setValue(src);
55
+ };
56
+ goog.inherits(Blockly.FieldImage, Blockly.Field);
57
+
58
+ /**
59
+ * Construct a FieldImage from a JSON arg object,
60
+ * dereferencing any string table references.
61
+ * @param {!Object} options A JSON object with options (src, width, height, alt,
62
+ * and flipRtl/flip_rtl).
63
+ * @returns {!Blockly.FieldImage} The new field instance.
64
+ * @package
65
+ * @nocollapse
66
+ */
67
+ Blockly.FieldImage.fromJson = function(options) {
68
+ var src = Blockly.utils.replaceMessageReferences(options['src']);
69
+ var width = Number(Blockly.utils.replaceMessageReferences(options['width']));
70
+ var height =
71
+ Number(Blockly.utils.replaceMessageReferences(options['height']));
72
+ var alt = Blockly.utils.replaceMessageReferences(options['alt']);
73
+ var flip_rtl = !!options['flip_rtl'] || !!options['flipRtl'];
74
+ return new Blockly.FieldImage(src, width, height, alt, flip_rtl);
75
+ };
76
+
77
+ /**
78
+ * Editable fields are saved by the XML renderer, non-editable fields are not.
79
+ */
80
+ Blockly.FieldImage.prototype.EDITABLE = false;
81
+
82
+ /**
83
+ * Install this image on a block.
84
+ */
85
+ Blockly.FieldImage.prototype.init = function() {
86
+ if (this.fieldGroup_) {
87
+ // Image has already been initialized once.
88
+ return;
89
+ }
90
+ // Build the DOM.
91
+ /** @type {SVGElement} */
92
+ this.fieldGroup_ = Blockly.utils.createSvgElement('g', {}, null);
93
+ if (!this.visible_) {
94
+ this.fieldGroup_.style.display = 'none';
95
+ }
96
+ /** @type {SVGElement} */
97
+ this.imageElement_ = Blockly.utils.createSvgElement(
98
+ 'image',
99
+ {
100
+ 'height': this.height_ + 'px',
101
+ 'width': this.width_ + 'px'
102
+ },
103
+ this.fieldGroup_);
104
+ this.setValue(this.src_);
105
+ this.sourceBlock_.getSvgRoot().appendChild(this.fieldGroup_);
106
+
107
+ // Configure the field to be transparent with respect to tooltips.
108
+ this.setTooltip(this.sourceBlock_);
109
+ Blockly.Tooltip.bindMouseEvents(this.imageElement_);
110
+ };
111
+
112
+ /**
113
+ * Dispose of all DOM objects belonging to this text.
114
+ */
115
+ Blockly.FieldImage.prototype.dispose = function() {
116
+ goog.dom.removeNode(this.fieldGroup_);
117
+ this.fieldGroup_ = null;
118
+ this.imageElement_ = null;
119
+ };
120
+
121
+ /**
122
+ * Change the tooltip text for this field.
123
+ * @param {string|!Element} newTip Text for tooltip or a parent element to
124
+ * link to for its tooltip.
125
+ */
126
+ Blockly.FieldImage.prototype.setTooltip = function(newTip) {
127
+ this.imageElement_.tooltip = newTip;
128
+ };
129
+
130
+ /**
131
+ * Get the source URL of this image.
132
+ * @return {string} Current text.
133
+ * @override
134
+ */
135
+ Blockly.FieldImage.prototype.getValue = function() {
136
+ return this.src_;
137
+ };
138
+
139
+ /**
140
+ * Set the source URL of this image.
141
+ * @param {?string} src New source.
142
+ * @override
143
+ */
144
+ Blockly.FieldImage.prototype.setValue = function(src) {
145
+ if (src === null) {
146
+ // No change if null.
147
+ return;
148
+ }
149
+ this.src_ = src;
150
+ if (this.imageElement_) {
151
+ // Extension blocks can't rely on having access to pathToMedia, so we allow this fake URL
152
+ // protocol instead.
153
+ var mediaPrefix = 'media://';
154
+ if (src.startsWith(mediaPrefix)) {
155
+ var pathToMedia = this.sourceBlock_.workspace.options.pathToMedia;
156
+ src = pathToMedia + src.substring(mediaPrefix.length);
157
+ }
158
+ this.imageElement_.setAttributeNS('http://www.w3.org/1999/xlink',
159
+ 'xlink:href', src || '');
160
+ }
161
+ };
162
+
163
+ /**
164
+ * Get whether to flip this image in RTL
165
+ * @return {boolean} True if we should flip in RTL.
166
+ */
167
+ Blockly.FieldImage.prototype.getFlipRTL = function() {
168
+ return this.flipRTL_;
169
+ };
170
+
171
+ /**
172
+ * Set the alt text of this image.
173
+ * @param {?string} alt New alt text.
174
+ * @override
175
+ */
176
+ Blockly.FieldImage.prototype.setText = function(alt) {
177
+ if (alt === null) {
178
+ // No change if null.
179
+ return;
180
+ }
181
+ this.text_ = alt;
182
+ };
183
+
184
+ /**
185
+ * Images are fixed width, no need to render.
186
+ * @private
187
+ */
188
+ Blockly.FieldImage.prototype.render_ = function() {
189
+ // NOP
190
+ };
191
+
192
+ /**
193
+ * Images are fixed width, no need to update.
194
+ * @private
195
+ */
196
+ Blockly.FieldImage.prototype.updateWidth = function() {
197
+ // NOP
198
+ };
199
+
200
+ Blockly.Field.register('field_image', Blockly.FieldImage);
@@ -0,0 +1,136 @@
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 Non-editable text field. Used for titles, labels, etc.
23
+ * @author fraser@google.com (Neil Fraser)
24
+ */
25
+ 'use strict';
26
+
27
+ goog.provide('Blockly.FieldLabel');
28
+
29
+ goog.require('Blockly.Field');
30
+ goog.require('Blockly.Tooltip');
31
+ goog.require('goog.dom');
32
+ goog.require('goog.math.Size');
33
+ goog.require('goog.userAgent');
34
+
35
+
36
+ /**
37
+ * Class for a non-editable field.
38
+ * @param {string} text The initial content of the field.
39
+ * @param {string=} opt_class Optional CSS class for the field's text.
40
+ * @extends {Blockly.Field}
41
+ * @constructor
42
+ */
43
+ Blockly.FieldLabel = function(text, opt_class) {
44
+ this.size_ = new goog.math.Size(0, 0);
45
+ this.class_ = opt_class;
46
+ this.setValue(text);
47
+ };
48
+ goog.inherits(Blockly.FieldLabel, Blockly.Field);
49
+
50
+ /**
51
+ * Construct a FieldLabel from a JSON arg object,
52
+ * dereferencing any string table references.
53
+ * @param {!Object} options A JSON object with options (text, and class).
54
+ * @returns {!Blockly.FieldLabel} The new field instance.
55
+ * @package
56
+ * @nocollapse
57
+ */
58
+ Blockly.FieldLabel.fromJson = function(options) {
59
+ var text = Blockly.utils.replaceMessageReferences(options['text']);
60
+ return new Blockly.FieldLabel(text, options['class']);
61
+ };
62
+
63
+ /**
64
+ * Editable fields usually show some sort of UI for the user to change them.
65
+ * @type {boolean}
66
+ * @public
67
+ */
68
+ Blockly.FieldLabel.prototype.EDITABLE = false;
69
+
70
+ /**
71
+ * Serializable fields are saved by the XML renderer, non-serializable fields
72
+ * are not. Editable fields should be serialized.
73
+ * @type {boolean}
74
+ * @public
75
+ */
76
+ Blockly.FieldLabel.prototype.SERIALIZABLE = false;
77
+
78
+ /**
79
+ * Install this text on a block.
80
+ */
81
+ Blockly.FieldLabel.prototype.init = function() {
82
+ if (this.textElement_) {
83
+ // Text has already been initialized once.
84
+ return;
85
+ }
86
+ // Build the DOM.
87
+ this.textElement_ = Blockly.utils.createSvgElement('text',
88
+ {
89
+ 'class': 'blocklyText',
90
+ 'y': Blockly.BlockSvg.FIELD_TOP_PADDING,
91
+ 'text-anchor': 'middle',
92
+ 'dominant-baseline': 'middle',
93
+ 'dy': goog.userAgent.EDGE_OR_IE ? Blockly.Field.IE_TEXT_OFFSET : '0'
94
+ }, null);
95
+ if (this.class_) {
96
+ Blockly.utils.addClass(this.textElement_, this.class_);
97
+ }
98
+ if (!this.visible_) {
99
+ this.textElement_.style.display = 'none';
100
+ }
101
+ this.sourceBlock_.getSvgRoot().appendChild(this.textElement_);
102
+
103
+ // Configure the field to be transparent with respect to tooltips.
104
+ this.textElement_.tooltip = this.sourceBlock_;
105
+ Blockly.Tooltip.bindMouseEvents(this.textElement_);
106
+ // Force a render.
107
+ this.render_();
108
+ };
109
+
110
+ /**
111
+ * Dispose of all DOM objects belonging to this text.
112
+ */
113
+ Blockly.FieldLabel.prototype.dispose = function() {
114
+ goog.dom.removeNode(this.textElement_);
115
+ this.textElement_ = null;
116
+ };
117
+
118
+ /**
119
+ * Gets the group element for this field.
120
+ * Used for measuring the size and for positioning.
121
+ * @return {!Element} The group element.
122
+ */
123
+ Blockly.FieldLabel.prototype.getSvgRoot = function() {
124
+ return /** @type {!Element} */ (this.textElement_);
125
+ };
126
+
127
+ /**
128
+ * Change the tooltip text for this field.
129
+ * @param {string|!Element} newTip Text for tooltip or a parent element to
130
+ * link to for its tooltip.
131
+ */
132
+ Blockly.FieldLabel.prototype.setTooltip = function(newTip) {
133
+ this.textElement_.tooltip = newTip;
134
+ };
135
+
136
+ Blockly.Field.register('field_label', Blockly.FieldLabel);