@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,337 @@
1
+ /**
2
+ * @license
3
+ * Visual Blocks Editor
4
+ *
5
+ * Copyright 2011 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 Library to create tooltips for Blockly.
23
+ * First, call Blockly.Tooltip.init() after onload.
24
+ * Second, set the 'tooltip' property on any SVG element that needs a tooltip.
25
+ * If the tooltip is a string, then that message will be displayed.
26
+ * If the tooltip is an SVG element, then that object's tooltip will be used.
27
+ * Third, call Blockly.Tooltip.bindMouseEvents(e) passing the SVG element.
28
+ * @author fraser@google.com (Neil Fraser)
29
+ */
30
+ 'use strict';
31
+
32
+ /**
33
+ * @name Blockly.Tooltip
34
+ * @namespace
35
+ **/
36
+ goog.provide('Blockly.Tooltip');
37
+
38
+ goog.require('goog.dom');
39
+ goog.require('goog.dom.TagName');
40
+
41
+
42
+ /**
43
+ * Is a tooltip currently showing?
44
+ */
45
+ Blockly.Tooltip.visible = false;
46
+
47
+ /**
48
+ * Is someone else blocking the tooltip from being shown?
49
+ * @type {boolean}
50
+ * @private
51
+ */
52
+ Blockly.Tooltip.blocked_ = false;
53
+
54
+ /**
55
+ * Maximum width (in characters) of a tooltip.
56
+ */
57
+ Blockly.Tooltip.LIMIT = 50;
58
+
59
+ /**
60
+ * PID of suspended thread to clear tooltip on mouse out.
61
+ * @private
62
+ */
63
+ Blockly.Tooltip.mouseOutPid_ = 0;
64
+
65
+ /**
66
+ * PID of suspended thread to show the tooltip.
67
+ * @private
68
+ */
69
+ Blockly.Tooltip.showPid_ = 0;
70
+
71
+ /**
72
+ * Last observed X location of the mouse pointer (freezes when tooltip appears).
73
+ * @private
74
+ */
75
+ Blockly.Tooltip.lastX_ = 0;
76
+
77
+ /**
78
+ * Last observed Y location of the mouse pointer (freezes when tooltip appears).
79
+ * @private
80
+ */
81
+ Blockly.Tooltip.lastY_ = 0;
82
+
83
+ /**
84
+ * Current element being pointed at.
85
+ * @private
86
+ */
87
+ Blockly.Tooltip.element_ = null;
88
+
89
+ /**
90
+ * Once a tooltip has opened for an element, that element is 'poisoned' and
91
+ * cannot respawn a tooltip until the pointer moves over a different element.
92
+ * @private
93
+ */
94
+ Blockly.Tooltip.poisonedElement_ = null;
95
+
96
+ /**
97
+ * Horizontal offset between mouse cursor and tooltip.
98
+ */
99
+ Blockly.Tooltip.OFFSET_X = 0;
100
+
101
+ /**
102
+ * Vertical offset between mouse cursor and tooltip.
103
+ */
104
+ Blockly.Tooltip.OFFSET_Y = 10;
105
+
106
+ /**
107
+ * Radius mouse can move before killing tooltip.
108
+ */
109
+ Blockly.Tooltip.RADIUS_OK = 10;
110
+
111
+ /**
112
+ * Delay before tooltip appears.
113
+ */
114
+ Blockly.Tooltip.HOVER_MS = 750;
115
+
116
+ /**
117
+ * Horizontal padding between tooltip and screen edge.
118
+ */
119
+ Blockly.Tooltip.MARGINS = 5;
120
+
121
+ /**
122
+ * The HTML container. Set once by Blockly.Tooltip.createDom.
123
+ * @type {Element}
124
+ */
125
+ Blockly.Tooltip.DIV = null;
126
+
127
+ /**
128
+ * Create the tooltip div and inject it onto the page.
129
+ */
130
+ Blockly.Tooltip.createDom = function() {
131
+ if (Blockly.Tooltip.DIV) {
132
+ return; // Already created.
133
+ }
134
+ // Create an HTML container for popup overlays (e.g. editor widgets).
135
+ Blockly.Tooltip.DIV =
136
+ goog.dom.createDom(goog.dom.TagName.DIV, 'blocklyTooltipDiv');
137
+ document.body.appendChild(Blockly.Tooltip.DIV);
138
+ };
139
+
140
+ /**
141
+ * Binds the required mouse events onto an SVG element.
142
+ * @param {!Element} element SVG element onto which tooltip is to be bound.
143
+ */
144
+ Blockly.Tooltip.bindMouseEvents = function(element) {
145
+ Blockly.bindEvent_(element, 'mouseover', null,
146
+ Blockly.Tooltip.onMouseOver_);
147
+ Blockly.bindEvent_(element, 'mouseout', null,
148
+ Blockly.Tooltip.onMouseOut_);
149
+
150
+ // Don't use bindEvent_ for mousemove since that would create a
151
+ // corresponding touch handler, even though this only makes sense in the
152
+ // context of a mouseover/mouseout.
153
+ element.addEventListener('mousemove', Blockly.Tooltip.onMouseMove_, false);
154
+ };
155
+
156
+ /**
157
+ * Hide the tooltip if the mouse is over a different object.
158
+ * Initialize the tooltip to potentially appear for this object.
159
+ * @param {!Event} e Mouse event.
160
+ * @private
161
+ */
162
+ Blockly.Tooltip.onMouseOver_ = function(e) {
163
+ if (Blockly.Tooltip.blocked_) {
164
+ // Someone doesn't want us to show tooltips.
165
+ return;
166
+ }
167
+ // If the tooltip is an object, treat it as a pointer to the next object in
168
+ // the chain to look at. Terminate when a string or function is found.
169
+ var element = e.target;
170
+ while (!goog.isString(element.tooltip) && !goog.isFunction(element.tooltip)) {
171
+ element = element.tooltip;
172
+ }
173
+ if (Blockly.Tooltip.element_ != element) {
174
+ Blockly.Tooltip.hide();
175
+ Blockly.Tooltip.poisonedElement_ = null;
176
+ Blockly.Tooltip.element_ = element;
177
+ }
178
+ // Forget about any immediately preceding mouseOut event.
179
+ clearTimeout(Blockly.Tooltip.mouseOutPid_);
180
+ };
181
+
182
+ /**
183
+ * Hide the tooltip if the mouse leaves the object and enters the workspace.
184
+ * @param {!Event} _e Mouse event.
185
+ * @private
186
+ */
187
+ Blockly.Tooltip.onMouseOut_ = function(_e) {
188
+ if (Blockly.Tooltip.blocked_) {
189
+ // Someone doesn't want us to show tooltips.
190
+ return;
191
+ }
192
+ // Moving from one element to another (overlapping or with no gap) generates
193
+ // a mouseOut followed instantly by a mouseOver. Fork off the mouseOut
194
+ // event and kill it if a mouseOver is received immediately.
195
+ // This way the task only fully executes if mousing into the void.
196
+ Blockly.Tooltip.mouseOutPid_ = setTimeout(function() {
197
+ Blockly.Tooltip.element_ = null;
198
+ Blockly.Tooltip.poisonedElement_ = null;
199
+ Blockly.Tooltip.hide();
200
+ }, 1);
201
+ clearTimeout(Blockly.Tooltip.showPid_);
202
+ };
203
+
204
+ /**
205
+ * When hovering over an element, schedule a tooltip to be shown. If a tooltip
206
+ * is already visible, hide it if the mouse strays out of a certain radius.
207
+ * @param {!Event} e Mouse event.
208
+ * @private
209
+ */
210
+ Blockly.Tooltip.onMouseMove_ = function(e) {
211
+ if (!Blockly.Tooltip.element_ || !Blockly.Tooltip.element_.tooltip) {
212
+ // No tooltip here to show.
213
+ return;
214
+ } else if (Blockly.WidgetDiv.isVisible()) {
215
+ // Don't display a tooltip if a widget is open (tooltip would be under it).
216
+ return;
217
+ } else if (Blockly.Tooltip.blocked_) {
218
+ // Someone doesn't want us to show tooltips. We are probably handling a
219
+ // user gesture, such as a click or drag.
220
+ return;
221
+ }
222
+ if (Blockly.Tooltip.visible) {
223
+ // Compute the distance between the mouse position when the tooltip was
224
+ // shown and the current mouse position. Pythagorean theorem.
225
+ var dx = Blockly.Tooltip.lastX_ - e.pageX;
226
+ var dy = Blockly.Tooltip.lastY_ - e.pageY;
227
+ if (Math.sqrt(dx * dx + dy * dy) > Blockly.Tooltip.RADIUS_OK) {
228
+ Blockly.Tooltip.hide();
229
+ }
230
+ } else if (Blockly.Tooltip.poisonedElement_ != Blockly.Tooltip.element_) {
231
+ // The mouse moved, clear any previously scheduled tooltip.
232
+ clearTimeout(Blockly.Tooltip.showPid_);
233
+ // Maybe this time the mouse will stay put. Schedule showing of tooltip.
234
+ Blockly.Tooltip.lastX_ = e.pageX;
235
+ Blockly.Tooltip.lastY_ = e.pageY;
236
+ Blockly.Tooltip.showPid_ =
237
+ setTimeout(Blockly.Tooltip.show_, Blockly.Tooltip.HOVER_MS);
238
+ }
239
+ };
240
+
241
+ /**
242
+ * Hide the tooltip.
243
+ */
244
+ Blockly.Tooltip.hide = function() {
245
+ if (Blockly.Tooltip.visible) {
246
+ Blockly.Tooltip.visible = false;
247
+ if (Blockly.Tooltip.DIV) {
248
+ Blockly.Tooltip.DIV.style.display = 'none';
249
+ }
250
+ }
251
+ if (Blockly.Tooltip.showPid_) {
252
+ clearTimeout(Blockly.Tooltip.showPid_);
253
+ }
254
+ };
255
+
256
+ /**
257
+ * Hide any in-progress tooltips and block showing new tooltips until the next
258
+ * call to unblock().
259
+ * @package
260
+ */
261
+ Blockly.Tooltip.block = function() {
262
+ Blockly.Tooltip.hide();
263
+ Blockly.Tooltip.blocked_ = true;
264
+ };
265
+
266
+ /**
267
+ * Unblock tooltips: allow them to be scheduled and shown according to their own
268
+ * logic.
269
+ * @package
270
+ */
271
+ Blockly.Tooltip.unblock = function() {
272
+ Blockly.Tooltip.blocked_ = false;
273
+ };
274
+
275
+ /**
276
+ * Create the tooltip and show it.
277
+ * @private
278
+ */
279
+ Blockly.Tooltip.show_ = function() {
280
+ if (Blockly.Tooltip.blocked_) {
281
+ // Someone doesn't want us to show tooltips.
282
+ return;
283
+ }
284
+ Blockly.Tooltip.poisonedElement_ = Blockly.Tooltip.element_;
285
+ if (!Blockly.Tooltip.DIV) {
286
+ return;
287
+ }
288
+ // Erase all existing text.
289
+ goog.dom.removeChildren(/** @type {!Element} */ (Blockly.Tooltip.DIV));
290
+ // Get the new text.
291
+ var tip = Blockly.Tooltip.element_.tooltip;
292
+ while (goog.isFunction(tip)) {
293
+ tip = tip();
294
+ }
295
+ tip = Blockly.utils.wrap(tip, Blockly.Tooltip.LIMIT);
296
+ // Create new text, line by line.
297
+ var lines = tip.split('\n');
298
+ for (var i = 0; i < lines.length; i++) {
299
+ var div = document.createElement('div');
300
+ div.appendChild(document.createTextNode(lines[i]));
301
+ Blockly.Tooltip.DIV.appendChild(div);
302
+ }
303
+ var rtl = Blockly.Tooltip.element_.RTL;
304
+ var windowSize = goog.dom.getViewportSize();
305
+ // Display the tooltip.
306
+ Blockly.Tooltip.DIV.style.direction = rtl ? 'rtl' : 'ltr';
307
+ Blockly.Tooltip.DIV.style.display = 'block';
308
+ Blockly.Tooltip.visible = true;
309
+ // Move the tooltip to just below the cursor.
310
+ var anchorX = Blockly.Tooltip.lastX_;
311
+ if (rtl) {
312
+ anchorX -= Blockly.Tooltip.OFFSET_X + Blockly.Tooltip.DIV.offsetWidth;
313
+ } else {
314
+ anchorX += Blockly.Tooltip.OFFSET_X;
315
+ }
316
+ var anchorY = Blockly.Tooltip.lastY_ + Blockly.Tooltip.OFFSET_Y;
317
+
318
+ if (anchorY + Blockly.Tooltip.DIV.offsetHeight >
319
+ windowSize.height + window.scrollY) {
320
+ // Falling off the bottom of the screen; shift the tooltip up.
321
+ anchorY -= Blockly.Tooltip.DIV.offsetHeight + 2 * Blockly.Tooltip.OFFSET_Y;
322
+ }
323
+ if (rtl) {
324
+ // Prevent falling off left edge in RTL mode.
325
+ anchorX = Math.max(Blockly.Tooltip.MARGINS - window.scrollX, anchorX);
326
+ } else {
327
+ if (anchorX + Blockly.Tooltip.DIV.offsetWidth >
328
+ windowSize.width + window.scrollX - 2 * Blockly.Tooltip.MARGINS) {
329
+ // Falling off the right edge of the screen;
330
+ // clamp the tooltip on the edge.
331
+ anchorX = windowSize.width - Blockly.Tooltip.DIV.offsetWidth -
332
+ 2 * Blockly.Tooltip.MARGINS;
333
+ }
334
+ }
335
+ Blockly.Tooltip.DIV.style.top = anchorY + 'px';
336
+ Blockly.Tooltip.DIV.style.left = anchorX + 'px';
337
+ };
package/core/touch.js ADDED
@@ -0,0 +1,226 @@
1
+ /**
2
+ * @license
3
+ * Visual Blocks Editor
4
+ *
5
+ * Copyright 2016 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 Touch handling for Blockly.
23
+ * @author fenichel@google.com (Rachel Fenichel)
24
+ */
25
+ 'use strict';
26
+
27
+ /**
28
+ * @name Blockly.Touch
29
+ * @namespace
30
+ **/
31
+ goog.provide('Blockly.Touch');
32
+
33
+ goog.require('goog.events');
34
+ goog.require('goog.events.BrowserFeature');
35
+ goog.require('goog.string');
36
+
37
+
38
+ /**
39
+ * Which touch events are we currently paying attention to?
40
+ * @type {DOMString}
41
+ * @private
42
+ */
43
+ Blockly.Touch.touchIdentifier_ = null;
44
+
45
+ /**
46
+ * The TOUCH_MAP lookup dictionary specifies additional touch events to fire,
47
+ * in conjunction with mouse events.
48
+ * @type {Object}
49
+ */
50
+ Blockly.Touch.TOUCH_MAP = {};
51
+ if (goog.events.BrowserFeature.TOUCH_ENABLED) {
52
+ Blockly.Touch.TOUCH_MAP = {
53
+ 'mousedown': ['touchstart'],
54
+ 'mousemove': ['touchmove'],
55
+ 'mouseup': ['touchend', 'touchcancel']
56
+ };
57
+ }
58
+
59
+ /**
60
+ * PID of queued long-press task.
61
+ * @private
62
+ */
63
+ Blockly.longPid_ = 0;
64
+
65
+ /**
66
+ * Context menus on touch devices are activated using a long-press.
67
+ * Unfortunately the contextmenu touch event is currently (2015) only supported
68
+ * by Chrome. This function is fired on any touchstart event, queues a task,
69
+ * which after about a second opens the context menu. The tasks is killed
70
+ * if the touch event terminates early.
71
+ * @param {!Event} e Touch start event.
72
+ * @param {Blockly.Gesture} gesture The gesture that triggered this longStart.
73
+ * @private
74
+ */
75
+ Blockly.longStart_ = function(e, gesture) {
76
+ Blockly.longStop_();
77
+ // Punt on multitouch events.
78
+ if (e.changedTouches.length != 1) {
79
+ return;
80
+ }
81
+ Blockly.longPid_ = setTimeout(function() {
82
+ e.button = 2; // Simulate a right button click.
83
+ // e was a touch event. It needs to pretend to be a mouse event.
84
+ e.clientX = e.changedTouches[0].clientX;
85
+ e.clientY = e.changedTouches[0].clientY;
86
+
87
+ // Let the gesture route the right-click correctly.
88
+ if (gesture) {
89
+ gesture.handleRightClick(e);
90
+ }
91
+ }, Blockly.LONGPRESS);
92
+ };
93
+
94
+ /**
95
+ * Nope, that's not a long-press. Either touchend or touchcancel was fired,
96
+ * or a drag hath begun. Kill the queued long-press task.
97
+ * @private
98
+ */
99
+ Blockly.longStop_ = function() {
100
+ if (Blockly.longPid_) {
101
+ clearTimeout(Blockly.longPid_);
102
+ Blockly.longPid_ = 0;
103
+ }
104
+ };
105
+
106
+ /**
107
+ * Clear the touch identifier that tracks which touch stream to pay attention
108
+ * to. This ends the current drag/gesture and allows other pointers to be
109
+ * captured.
110
+ */
111
+ Blockly.Touch.clearTouchIdentifier = function() {
112
+ Blockly.Touch.touchIdentifier_ = null;
113
+ };
114
+
115
+ /**
116
+ * Decide whether Blockly should handle or ignore this event.
117
+ * Mouse and touch events require special checks because we only want to deal
118
+ * with one touch stream at a time. All other events should always be handled.
119
+ * @param {!Event} e The event to check.
120
+ * @return {boolean} True if this event should be passed through to the
121
+ * registered handler; false if it should be blocked.
122
+ */
123
+ Blockly.Touch.shouldHandleEvent = function(e) {
124
+ return !Blockly.Touch.isMouseOrTouchEvent(e) ||
125
+ Blockly.Touch.checkTouchIdentifier(e);
126
+ };
127
+
128
+ /**
129
+ * Get the touch identifier from the given event. If it was a mouse event, the
130
+ * identifier is the string 'mouse'.
131
+ * @param {!Event} e Mouse event or touch event.
132
+ * @return {string} The touch identifier from the first changed touch, if
133
+ * defined. Otherwise 'mouse'.
134
+ */
135
+ Blockly.Touch.getTouchIdentifierFromEvent = function(e) {
136
+ return (e.changedTouches && e.changedTouches[0] &&
137
+ e.changedTouches[0].identifier != undefined &&
138
+ e.changedTouches[0].identifier != null) ?
139
+ e.changedTouches[0].identifier : 'mouse';
140
+ };
141
+
142
+ /**
143
+ * Check whether the touch identifier on the event matches the current saved
144
+ * identifier. If there is no identifier, that means it's a mouse event and
145
+ * we'll use the identifier "mouse". This means we won't deal well with
146
+ * multiple mice being used at the same time. That seems okay.
147
+ * If the current identifier was unset, save the identifier from the
148
+ * event. This starts a drag/gesture, during which touch events with other
149
+ * identifiers will be silently ignored.
150
+ * @param {!Event} e Mouse event or touch event.
151
+ * @return {boolean} Whether the identifier on the event matches the current
152
+ * saved identifier.
153
+ */
154
+ Blockly.Touch.checkTouchIdentifier = function(e) {
155
+ var identifier = Blockly.Touch.getTouchIdentifierFromEvent(e);
156
+
157
+ // if (Blockly.touchIdentifier_ )is insufficient because Android touch
158
+ // identifiers may be zero.
159
+ if (Blockly.Touch.touchIdentifier_ != undefined &&
160
+ Blockly.Touch.touchIdentifier_ != null) {
161
+ // We're already tracking some touch/mouse event. Is this from the same
162
+ // source?
163
+ return Blockly.Touch.touchIdentifier_ == identifier;
164
+ }
165
+ if (e.type == 'mousedown' || e.type == 'touchstart') {
166
+ // No identifier set yet, and this is the start of a drag. Set it and
167
+ // return.
168
+ Blockly.Touch.touchIdentifier_ = identifier;
169
+ return true;
170
+ }
171
+ // There was no identifier yet, but this wasn't a start event so we're going
172
+ // to ignore it. This probably means that another drag finished while this
173
+ // pointer was down.
174
+ return false;
175
+ };
176
+
177
+ /**
178
+ * Set an event's clientX and clientY from its first changed touch. Use this to
179
+ * make a touch event work in a mouse event handler.
180
+ * @param {!Event} e A touch event.
181
+ */
182
+ Blockly.Touch.setClientFromTouch = function(e) {
183
+ if (Blockly.utils.startsWith(e.type, 'touch')) {
184
+ // Map the touch event's properties to the event.
185
+ var touchPoint = e.changedTouches[0];
186
+ e.clientX = touchPoint.clientX;
187
+ e.clientY = touchPoint.clientY;
188
+ }
189
+ };
190
+
191
+ /**
192
+ * Check whether a given event is a mouse or touch event.
193
+ * @param {!Event} e An event.
194
+ * @return {boolean} true if it is a mouse or touch event; false otherwise.
195
+ */
196
+ Blockly.Touch.isMouseOrTouchEvent = function(e) {
197
+ return Blockly.utils.startsWith(e.type, 'touch') ||
198
+ Blockly.utils.startsWith(e.type, 'mouse');
199
+ };
200
+
201
+ /**
202
+ * Split an event into an array of events, one per changed touch or mouse
203
+ * point.
204
+ * @param {!Event} e A mouse event or a touch event with one or more changed
205
+ * touches.
206
+ * @return {!Array.<!Event>} An array of mouse or touch events. Each touch
207
+ * event will have exactly one changed touch.
208
+ */
209
+ Blockly.Touch.splitEventByTouches = function(e) {
210
+ var events = [];
211
+ if (e.changedTouches) {
212
+ for (var i = 0; i < e.changedTouches.length; i++) {
213
+ var newEvent = {
214
+ type: e.type,
215
+ changedTouches: [e.changedTouches[i]],
216
+ target: e.target,
217
+ stopPropagation: function(){ e.stopPropagation(); },
218
+ preventDefault: function(){ e.preventDefault(); }
219
+ };
220
+ events[i] = newEvent;
221
+ }
222
+ } else {
223
+ events.push(e);
224
+ }
225
+ return events;
226
+ };