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
@@ -35,10 +35,10 @@ Dart['text_join'] = function(block) {
35
35
  // Create a string made up of any number of elements of any type.
36
36
  switch (block.itemCount_) {
37
37
  case 0:
38
- return ['\'\'', Dart.ORDER_ATOMIC];
38
+ return ["''", Dart.ORDER_ATOMIC];
39
39
  case 1: {
40
40
  const element =
41
- Dart.valueToCode(block, 'ADD0', Dart.ORDER_UNARY_POSTFIX) || '\'\'';
41
+ Dart.valueToCode(block, 'ADD0', Dart.ORDER_UNARY_POSTFIX) || "''";
42
42
  const code = element + '.toString()';
43
43
  return [code, Dart.ORDER_UNARY_POSTFIX];
44
44
  }
@@ -46,7 +46,7 @@ Dart['text_join'] = function(block) {
46
46
  const elements = new Array(block.itemCount_);
47
47
  for (let i = 0; i < block.itemCount_; i++) {
48
48
  elements[i] =
49
- Dart.valueToCode(block, 'ADD' + i, Dart.ORDER_NONE) || '\'\'';
49
+ Dart.valueToCode(block, 'ADD' + i, Dart.ORDER_NONE) || "''";
50
50
  }
51
51
  const code = '[' + elements.join(',') + '].join()';
52
52
  return [code, Dart.ORDER_UNARY_POSTFIX];
@@ -58,21 +58,21 @@ Dart['text_append'] = function(block) {
58
58
  // Append to a variable in place.
59
59
  const varName =
60
60
  Dart.nameDB_.getName(block.getFieldValue('VAR'), NameType.VARIABLE);
61
- const value = Dart.valueToCode(block, 'TEXT', Dart.ORDER_NONE) || '\'\'';
61
+ const value = Dart.valueToCode(block, 'TEXT', Dart.ORDER_NONE) || "''";
62
62
  return varName + ' = [' + varName + ', ' + value + '].join();\n';
63
63
  };
64
64
 
65
65
  Dart['text_length'] = function(block) {
66
66
  // String or array length.
67
67
  const text =
68
- Dart.valueToCode(block, 'VALUE', Dart.ORDER_UNARY_POSTFIX) || '\'\'';
68
+ Dart.valueToCode(block, 'VALUE', Dart.ORDER_UNARY_POSTFIX) || "''";
69
69
  return [text + '.length', Dart.ORDER_UNARY_POSTFIX];
70
70
  };
71
71
 
72
72
  Dart['text_isEmpty'] = function(block) {
73
73
  // Is the string null or array empty?
74
74
  const text =
75
- Dart.valueToCode(block, 'VALUE', Dart.ORDER_UNARY_POSTFIX) || '\'\'';
75
+ Dart.valueToCode(block, 'VALUE', Dart.ORDER_UNARY_POSTFIX) || "''";
76
76
  return [text + '.isEmpty', Dart.ORDER_UNARY_POSTFIX];
77
77
  };
78
78
 
@@ -80,9 +80,9 @@ Dart['text_indexOf'] = function(block) {
80
80
  // Search the text for a substring.
81
81
  const operator =
82
82
  block.getFieldValue('END') === 'FIRST' ? 'indexOf' : 'lastIndexOf';
83
- const substring = Dart.valueToCode(block, 'FIND', Dart.ORDER_NONE) || '\'\'';
83
+ const substring = Dart.valueToCode(block, 'FIND', Dart.ORDER_NONE) || "''";
84
84
  const text =
85
- Dart.valueToCode(block, 'VALUE', Dart.ORDER_UNARY_POSTFIX) || '\'\'';
85
+ Dart.valueToCode(block, 'VALUE', Dart.ORDER_UNARY_POSTFIX) || "''";
86
86
  const code = text + '.' + operator + '(' + substring + ')';
87
87
  if (block.workspace.options.oneBasedIndex) {
88
88
  return [code + ' + 1', Dart.ORDER_ADDITIVE];
@@ -97,7 +97,7 @@ Dart['text_charAt'] = function(block) {
97
97
  const textOrder = (where === 'FIRST' || where === 'FROM_START') ?
98
98
  Dart.ORDER_UNARY_POSTFIX :
99
99
  Dart.ORDER_NONE;
100
- const text = Dart.valueToCode(block, 'VALUE', textOrder) || '\'\'';
100
+ const text = Dart.valueToCode(block, 'VALUE', textOrder) || "''";
101
101
  let at;
102
102
  switch (where) {
103
103
  case 'FIRST': {
@@ -114,20 +114,22 @@ Dart['text_charAt'] = function(block) {
114
114
  // Fall through.
115
115
  case 'FROM_END': {
116
116
  at = Dart.getAdjusted(block, 'AT', 1);
117
- const functionName = Dart.provideFunction_('text_get_from_end', [
118
- 'String ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(String text, num x) {',
119
- ' return text[text.length - x];', '}'
120
- ]);
117
+ const functionName = Dart.provideFunction_('text_get_from_end', `
118
+ String ${Dart.FUNCTION_NAME_PLACEHOLDER_}(String text, num x) {
119
+ return text[text.length - x];
120
+ }
121
+ `);
121
122
  const code = functionName + '(' + text + ', ' + at + ')';
122
123
  return [code, Dart.ORDER_UNARY_POSTFIX];
123
124
  }
124
125
  case 'RANDOM': {
125
126
  Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;';
126
- const functionName = Dart.provideFunction_('text_random_letter', [
127
- 'String ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(String text) {',
128
- ' int x = new Math.Random().nextInt(text.length);',
129
- ' return text[x];', '}'
130
- ]);
127
+ const functionName = Dart.provideFunction_('text_random_letter', `
128
+ String ${Dart.FUNCTION_NAME_PLACEHOLDER_}(String text) {
129
+ int x = new Math.Random().nextInt(text.length);
130
+ return text[x];
131
+ }
132
+ `);
131
133
  const code = functionName + '(' + text + ')';
132
134
  return [code, Dart.ORDER_UNARY_POSTFIX];
133
135
  }
@@ -142,7 +144,7 @@ Dart['text_getSubstring'] = function(block) {
142
144
  const requiresLengthCall = (where1 !== 'FROM_END' && where2 === 'FROM_START');
143
145
  const textOrder =
144
146
  requiresLengthCall ? Dart.ORDER_UNARY_POSTFIX : Dart.ORDER_NONE;
145
- const text = Dart.valueToCode(block, 'STRING', textOrder) || '\'\'';
147
+ const text = Dart.valueToCode(block, 'STRING', textOrder) || "''";
146
148
  let code;
147
149
  if (where1 === 'FIRST' && where2 === 'LAST') {
148
150
  code = text;
@@ -188,19 +190,25 @@ Dart['text_getSubstring'] = function(block) {
188
190
  } else {
189
191
  const at1 = Dart.getAdjusted(block, 'AT1');
190
192
  const at2 = Dart.getAdjusted(block, 'AT2');
191
- const functionName = Dart.provideFunction_('text_get_substring', [
192
- 'String ' + Dart.FUNCTION_NAME_PLACEHOLDER_ +
193
- '(String text, String where1, num at1, String where2, num at2) {',
194
- ' int getAt(String where, num at) {', ' if (where == \'FROM_END\') {',
195
- ' at = text.length - 1 - at;',
196
- ' } else if (where == \'FIRST\') {', ' at = 0;',
197
- ' } else if (where == \'LAST\') {', ' at = text.length - 1;',
198
- ' } else if (where != \'FROM_START\') {',
199
- ' throw \'Unhandled option (text_getSubstring).\';', ' }',
200
- ' return at;', ' }', ' at1 = getAt(where1, at1);',
201
- ' at2 = getAt(where2, at2) + 1;', ' return text.substring(at1, at2);',
202
- '}'
203
- ]);
193
+ const functionName = Dart.provideFunction_('text_get_substring', `
194
+ String ${Dart.FUNCTION_NAME_PLACEHOLDER_}(String text, String where1, num at1, String where2, num at2) {
195
+ int getAt(String where, num at) {
196
+ if (where == 'FROM_END') {
197
+ at = text.length - 1 - at;
198
+ } else if (where == 'FIRST') {
199
+ at = 0;
200
+ } else if (where == 'LAST') {
201
+ at = text.length - 1;
202
+ } else if (where != 'FROM_START') {
203
+ throw 'Unhandled option (text_getSubstring).';
204
+ }
205
+ return at;
206
+ }
207
+ at1 = getAt(where1, at1);
208
+ at2 = getAt(where2, at2) + 1;
209
+ return text.substring(at1, at2);
210
+ }
211
+ `);
204
212
  code = functionName + '(' + text + ', \'' + where1 + '\', ' + at1 + ', \'' +
205
213
  where2 + '\', ' + at2 + ')';
206
214
  }
@@ -216,23 +224,29 @@ Dart['text_changeCase'] = function(block) {
216
224
  };
217
225
  const operator = OPERATORS[block.getFieldValue('CASE')];
218
226
  const textOrder = operator ? Dart.ORDER_UNARY_POSTFIX : Dart.ORDER_NONE;
219
- const text = Dart.valueToCode(block, 'TEXT', textOrder) || '\'\'';
227
+ const text = Dart.valueToCode(block, 'TEXT', textOrder) || "''";
220
228
  let code;
221
229
  if (operator) {
222
230
  // Upper and lower case are functions built into Dart.
223
231
  code = text + operator;
224
232
  } else {
225
233
  // Title case is not a native Dart function. Define one.
226
- const functionName = Dart.provideFunction_('text_toTitleCase', [
227
- 'String ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(String str) {',
228
- ' RegExp exp = new RegExp(r\'\\b\');',
229
- ' List<String> list = str.split(exp);',
230
- ' final title = new StringBuffer();', ' for (String part in list) {',
231
- ' if (part.length > 0) {', ' title.write(part[0].toUpperCase());',
232
- ' if (part.length > 0) {',
233
- ' title.write(part.substring(1).toLowerCase());', ' }',
234
- ' }', ' }', ' return title.toString();', '}'
235
- ]);
234
+ const functionName = Dart.provideFunction_('text_toTitleCase', `
235
+ String ${Dart.FUNCTION_NAME_PLACEHOLDER_}(String str) {
236
+ RegExp exp = new RegExp(r'\\b');
237
+ List<String> list = str.split(exp);
238
+ final title = new StringBuffer();
239
+ for (String part in list) {
240
+ if (part.length > 0) {
241
+ title.write(part[0].toUpperCase());
242
+ if (part.length > 0) {
243
+ title.write(part.substring(1).toLowerCase());
244
+ }
245
+ }
246
+ }
247
+ return title.toString();
248
+ }
249
+ `);
236
250
  code = functionName + '(' + text + ')';
237
251
  }
238
252
  return [code, Dart.ORDER_UNARY_POSTFIX];
@@ -247,13 +261,13 @@ Dart['text_trim'] = function(block) {
247
261
  };
248
262
  const operator = OPERATORS[block.getFieldValue('MODE')];
249
263
  const text =
250
- Dart.valueToCode(block, 'TEXT', Dart.ORDER_UNARY_POSTFIX) || '\'\'';
264
+ Dart.valueToCode(block, 'TEXT', Dart.ORDER_UNARY_POSTFIX) || "''";
251
265
  return [text + operator, Dart.ORDER_UNARY_POSTFIX];
252
266
  };
253
267
 
254
268
  Dart['text_print'] = function(block) {
255
269
  // Print statement.
256
- const msg = Dart.valueToCode(block, 'TEXT', Dart.ORDER_NONE) || '\'\'';
270
+ const msg = Dart.valueToCode(block, 'TEXT', Dart.ORDER_NONE) || "''";
257
271
  return 'print(' + msg + ');\n';
258
272
  };
259
273
 
@@ -266,7 +280,7 @@ Dart['text_prompt_ext'] = function(block) {
266
280
  msg = Dart.quote_(block.getFieldValue('TEXT'));
267
281
  } else {
268
282
  // External message.
269
- msg = Dart.valueToCode(block, 'TEXT', Dart.ORDER_NONE) || '\'\'';
283
+ msg = Dart.valueToCode(block, 'TEXT', Dart.ORDER_NONE) || "''";
270
284
  }
271
285
  let code = 'Html.window.prompt(' + msg + ', \'\')';
272
286
  const toNumber = block.getFieldValue('TYPE') === 'NUMBER';
@@ -280,27 +294,35 @@ Dart['text_prompt_ext'] = function(block) {
280
294
  Dart['text_prompt'] = Dart['text_prompt_ext'];
281
295
 
282
296
  Dart['text_count'] = function(block) {
283
- const text = Dart.valueToCode(block, 'TEXT', Dart.ORDER_NONE) || '\'\'';
284
- const sub = Dart.valueToCode(block, 'SUB', Dart.ORDER_NONE) || '\'\'';
297
+ const text = Dart.valueToCode(block, 'TEXT', Dart.ORDER_NONE) || "''";
298
+ const sub = Dart.valueToCode(block, 'SUB', Dart.ORDER_NONE) || "''";
285
299
  // Substring count is not a native Dart function. Define one.
286
- const functionName = Dart.provideFunction_('text_count', [
287
- 'int ' + Dart.FUNCTION_NAME_PLACEHOLDER_ +
288
- '(String haystack, String needle) {',
289
- ' if (needle.length == 0) {', ' return haystack.length + 1;', ' }',
290
- ' int index = 0;', ' int count = 0;', ' while (index != -1) {',
291
- ' index = haystack.indexOf(needle, index);', ' if (index != -1) {',
292
- ' count++;', ' index += needle.length;', ' }', ' }',
293
- ' return count;', '}'
294
- ]);
300
+ const functionName = Dart.provideFunction_('text_count', `
301
+ int ${Dart.FUNCTION_NAME_PLACEHOLDER_}(String haystack, String needle) {
302
+ if (needle.length == 0) {
303
+ return haystack.length + 1;
304
+ }
305
+ int index = 0;
306
+ int count = 0;
307
+ while (index != -1) {
308
+ index = haystack.indexOf(needle, index);
309
+ if (index != -1) {
310
+ count++;
311
+ index += needle.length;
312
+ }
313
+ }
314
+ return count;
315
+ }
316
+ `);
295
317
  const code = functionName + '(' + text + ', ' + sub + ')';
296
318
  return [code, Dart.ORDER_UNARY_POSTFIX];
297
319
  };
298
320
 
299
321
  Dart['text_replace'] = function(block) {
300
322
  const text =
301
- Dart.valueToCode(block, 'TEXT', Dart.ORDER_UNARY_POSTFIX) || '\'\'';
302
- const from = Dart.valueToCode(block, 'FROM', Dart.ORDER_NONE) || '\'\'';
303
- const to = Dart.valueToCode(block, 'TO', Dart.ORDER_NONE) || '\'\'';
323
+ Dart.valueToCode(block, 'TEXT', Dart.ORDER_UNARY_POSTFIX) || "''";
324
+ const from = Dart.valueToCode(block, 'FROM', Dart.ORDER_NONE) || "''";
325
+ const to = Dart.valueToCode(block, 'TO', Dart.ORDER_NONE) || "''";
304
326
  const code = text + '.replaceAll(' + from + ', ' + to + ')';
305
327
  return [code, Dart.ORDER_UNARY_POSTFIX];
306
328
  };
@@ -310,7 +332,7 @@ Dart['text_reverse'] = function(block) {
310
332
  // http://stackoverflow.com/a/21613700/3529104
311
333
  // Implementing something is possibly better than not implementing anything?
312
334
  const text =
313
- Dart.valueToCode(block, 'TEXT', Dart.ORDER_UNARY_POSTFIX) || '\'\'';
335
+ Dart.valueToCode(block, 'TEXT', Dart.ORDER_UNARY_POSTFIX) || "''";
314
336
  const code = 'new String.fromCharCodes(' + text + '.runes.toList().reversed)';
315
337
  return [code, Dart.ORDER_UNARY_PREFIX];
316
338
  };
@@ -22,11 +22,12 @@ JavaScript['colour_picker'] = function(block) {
22
22
 
23
23
  JavaScript['colour_random'] = function(block) {
24
24
  // Generate a random colour.
25
- const functionName = JavaScript.provideFunction_('colourRandom', [
26
- 'function ' + JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '() {',
27
- ' var num = Math.floor(Math.random() * Math.pow(2, 24));',
28
- ' return \'#\' + (\'00000\' + num.toString(16)).substr(-6);', '}'
29
- ]);
25
+ const functionName = JavaScript.provideFunction_('colourRandom', `
26
+ function ${JavaScript.FUNCTION_NAME_PLACEHOLDER_}() {
27
+ var num = Math.floor(Math.random() * Math.pow(2, 24));
28
+ return '#' + ('00000' + num.toString(16)).substr(-6);
29
+ }
30
+ `);
30
31
  const code = functionName + '()';
31
32
  return [code, JavaScript.ORDER_FUNCTION_CALL];
32
33
  };
@@ -38,16 +39,17 @@ JavaScript['colour_rgb'] = function(block) {
38
39
  JavaScript.valueToCode(block, 'GREEN', JavaScript.ORDER_NONE) || 0;
39
40
  const blue =
40
41
  JavaScript.valueToCode(block, 'BLUE', JavaScript.ORDER_NONE) || 0;
41
- const functionName = JavaScript.provideFunction_('colourRgb', [
42
- 'function ' + JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(r, g, b) {',
43
- ' r = Math.max(Math.min(Number(r), 100), 0) * 2.55;',
44
- ' g = Math.max(Math.min(Number(g), 100), 0) * 2.55;',
45
- ' b = Math.max(Math.min(Number(b), 100), 0) * 2.55;',
46
- ' r = (\'0\' + (Math.round(r) || 0).toString(16)).slice(-2);',
47
- ' g = (\'0\' + (Math.round(g) || 0).toString(16)).slice(-2);',
48
- ' b = (\'0\' + (Math.round(b) || 0).toString(16)).slice(-2);',
49
- ' return \'#\' + r + g + b;', '}'
50
- ]);
42
+ const functionName = JavaScript.provideFunction_('colourRgb', `
43
+ function ${JavaScript.FUNCTION_NAME_PLACEHOLDER_}(r, g, b) {
44
+ r = Math.max(Math.min(Number(r), 100), 0) * 2.55;
45
+ g = Math.max(Math.min(Number(g), 100), 0) * 2.55;
46
+ b = Math.max(Math.min(Number(b), 100), 0) * 2.55;
47
+ r = ('0' + (Math.round(r) || 0).toString(16)).slice(-2);
48
+ g = ('0' + (Math.round(g) || 0).toString(16)).slice(-2);
49
+ b = ('0' + (Math.round(b) || 0).toString(16)).slice(-2);
50
+ return '#' + r + g + b;
51
+ }
52
+ `);
51
53
  const code = functionName + '(' + red + ', ' + green + ', ' + blue + ')';
52
54
  return [code, JavaScript.ORDER_FUNCTION_CALL];
53
55
  };
@@ -55,28 +57,29 @@ JavaScript['colour_rgb'] = function(block) {
55
57
  JavaScript['colour_blend'] = function(block) {
56
58
  // Blend two colours together.
57
59
  const c1 = JavaScript.valueToCode(block, 'COLOUR1', JavaScript.ORDER_NONE) ||
58
- '\'#000000\'';
60
+ "'#000000'";
59
61
  const c2 = JavaScript.valueToCode(block, 'COLOUR2', JavaScript.ORDER_NONE) ||
60
- '\'#000000\'';
62
+ "'#000000'";
61
63
  const ratio =
62
64
  JavaScript.valueToCode(block, 'RATIO', JavaScript.ORDER_NONE) || 0.5;
63
- const functionName = JavaScript.provideFunction_('colourBlend', [
64
- 'function ' + JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(c1, c2, ratio) {',
65
- ' ratio = Math.max(Math.min(Number(ratio), 1), 0);',
66
- ' var r1 = parseInt(c1.substring(1, 3), 16);',
67
- ' var g1 = parseInt(c1.substring(3, 5), 16);',
68
- ' var b1 = parseInt(c1.substring(5, 7), 16);',
69
- ' var r2 = parseInt(c2.substring(1, 3), 16);',
70
- ' var g2 = parseInt(c2.substring(3, 5), 16);',
71
- ' var b2 = parseInt(c2.substring(5, 7), 16);',
72
- ' var r = Math.round(r1 * (1 - ratio) + r2 * ratio);',
73
- ' var g = Math.round(g1 * (1 - ratio) + g2 * ratio);',
74
- ' var b = Math.round(b1 * (1 - ratio) + b2 * ratio);',
75
- ' r = (\'0\' + (r || 0).toString(16)).slice(-2);',
76
- ' g = (\'0\' + (g || 0).toString(16)).slice(-2);',
77
- ' b = (\'0\' + (b || 0).toString(16)).slice(-2);',
78
- ' return \'#\' + r + g + b;', '}'
79
- ]);
65
+ const functionName = JavaScript.provideFunction_('colourBlend', `
66
+ function ${JavaScript.FUNCTION_NAME_PLACEHOLDER_}(c1, c2, ratio) {
67
+ ratio = Math.max(Math.min(Number(ratio), 1), 0);
68
+ var r1 = parseInt(c1.substring(1, 3), 16);
69
+ var g1 = parseInt(c1.substring(3, 5), 16);
70
+ var b1 = parseInt(c1.substring(5, 7), 16);
71
+ var r2 = parseInt(c2.substring(1, 3), 16);
72
+ var g2 = parseInt(c2.substring(3, 5), 16);
73
+ var b2 = parseInt(c2.substring(5, 7), 16);
74
+ var r = Math.round(r1 * (1 - ratio) + r2 * ratio);
75
+ var g = Math.round(g1 * (1 - ratio) + g2 * ratio);
76
+ var b = Math.round(b1 * (1 - ratio) + b2 * ratio);
77
+ r = ('0' + (r || 0).toString(16)).slice(-2);
78
+ g = ('0' + (g || 0).toString(16)).slice(-2);
79
+ b = ('0' + (b || 0).toString(16)).slice(-2);
80
+ return '#' + r + g + b;
81
+ }
82
+ `);
80
83
  const code = functionName + '(' + c1 + ', ' + c2 + ', ' + ratio + ')';
81
84
  return [code, JavaScript.ORDER_FUNCTION_CALL];
82
85
  };
@@ -35,11 +35,15 @@ JavaScript['lists_create_with'] = function(block) {
35
35
 
36
36
  JavaScript['lists_repeat'] = function(block) {
37
37
  // Create a list with one element repeated.
38
- const functionName = JavaScript.provideFunction_('listsRepeat', [
39
- 'function ' + JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(value, n) {',
40
- ' var array = [];', ' for (var i = 0; i < n; i++) {',
41
- ' array[i] = value;', ' }', ' return array;', '}'
42
- ]);
38
+ const functionName = JavaScript.provideFunction_('listsRepeat', `
39
+ function ${JavaScript.FUNCTION_NAME_PLACEHOLDER_}(value, n) {
40
+ var array = [];
41
+ for (var i = 0; i < n; i++) {
42
+ array[i] = value;
43
+ }
44
+ return array;
45
+ }
46
+ `);
43
47
  const element =
44
48
  JavaScript.valueToCode(block, 'ITEM', JavaScript.ORDER_NONE) || 'null';
45
49
  const repeatCount =
@@ -67,7 +71,7 @@ JavaScript['lists_indexOf'] = function(block) {
67
71
  const operator =
68
72
  block.getFieldValue('END') === 'FIRST' ? 'indexOf' : 'lastIndexOf';
69
73
  const item =
70
- JavaScript.valueToCode(block, 'FIND', JavaScript.ORDER_NONE) || '\'\'';
74
+ JavaScript.valueToCode(block, 'FIND', JavaScript.ORDER_NONE) || "''";
71
75
  const list =
72
76
  JavaScript.valueToCode(block, 'VALUE', JavaScript.ORDER_MEMBER) || '[]';
73
77
  const code = list + '.' + operator + '(' + item + ')';
@@ -136,13 +140,16 @@ JavaScript['lists_getIndex'] = function(block) {
136
140
  break;
137
141
  }
138
142
  case ('RANDOM'): {
139
- const functionName = JavaScript.provideFunction_('listsGetRandomItem', [
140
- 'function ' + JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
141
- '(list, remove) {',
142
- ' var x = Math.floor(Math.random() * list.length);', ' if (remove) {',
143
- ' return list.splice(x, 1)[0];', ' } else {', ' return list[x];',
144
- ' }', '}'
145
- ]);
143
+ const functionName = JavaScript.provideFunction_('listsGetRandomItem', `
144
+ function ${JavaScript.FUNCTION_NAME_PLACEHOLDER_}(list, remove) {
145
+ var x = Math.floor(Math.random() * list.length);
146
+ if (remove) {
147
+ return list.splice(x, 1)[0];
148
+ } else {
149
+ return list[x];
150
+ }
151
+ }
152
+ `);
146
153
  const code = functionName + '(' + list + ', ' + (mode !== 'GET') + ')';
147
154
  if (mode === 'GET' || mode === 'GET_REMOVE') {
148
155
  return [code, JavaScript.ORDER_FUNCTION_CALL];
@@ -309,23 +316,22 @@ JavaScript['lists_getSublist'] = function(block) {
309
316
  'FIRST': 'First',
310
317
  'LAST': 'Last',
311
318
  'FROM_START': 'FromStart',
312
- 'FROM_END': 'FromEnd'
319
+ 'FROM_END': 'FromEnd',
313
320
  };
321
+ // The value for 'FROM_END' and'FROM_START' depends on `at` so
322
+ // we add it as a parameter.
323
+ const at1Param =
324
+ (where1 === 'FROM_END' || where1 === 'FROM_START') ? ', at1' : '';
325
+ const at2Param =
326
+ (where2 === 'FROM_END' || where2 === 'FROM_START') ? ', at2' : '';
314
327
  const functionName = JavaScript.provideFunction_(
315
- 'subsequence' + wherePascalCase[where1] + wherePascalCase[where2], [
316
- 'function ' + JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(sequence' +
317
- // The value for 'FROM_END' and'FROM_START' depends on `at` so
318
- // we add it as a parameter.
319
- ((where1 === 'FROM_END' || where1 === 'FROM_START') ? ', at1' :
320
- '') +
321
- ((where2 === 'FROM_END' || where2 === 'FROM_START') ? ', at2' :
322
- '') +
323
- ') {',
324
- getSubstringIndex('sequence', where1, 'at1') + ';',
325
- ' var end = ' + getSubstringIndex('sequence', where2, 'at2') +
326
- ' + 1;',
327
- ' return sequence.slice(start, end);', '}'
328
- ]);
328
+ 'subsequence' + wherePascalCase[where1] + wherePascalCase[where2], `
329
+ function ${JavaScript.FUNCTION_NAME_PLACEHOLDER_}(sequence${at1Param}${at2Param}) {
330
+ var start = ${getSubstringIndex('sequence', where1, 'at1')};
331
+ var end = ${getSubstringIndex('sequence', where2, 'at2')} + 1;
332
+ return sequence.slice(start, end);
333
+ }
334
+ `);
329
335
  code = functionName + '(' + list +
330
336
  // The value for 'FROM_END' and 'FROM_START' depends on `at` so we
331
337
  // pass it.
@@ -344,19 +350,20 @@ JavaScript['lists_sort'] = function(block) {
344
350
  const direction = block.getFieldValue('DIRECTION') === '1' ? 1 : -1;
345
351
  const type = block.getFieldValue('TYPE');
346
352
  const getCompareFunctionName =
347
- JavaScript.provideFunction_('listsGetSortCompare', [
348
- 'function ' + JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
349
- '(type, direction) {',
350
- ' var compareFuncs = {', ' "NUMERIC": function(a, b) {',
351
- ' return Number(a) - Number(b); },',
352
- ' "TEXT": function(a, b) {',
353
- ' return a.toString() > b.toString() ? 1 : -1; },',
354
- ' "IGNORE_CASE": function(a, b) {',
355
- ' return a.toString().toLowerCase() > ' +
356
- 'b.toString().toLowerCase() ? 1 : -1; },',
357
- ' };', ' var compare = compareFuncs[type];',
358
- ' return function(a, b) { return compare(a, b) * direction; }', '}'
359
- ]);
353
+ JavaScript.provideFunction_('listsGetSortCompare', `
354
+ function ${JavaScript.FUNCTION_NAME_PLACEHOLDER_}(type, direction) {
355
+ var compareFuncs = {
356
+ 'NUMERIC': function(a, b) {
357
+ return Number(a) - Number(b); },
358
+ 'TEXT': function(a, b) {
359
+ return a.toString() > b.toString() ? 1 : -1; },
360
+ 'IGNORE_CASE': function(a, b) {
361
+ return a.toString().toLowerCase() > b.toString().toLowerCase() ? 1 : -1; },
362
+ };
363
+ var compare = compareFuncs[type];
364
+ return function(a, b) { return compare(a, b) * direction; };
365
+ }
366
+ `);
360
367
  return [
361
368
  list + '.slice().sort(' + getCompareFunctionName + '("' + type + '", ' +
362
369
  direction + '))',
@@ -368,12 +375,12 @@ JavaScript['lists_split'] = function(block) {
368
375
  // Block for splitting text into a list, or joining a list into text.
369
376
  let input = JavaScript.valueToCode(block, 'INPUT', JavaScript.ORDER_MEMBER);
370
377
  const delimiter =
371
- JavaScript.valueToCode(block, 'DELIM', JavaScript.ORDER_NONE) || '\'\'';
378
+ JavaScript.valueToCode(block, 'DELIM', JavaScript.ORDER_NONE) || "''";
372
379
  const mode = block.getFieldValue('MODE');
373
380
  let functionName;
374
381
  if (mode === 'SPLIT') {
375
382
  if (!input) {
376
- input = '\'\'';
383
+ input = "''";
377
384
  }
378
385
  functionName = 'split';
379
386
  } else if (mode === 'JOIN') {