blockly 7.20211209.4 → 8.0.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 (262) hide show
  1. package/blockly.d.ts +18963 -18432
  2. package/blockly.min.js +852 -844
  3. package/blockly_compressed.js +669 -664
  4. package/blockly_compressed.js.map +1 -1
  5. package/blocks/blocks.js +47 -0
  6. package/blocks/colour.js +13 -3
  7. package/blocks/lists.js +22 -13
  8. package/blocks/logic.js +13 -3
  9. package/blocks/loops.js +24 -11
  10. package/blocks/math.js +12 -3
  11. package/blocks/procedures.js +41 -27
  12. package/blocks/text.js +22 -13
  13. package/blocks/variables.js +14 -3
  14. package/blocks/variables_dynamic.js +13 -3
  15. package/blocks_compressed.js +146 -141
  16. package/blocks_compressed.js.map +1 -1
  17. package/core/block.js +1869 -1814
  18. package/core/block_drag_surface.js +201 -200
  19. package/core/block_dragger.js +377 -373
  20. package/core/block_svg.js +1593 -1479
  21. package/core/blockly.js +8 -22
  22. package/core/blocks.js +9 -2
  23. package/core/browser_events.js +22 -5
  24. package/core/bubble.js +841 -797
  25. package/core/bubble_dragger.js +213 -206
  26. package/core/bump_objects.js +2 -2
  27. package/core/clipboard.js +9 -9
  28. package/core/comment.js +353 -332
  29. package/core/common.js +46 -17
  30. package/core/component_manager.js +181 -174
  31. package/core/config.js +87 -0
  32. package/core/connection.js +595 -584
  33. package/core/connection_checker.js +242 -244
  34. package/core/connection_db.js +235 -230
  35. package/core/contextmenu.js +9 -6
  36. package/core/contextmenu_items.js +1 -2
  37. package/core/contextmenu_registry.js +93 -89
  38. package/core/css.js +474 -474
  39. package/core/delete_area.js +45 -42
  40. package/core/drag_target.js +57 -56
  41. package/core/dropdowndiv.js +153 -163
  42. package/core/events/events.js +2 -2
  43. package/core/events/events_abstract.js +89 -77
  44. package/core/events/events_block_base.js +37 -36
  45. package/core/events/events_block_change.js +130 -124
  46. package/core/events/events_block_create.js +73 -71
  47. package/core/events/events_block_delete.js +84 -82
  48. package/core/events/events_block_drag.js +50 -49
  49. package/core/events/events_block_move.js +147 -140
  50. package/core/events/events_bubble_open.js +51 -50
  51. package/core/events/events_click.js +48 -44
  52. package/core/events/events_comment_base.js +72 -69
  53. package/core/events/events_comment_change.js +63 -61
  54. package/core/events/events_comment_create.js +44 -42
  55. package/core/events/events_comment_delete.js +42 -40
  56. package/core/events/events_comment_move.js +106 -104
  57. package/core/events/events_marker_move.js +65 -64
  58. package/core/events/events_selected.js +46 -45
  59. package/core/events/events_theme_change.js +36 -35
  60. package/core/events/events_toolbox_item_select.js +46 -45
  61. package/core/events/events_trashcan_open.js +37 -36
  62. package/core/events/events_ui.js +47 -46
  63. package/core/events/events_ui_base.js +30 -29
  64. package/core/events/events_var_base.js +37 -36
  65. package/core/events/events_var_create.js +50 -48
  66. package/core/events/events_var_delete.js +50 -48
  67. package/core/events/events_var_rename.js +51 -49
  68. package/core/events/events_viewport.js +66 -65
  69. package/core/events/utils.js +29 -14
  70. package/core/events/workspace_events.js +49 -55
  71. package/core/extensions.js +4 -3
  72. package/core/field.js +1061 -997
  73. package/core/field_angle.js +462 -442
  74. package/core/field_checkbox.js +194 -182
  75. package/core/field_colour.js +519 -505
  76. package/core/field_dropdown.js +617 -598
  77. package/core/field_image.js +229 -220
  78. package/core/field_label.js +102 -91
  79. package/core/field_label_serializable.js +42 -41
  80. package/core/field_multilineinput.js +372 -358
  81. package/core/field_number.js +272 -253
  82. package/core/field_textinput.js +499 -467
  83. package/core/field_variable.js +458 -420
  84. package/core/flyout_base.js +1005 -952
  85. package/core/flyout_button.js +277 -260
  86. package/core/flyout_horizontal.js +304 -302
  87. package/core/flyout_metrics_manager.js +64 -64
  88. package/core/flyout_vertical.js +306 -300
  89. package/core/generator.js +459 -446
  90. package/core/gesture.js +829 -813
  91. package/core/grid.js +166 -163
  92. package/core/icon.js +168 -159
  93. package/core/inject.js +7 -5
  94. package/core/input.js +257 -248
  95. package/core/insertion_marker_manager.js +655 -624
  96. package/core/internal_constants.js +0 -129
  97. package/core/keyboard_nav/ast_node.js +605 -596
  98. package/core/keyboard_nav/basic_cursor.js +166 -165
  99. package/core/keyboard_nav/cursor.js +99 -97
  100. package/core/keyboard_nav/marker.js +83 -79
  101. package/core/keyboard_nav/tab_navigate_cursor.js +18 -23
  102. package/core/marker_manager.js +153 -141
  103. package/core/menu.js +377 -372
  104. package/core/menuitem.js +223 -217
  105. package/core/metrics_manager.js +403 -390
  106. package/core/mutator.js +468 -437
  107. package/core/names.js +229 -188
  108. package/core/options.js +290 -284
  109. package/core/procedures.js +29 -17
  110. package/core/registry.js +19 -16
  111. package/core/rendered_connection.js +482 -463
  112. package/core/renderers/common/block_rendering.js +9 -3
  113. package/core/renderers/common/constants.js +1119 -1112
  114. package/core/renderers/common/debug.js +14 -0
  115. package/core/renderers/common/debugger.js +338 -316
  116. package/core/renderers/common/drawer.js +380 -370
  117. package/core/renderers/common/i_path_object.js +2 -2
  118. package/core/renderers/common/info.js +626 -618
  119. package/core/renderers/common/marker_svg.js +579 -541
  120. package/core/renderers/common/path_object.js +203 -200
  121. package/core/renderers/common/renderer.js +220 -218
  122. package/core/renderers/geras/constants.js +36 -36
  123. package/core/renderers/geras/drawer.js +155 -147
  124. package/core/renderers/geras/highlight_constants.js +244 -238
  125. package/core/renderers/geras/highlighter.js +231 -179
  126. package/core/renderers/geras/info.js +392 -369
  127. package/core/renderers/geras/measurables/inline_input.js +25 -19
  128. package/core/renderers/geras/measurables/statement_input.js +23 -17
  129. package/core/renderers/geras/path_object.js +106 -121
  130. package/core/renderers/geras/renderer.js +96 -98
  131. package/core/renderers/measurables/base.js +30 -18
  132. package/core/renderers/measurables/bottom_row.js +83 -80
  133. package/core/renderers/measurables/connection.js +22 -15
  134. package/core/renderers/measurables/external_value_input.js +35 -22
  135. package/core/renderers/measurables/field.js +35 -20
  136. package/core/renderers/measurables/hat.js +18 -13
  137. package/core/renderers/measurables/icon.js +24 -17
  138. package/core/renderers/measurables/in_row_spacer.js +15 -13
  139. package/core/renderers/measurables/inline_input.js +43 -33
  140. package/core/renderers/measurables/input_connection.js +41 -28
  141. package/core/renderers/measurables/input_row.js +50 -44
  142. package/core/renderers/measurables/jagged_edge.js +14 -12
  143. package/core/renderers/measurables/next_connection.js +16 -14
  144. package/core/renderers/measurables/output_connection.js +26 -20
  145. package/core/renderers/measurables/previous_connection.js +16 -15
  146. package/core/renderers/measurables/round_corner.js +20 -18
  147. package/core/renderers/measurables/row.js +184 -168
  148. package/core/renderers/measurables/spacer_row.js +38 -23
  149. package/core/renderers/measurables/square_corner.js +18 -16
  150. package/core/renderers/measurables/statement_input.js +23 -20
  151. package/core/renderers/measurables/top_row.js +88 -85
  152. package/core/renderers/minimalist/constants.js +8 -7
  153. package/core/renderers/minimalist/drawer.js +11 -10
  154. package/core/renderers/minimalist/info.js +18 -18
  155. package/core/renderers/minimalist/renderer.js +40 -39
  156. package/core/renderers/thrasos/info.js +258 -248
  157. package/core/renderers/thrasos/renderer.js +20 -20
  158. package/core/renderers/zelos/constants.js +898 -873
  159. package/core/renderers/zelos/drawer.js +186 -169
  160. package/core/renderers/zelos/info.js +502 -479
  161. package/core/renderers/zelos/marker_svg.js +129 -115
  162. package/core/renderers/zelos/measurables/bottom_row.js +31 -30
  163. package/core/renderers/zelos/measurables/inputs.js +22 -21
  164. package/core/renderers/zelos/measurables/row_elements.js +14 -13
  165. package/core/renderers/zelos/measurables/top_row.js +34 -33
  166. package/core/renderers/zelos/path_object.js +181 -180
  167. package/core/renderers/zelos/renderer.js +91 -92
  168. package/core/scrollbar.js +759 -713
  169. package/core/scrollbar_pair.js +250 -245
  170. package/core/serialization/blocks.js +19 -9
  171. package/core/serialization/workspaces.js +3 -2
  172. package/core/shortcut_registry.js +286 -277
  173. package/core/sprites.js +31 -0
  174. package/core/theme.js +135 -141
  175. package/core/theme_manager.js +147 -143
  176. package/core/toolbox/category.js +602 -576
  177. package/core/toolbox/collapsible_category.js +226 -227
  178. package/core/toolbox/separator.js +70 -61
  179. package/core/toolbox/toolbox.js +934 -927
  180. package/core/toolbox/toolbox_item.js +115 -99
  181. package/core/tooltip.js +108 -35
  182. package/core/touch.js +8 -3
  183. package/core/touch_gesture.js +254 -251
  184. package/core/trashcan.js +606 -595
  185. package/core/utils/coordinate.js +97 -95
  186. package/core/utils/dom.js +2 -2
  187. package/core/utils/global.js +2 -0
  188. package/core/utils/rect.js +41 -37
  189. package/core/utils/sentinel.js +25 -0
  190. package/core/utils/size.js +30 -27
  191. package/core/utils/svg.js +18 -16
  192. package/core/variable_map.js +325 -341
  193. package/core/variable_model.js +55 -54
  194. package/core/variables.js +9 -2
  195. package/core/variables_dynamic.js +3 -1
  196. package/core/warning.js +126 -120
  197. package/core/widgetdiv.js +4 -4
  198. package/core/workspace.js +685 -664
  199. package/core/workspace_audio.js +124 -118
  200. package/core/workspace_comment.js +308 -298
  201. package/core/workspace_comment_svg.js +1029 -951
  202. package/core/workspace_drag_surface_svg.js +147 -140
  203. package/core/workspace_dragger.js +70 -71
  204. package/core/workspace_svg.js +2322 -2297
  205. package/core/xml.js +30 -20
  206. package/core/zoom_controls.js +431 -439
  207. package/dart_compressed.js +40 -43
  208. package/dart_compressed.js.map +1 -1
  209. package/generators/dart/colour.js +56 -64
  210. package/generators/dart/lists.js +61 -50
  211. package/generators/dart/math.js +160 -148
  212. package/generators/dart/text.js +83 -61
  213. package/generators/javascript/colour.js +37 -34
  214. package/generators/javascript/lists.js +50 -43
  215. package/generators/javascript/math.js +123 -139
  216. package/generators/javascript/text.js +67 -81
  217. package/generators/lua/colour.js +25 -23
  218. package/generators/lua/lists.js +97 -69
  219. package/generators/lua/logic.js +1 -2
  220. package/generators/lua/math.js +182 -144
  221. package/generators/lua/text.js +116 -99
  222. package/generators/php/colour.js +38 -32
  223. package/generators/php/lists.js +109 -89
  224. package/generators/php/math.js +90 -81
  225. package/generators/php/text.js +63 -61
  226. package/generators/python/colour.js +18 -18
  227. package/generators/python/lists.js +38 -30
  228. package/generators/python/loops.js +12 -8
  229. package/generators/python/math.js +104 -106
  230. package/generators/python/text.js +34 -30
  231. package/javascript_compressed.js +37 -39
  232. package/javascript_compressed.js.map +1 -1
  233. package/lua_compressed.js +39 -42
  234. package/lua_compressed.js.map +1 -1
  235. package/msg/az.js +2 -2
  236. package/msg/be.js +4 -4
  237. package/msg/cs.js +15 -15
  238. package/msg/de.js +1 -1
  239. package/msg/diq.js +1 -1
  240. package/msg/eo.js +1 -1
  241. package/msg/es.js +1 -1
  242. package/msg/fa.js +1 -1
  243. package/msg/fr.js +4 -4
  244. package/msg/he.js +1 -1
  245. package/msg/hr.js +2 -2
  246. package/msg/hy.js +2 -2
  247. package/msg/id.js +12 -12
  248. package/msg/inh.js +14 -14
  249. package/msg/ja.js +7 -7
  250. package/msg/lv.js +29 -29
  251. package/msg/pa.js +3 -3
  252. package/msg/smn.js +436 -0
  253. package/msg/te.js +1 -1
  254. package/msg/yue.js +1 -1
  255. package/msg/zh-hans.js +3 -3
  256. package/msg/zh-hant.js +3 -3
  257. package/package.json +7 -6
  258. package/php_compressed.js +38 -42
  259. package/php_compressed.js.map +1 -1
  260. package/python_compressed.js +26 -25
  261. package/python_compressed.js.map +1 -1
  262. package/blocks/all.js +0 -23
@@ -30,128 +30,144 @@ const {WorkspaceSvg} = goog.requireType('Blockly.WorkspaceSvg');
30
30
 
31
31
  /**
32
32
  * Class for an item in the toolbox.
33
- * @param {!toolbox.ToolboxItemInfo} toolboxItemDef The JSON defining the
34
- * toolbox item.
35
- * @param {!IToolbox} toolbox The toolbox that holds the toolbox item.
36
- * @param {ICollapsibleToolboxItem=} opt_parent The parent toolbox item
37
- * or null if the category does not have a parent.
38
- * @constructor
39
33
  * @implements {IToolboxItem}
40
34
  * @alias Blockly.ToolboxItem
41
35
  */
42
- const ToolboxItem = function(toolboxItemDef, toolbox, opt_parent) {
36
+ class ToolboxItem {
43
37
  /**
44
- * The id for the category.
45
- * @type {string}
46
- * @protected
38
+ * @param {!toolbox.ToolboxItemInfo} toolboxItemDef The JSON defining
39
+ * the toolbox item.
40
+ * @param {!IToolbox} toolbox The toolbox that holds the toolbox item.
41
+ * @param {ICollapsibleToolboxItem=} opt_parent The parent toolbox item
42
+ * or null if the category does not have a parent.
47
43
  */
48
- this.id_ = toolboxItemDef['toolboxitemid'] || idGenerator.getNextUniqueId();
44
+ constructor(toolboxItemDef, toolbox, opt_parent) {
45
+ /**
46
+ * The id for the category.
47
+ * @type {string}
48
+ * @protected
49
+ */
50
+ this.id_ = toolboxItemDef['toolboxitemid'] || idGenerator.getNextUniqueId();
51
+
52
+ /**
53
+ * The parent of the category.
54
+ * @type {?ICollapsibleToolboxItem}
55
+ * @protected
56
+ */
57
+ this.parent_ = opt_parent || null;
58
+
59
+ /**
60
+ * The level that the category is nested at.
61
+ * @type {number}
62
+ * @protected
63
+ */
64
+ this.level_ = this.parent_ ? this.parent_.getLevel() + 1 : 0;
65
+
66
+ /**
67
+ * The JSON definition of the toolbox item.
68
+ * @type {?toolbox.ToolboxItemInfo}
69
+ * @protected
70
+ */
71
+ this.toolboxItemDef_ = toolboxItemDef;
72
+
73
+ /**
74
+ * The toolbox this category belongs to.
75
+ * @type {!IToolbox}
76
+ * @protected
77
+ */
78
+ this.parentToolbox_ = toolbox;
79
+
80
+ /**
81
+ * The workspace of the parent toolbox.
82
+ * @type {!WorkspaceSvg}
83
+ * @protected
84
+ */
85
+ this.workspace_ = this.parentToolbox_.getWorkspace();
86
+ }
49
87
 
50
88
  /**
51
- * The parent of the category.
52
- * @type {?ICollapsibleToolboxItem}
53
- * @protected
89
+ * Initializes the toolbox item.
90
+ * This includes creating the DOM and updating the state of any items based
91
+ * on the info object.
92
+ * @public
54
93
  */
55
- this.parent_ = opt_parent || null;
94
+ init() {
95
+ // No-op by default.
96
+ }
56
97
 
57
98
  /**
58
- * The level that the category is nested at.
59
- * @type {number}
60
- * @protected
99
+ * Gets the div for the toolbox item.
100
+ * @return {?Element} The div for the toolbox item.
101
+ * @public
61
102
  */
62
- this.level_ = this.parent_ ? this.parent_.getLevel() + 1 : 0;
103
+ getDiv() {
104
+ return null;
105
+ }
63
106
 
64
107
  /**
65
- * The JSON definition of the toolbox item.
66
- * @type {!toolbox.ToolboxItemInfo}
67
- * @protected
108
+ * Gets the HTML element that is clickable.
109
+ * The parent toolbox element receives clicks. The parent toolbox will add an
110
+ * ID to this element so it can pass the onClick event to the correct
111
+ * toolboxItem.
112
+ * @return {?Element} The HTML element that receives clicks, or null if this
113
+ * item should not receive clicks.
114
+ * @public
68
115
  */
69
- this.toolboxItemDef_ = toolboxItemDef;
116
+ getClickTarget() {
117
+ return null;
118
+ }
70
119
 
71
120
  /**
72
- * The toolbox this category belongs to.
73
- * @type {!IToolbox}
74
- * @protected
121
+ * Gets a unique identifier for this toolbox item.
122
+ * @return {string} The ID for the toolbox item.
123
+ * @public
75
124
  */
76
- this.parentToolbox_ = toolbox;
125
+ getId() {
126
+ return this.id_;
127
+ }
77
128
 
78
129
  /**
79
- * The workspace of the parent toolbox.
80
- * @type {!WorkspaceSvg}
81
- * @protected
130
+ * Gets the parent if the toolbox item is nested.
131
+ * @return {?IToolboxItem} The parent toolbox item, or null if
132
+ * this toolbox item is not nested.
133
+ * @public
82
134
  */
83
- this.workspace_ = this.parentToolbox_.getWorkspace();
84
- };
135
+ getParent() {
136
+ return null;
137
+ }
85
138
 
86
- /**
87
- * Initializes the toolbox item.
88
- * This includes creating the DOM and updating the state of any items based
89
- * on the info object.
90
- * @public
91
- */
92
- ToolboxItem.prototype.init = function() {
93
- // No-op by default.
94
- };
95
-
96
- /**
97
- * Gets the div for the toolbox item.
98
- * @return {?Element} The div for the toolbox item.
99
- * @public
100
- */
101
- ToolboxItem.prototype.getDiv = function() {
102
- return null;
103
- };
104
-
105
- /**
106
- * Gets a unique identifier for this toolbox item.
107
- * @return {string} The ID for the toolbox item.
108
- * @public
109
- */
110
- ToolboxItem.prototype.getId = function() {
111
- return this.id_;
112
- };
113
-
114
- /**
115
- * Gets the parent if the toolbox item is nested.
116
- * @return {?IToolboxItem} The parent toolbox item, or null if
117
- * this toolbox item is not nested.
118
- * @public
119
- */
120
- ToolboxItem.prototype.getParent = function() {
121
- return null;
122
- };
123
-
124
- /**
125
- * Gets the nested level of the category.
126
- * @return {number} The nested level of the category.
127
- * @package
128
- */
129
- ToolboxItem.prototype.getLevel = function() {
130
- return this.level_;
131
- };
139
+ /**
140
+ * Gets the nested level of the category.
141
+ * @return {number} The nested level of the category.
142
+ * @package
143
+ */
144
+ getLevel() {
145
+ return this.level_;
146
+ }
132
147
 
133
- /**
134
- * Whether the toolbox item is selectable.
135
- * @return {boolean} True if the toolbox item can be selected.
136
- * @public
137
- */
138
- ToolboxItem.prototype.isSelectable = function() {
139
- return false;
140
- };
148
+ /**
149
+ * Whether the toolbox item is selectable.
150
+ * @return {boolean} True if the toolbox item can be selected.
151
+ * @public
152
+ */
153
+ isSelectable() {
154
+ return false;
155
+ }
141
156
 
142
- /**
143
- * Whether the toolbox item is collapsible.
144
- * @return {boolean} True if the toolbox item is collapsible.
145
- * @public
146
- */
147
- ToolboxItem.prototype.isCollapsible = function() {
148
- return false;
149
- };
157
+ /**
158
+ * Whether the toolbox item is collapsible.
159
+ * @return {boolean} True if the toolbox item is collapsible.
160
+ * @public
161
+ */
162
+ isCollapsible() {
163
+ return false;
164
+ }
150
165
 
151
- /**
152
- * Dispose of this toolbox item. No-op by default.
153
- * @public
154
- */
155
- ToolboxItem.prototype.dispose = function() {};
166
+ /**
167
+ * Dispose of this toolbox item. No-op by default.
168
+ * @public
169
+ */
170
+ dispose() {}
171
+ }
156
172
 
157
173
  exports.ToolboxItem = ToolboxItem;
package/core/tooltip.js CHANGED
@@ -4,23 +4,15 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
 
7
- /**
8
- * @fileoverview Library to create tooltips for Blockly.
9
- * First, call init() after onload.
10
- * Second, set the 'tooltip' property on any SVG element that needs a tooltip.
11
- * If the tooltip is a string, then that message will be displayed.
12
- * If the tooltip is an SVG element, then that object's tooltip will be used.
13
- * Third, call bindMouseEvents(e) passing the SVG element.
14
- */
15
7
  'use strict';
16
8
 
17
9
  /**
18
10
  * Library to create tooltips for Blockly.
19
- * First, call init() after onload.
11
+ * First, call createDom() after onload.
20
12
  * Second, set the 'tooltip' property on any SVG element that needs a tooltip.
21
- * If the tooltip is a string, then that message will be displayed.
22
- * If the tooltip is an SVG element, then that object's tooltip will be used.
23
- * Third, call bindMouseEvents(e) passing the SVG element.
13
+ * If the tooltip is a string, or a function that returns a string, that message
14
+ * will be displayed. If the tooltip is an SVG element, then that object's
15
+ * tooltip will be used. Third, call bindMouseEvents(e) passing the SVG element.
24
16
  * @namespace Blockly.Tooltip
25
17
  */
26
18
  goog.module('Blockly.Tooltip');
@@ -42,6 +34,46 @@ const deprecation = goog.require('Blockly.utils.deprecation');
42
34
  let TipInfo;
43
35
  exports.TipInfo = TipInfo;
44
36
 
37
+ /**
38
+ * A function that renders custom tooltip UI.
39
+ * 1st parameter: the div element to render content into.
40
+ * 2nd parameter: the element being moused over (i.e., the element for which the
41
+ * tooltip should be shown).
42
+ * @typedef {function(!Element, !Element)}
43
+ * @alias Blockly.Tooltip.CustomTooltip
44
+ */
45
+ let CustomTooltip;
46
+ exports.CustomTooltip = CustomTooltip;
47
+
48
+ /**
49
+ * An optional function that renders custom tooltips into the provided DIV. If
50
+ * this is defined, the function will be called instead of rendering the default
51
+ * tooltip UI.
52
+ * @type {!CustomTooltip|undefined}
53
+ */
54
+ let customTooltip = undefined;
55
+
56
+ /**
57
+ * Sets a custom function that will be called if present instead of the default
58
+ * tooltip UI.
59
+ * @param {!CustomTooltip} customFn A custom tooltip used to render an alternate
60
+ * tooltip UI.
61
+ * @alias Blockly.Tooltip.setCustomTooltip
62
+ */
63
+ const setCustomTooltip = function(customFn) {
64
+ customTooltip = customFn;
65
+ };
66
+ exports.setCustomTooltip = setCustomTooltip;
67
+
68
+ /**
69
+ * Gets the custom tooltip function.
70
+ * @returns {!CustomTooltip|undefined} The custom tooltip function, if defined.
71
+ */
72
+ const getCustomTooltip = function() {
73
+ return customTooltip;
74
+ };
75
+ exports.getCustomTooltip = getCustomTooltip;
76
+
45
77
  /**
46
78
  * Is a tooltip currently showing?
47
79
  * @type {boolean}
@@ -160,13 +192,13 @@ exports.MARGINS = MARGINS;
160
192
 
161
193
  /**
162
194
  * The HTML container. Set once by createDom.
163
- * @type {Element}
195
+ * @type {?HTMLDivElement}
164
196
  */
165
197
  let DIV = null;
166
198
 
167
199
  /**
168
200
  * Returns the HTML tooltip container.
169
- * @returns {Element} The HTML tooltip container.
201
+ * @returns {?HTMLDivElement} The HTML tooltip container.
170
202
  * @alias Blockly.Tooltip.getDiv
171
203
  */
172
204
  const getDiv = function() {
@@ -178,7 +210,7 @@ Object.defineProperties(exports, {
178
210
  /**
179
211
  * The HTML container. Set once by createDom.
180
212
  * @name Blockly.Tooltip.DIV
181
- * @type {Element}
213
+ * @type {HTMLDivElement}
182
214
  * @deprecated Use Blockly.Tooltip.getDiv() and .setDiv().
183
215
  * (September 2021)
184
216
  * @suppress {checkTypes}
@@ -242,7 +274,7 @@ const createDom = function() {
242
274
  return; // Already created.
243
275
  }
244
276
  // Create an HTML container for popup overlays (e.g. editor widgets).
245
- DIV = document.createElement('div');
277
+ DIV = /** @type {!HTMLDivElement} */ (document.createElement('div'));
246
278
  DIV.className = 'blocklyTooltipDiv';
247
279
  const container = common.getParentContainer() || document.body;
248
280
  container.appendChild(DIV);
@@ -410,48 +442,60 @@ const unblock = function() {
410
442
  exports.unblock = unblock;
411
443
 
412
444
  /**
413
- * Create the tooltip and show it.
445
+ * Renders the tooltip content into the tooltip div.
414
446
  */
415
- const show = function() {
416
- if (blocked) {
417
- // Someone doesn't want us to show tooltips.
447
+ const renderContent = function() {
448
+ if (!DIV || !element) {
449
+ // This shouldn't happen, but if it does, we can't render.
418
450
  return;
419
451
  }
420
- poisonedElement = element;
421
- if (!DIV) {
422
- return;
452
+ if (typeof customTooltip === 'function') {
453
+ customTooltip(DIV, element);
454
+ } else {
455
+ renderDefaultContent();
423
456
  }
424
- // Erase all existing text.
425
- DIV.textContent = '';
457
+ };
458
+
459
+ /**
460
+ * Renders the default tooltip UI.
461
+ */
462
+ const renderDefaultContent = function() {
426
463
  let tip = getTooltipOfObject(element);
427
464
  tip = blocklyString.wrap(tip, LIMIT);
428
465
  // Create new text, line by line.
429
466
  const lines = tip.split('\n');
430
467
  for (let i = 0; i < lines.length; i++) {
431
- const div = document.createElement('div');
468
+ const div = /** @type {!HTMLDivElement} */ (document.createElement('div'));
432
469
  div.appendChild(document.createTextNode(lines[i]));
433
470
  DIV.appendChild(div);
434
471
  }
435
- const rtl = /** @type {{RTL: boolean}} */ (element).RTL;
472
+ };
473
+
474
+ /**
475
+ * Gets the coordinates for the tooltip div, taking into account the edges of
476
+ * the screen to prevent showing the tooltip offscreen.
477
+ * @param {boolean} rtl True if the tooltip should be in right-to-left layout.
478
+ * @returns {{x: number, y: number}} Coordinates at which the tooltip div should
479
+ * be placed.
480
+ */
481
+ const getPosition = function(rtl) {
482
+ // Position the tooltip just below the cursor.
436
483
  const windowWidth = document.documentElement.clientWidth;
437
484
  const windowHeight = document.documentElement.clientHeight;
438
- // Display the tooltip.
439
- DIV.style.direction = rtl ? 'rtl' : 'ltr';
440
- DIV.style.display = 'block';
441
- visible = true;
442
- // Move the tooltip to just below the cursor.
485
+
443
486
  let anchorX = lastX;
444
487
  if (rtl) {
445
488
  anchorX -= OFFSET_X + DIV.offsetWidth;
446
489
  } else {
447
490
  anchorX += OFFSET_X;
448
491
  }
449
- let anchorY = lastY + OFFSET_Y;
450
492
 
493
+ let anchorY = lastY + OFFSET_Y;
451
494
  if (anchorY + DIV.offsetHeight > windowHeight + window.scrollY) {
452
495
  // Falling off the bottom of the screen; shift the tooltip up.
453
496
  anchorY -= DIV.offsetHeight + 2 * OFFSET_Y;
454
497
  }
498
+
455
499
  if (rtl) {
456
500
  // Prevent falling off left edge in RTL mode.
457
501
  anchorX = Math.max(MARGINS - window.scrollX, anchorX);
@@ -463,6 +507,35 @@ const show = function() {
463
507
  anchorX = windowWidth - DIV.offsetWidth - 2 * MARGINS;
464
508
  }
465
509
  }
466
- DIV.style.top = anchorY + 'px';
467
- DIV.style.left = anchorX + 'px';
510
+
511
+ return {x: anchorX, y: anchorY};
512
+ };
513
+
514
+ /**
515
+ * Create the tooltip and show it.
516
+ */
517
+ const show = function() {
518
+ if (blocked) {
519
+ // Someone doesn't want us to show tooltips.
520
+ return;
521
+ }
522
+ poisonedElement = element;
523
+ if (!DIV) {
524
+ return;
525
+ }
526
+ // Erase all existing text.
527
+ DIV.textContent = '';
528
+
529
+ // Add new content.
530
+ renderContent();
531
+
532
+ // Display the tooltip.
533
+ const rtl = /** @type {{RTL: boolean}} */ (element).RTL;
534
+ DIV.style.direction = rtl ? 'rtl' : 'ltr';
535
+ DIV.style.display = 'block';
536
+ visible = true;
537
+
538
+ const {x, y} = getPosition(rtl);
539
+ DIV.style.left = x + 'px';
540
+ DIV.style.top = y + 'px';
468
541
  };
package/core/touch.js CHANGED
@@ -15,13 +15,18 @@
15
15
  */
16
16
  goog.module('Blockly.Touch');
17
17
 
18
- const internalConstants = goog.require('Blockly.internalConstants');
19
18
  const utilsString = goog.require('Blockly.utils.string');
20
19
  /* eslint-disable-next-line no-unused-vars */
21
20
  const {Gesture} = goog.requireType('Blockly.Gesture');
22
21
  const {globalThis} = goog.require('Blockly.utils.global');
23
22
 
24
23
 
24
+ /**
25
+ * Length in ms for a touch to become a long press.
26
+ * @const
27
+ */
28
+ const LONGPRESS = 750;
29
+
25
30
  /**
26
31
  * Whether touch is enabled in the browser.
27
32
  * Copied from Closure's goog.events.BrowserFeature.TOUCH_ENABLED
@@ -107,7 +112,7 @@ const longStart = function(e, gesture) {
107
112
  if (gesture) {
108
113
  gesture.handleRightClick(e);
109
114
  }
110
- }, internalConstants.LONGPRESS);
115
+ }, LONGPRESS);
111
116
  };
112
117
  exports.longStart = longStart;
113
118
 
@@ -212,7 +217,7 @@ exports.checkTouchIdentifier = checkTouchIdentifier;
212
217
  * @alias Blockly.Touch.setClientFromTouch
213
218
  */
214
219
  const setClientFromTouch = function(e) {
215
- if (utilsString.startsWith(e.type, 'touch')) {
220
+ if (utilsString.startsWith(e.type, 'touch') && e.changedTouches) {
216
221
  // Map the touch event's properties to the event.
217
222
  const touchPoint = e.changedTouches[0];
218
223
  e.clientX = touchPoint.clientX;