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
@@ -32,22 +32,22 @@ Lua['text_multiline'] = function(block) {
32
32
  Lua['text_join'] = function(block) {
33
33
  // Create a string made up of any number of elements of any type.
34
34
  if (block.itemCount_ === 0) {
35
- return ['\'\'', Lua.ORDER_ATOMIC];
35
+ return ["''", Lua.ORDER_ATOMIC];
36
36
  } else if (block.itemCount_ === 1) {
37
- const element = Lua.valueToCode(block, 'ADD0', Lua.ORDER_NONE) || '\'\'';
37
+ const element = Lua.valueToCode(block, 'ADD0', Lua.ORDER_NONE) || "''";
38
38
  const code = 'tostring(' + element + ')';
39
39
  return [code, Lua.ORDER_HIGH];
40
40
  } else if (block.itemCount_ === 2) {
41
41
  const element0 =
42
- Lua.valueToCode(block, 'ADD0', Lua.ORDER_CONCATENATION) || '\'\'';
42
+ Lua.valueToCode(block, 'ADD0', Lua.ORDER_CONCATENATION) || "''";
43
43
  const element1 =
44
- Lua.valueToCode(block, 'ADD1', Lua.ORDER_CONCATENATION) || '\'\'';
44
+ Lua.valueToCode(block, 'ADD1', Lua.ORDER_CONCATENATION) || "''";
45
45
  const code = element0 + ' .. ' + element1;
46
46
  return [code, Lua.ORDER_CONCATENATION];
47
47
  } else {
48
48
  const elements = [];
49
49
  for (let i = 0; i < block.itemCount_; i++) {
50
- elements[i] = Lua.valueToCode(block, 'ADD' + i, Lua.ORDER_NONE) || '\'\'';
50
+ elements[i] = Lua.valueToCode(block, 'ADD' + i, Lua.ORDER_NONE) || "''";
51
51
  }
52
52
  const code = 'table.concat({' + elements.join(', ') + '})';
53
53
  return [code, Lua.ORDER_HIGH];
@@ -59,41 +59,47 @@ Lua['text_append'] = function(block) {
59
59
  const varName =
60
60
  Lua.nameDB_.getName(block.getFieldValue('VAR'), NameType.VARIABLE);
61
61
  const value =
62
- Lua.valueToCode(block, 'TEXT', Lua.ORDER_CONCATENATION) || '\'\'';
62
+ Lua.valueToCode(block, 'TEXT', Lua.ORDER_CONCATENATION) || "''";
63
63
  return varName + ' = ' + varName + ' .. ' + value + '\n';
64
64
  };
65
65
 
66
66
  Lua['text_length'] = function(block) {
67
67
  // String or array length.
68
- const text = Lua.valueToCode(block, 'VALUE', Lua.ORDER_UNARY) || '\'\'';
68
+ const text = Lua.valueToCode(block, 'VALUE', Lua.ORDER_UNARY) || "''";
69
69
  return ['#' + text, Lua.ORDER_UNARY];
70
70
  };
71
71
 
72
72
  Lua['text_isEmpty'] = function(block) {
73
73
  // Is the string null or array empty?
74
- const text = Lua.valueToCode(block, 'VALUE', Lua.ORDER_UNARY) || '\'\'';
74
+ const text = Lua.valueToCode(block, 'VALUE', Lua.ORDER_UNARY) || "''";
75
75
  return ['#' + text + ' == 0', Lua.ORDER_RELATIONAL];
76
76
  };
77
77
 
78
78
  Lua['text_indexOf'] = function(block) {
79
79
  // Search the text for a substring.
80
- const substring = Lua.valueToCode(block, 'FIND', Lua.ORDER_NONE) || '\'\'';
81
- const text = Lua.valueToCode(block, 'VALUE', Lua.ORDER_NONE) || '\'\'';
80
+ const substring = Lua.valueToCode(block, 'FIND', Lua.ORDER_NONE) || "''";
81
+ const text = Lua.valueToCode(block, 'VALUE', Lua.ORDER_NONE) || "''";
82
82
  let functionName;
83
83
  if (block.getFieldValue('END') === 'FIRST') {
84
- functionName = Lua.provideFunction_('firstIndexOf', [
85
- 'function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(str, substr) ',
86
- ' local i = string.find(str, substr, 1, true)', ' if i == nil then',
87
- ' return 0', ' else', ' return i', ' end', 'end'
88
- ]);
84
+ functionName = Lua.provideFunction_('firstIndexOf', `
85
+ function ${Lua.FUNCTION_NAME_PLACEHOLDER_}(str, substr)
86
+ local i = string.find(str, substr, 1, true)
87
+ if i == nil then
88
+ return 0
89
+ end
90
+ return i
91
+ end
92
+ `);
89
93
  } else {
90
- functionName = Lua.provideFunction_('lastIndexOf', [
91
- 'function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(str, substr)',
92
- ' local i = string.find(string.reverse(str), ' +
93
- 'string.reverse(substr), 1, true)',
94
- ' if i then', ' return #str + 2 - i - #substr', ' end', ' return 0',
95
- 'end'
96
- ]);
94
+ functionName = Lua.provideFunction_('lastIndexOf', `
95
+ function ${Lua.FUNCTION_NAME_PLACEHOLDER_}(str, substr)
96
+ local i = string.find(string.reverse(str), string.reverse(substr), 1, true)
97
+ if i then
98
+ return #str + 2 - i - #substr
99
+ end
100
+ return 0
101
+ end
102
+ `);
97
103
  }
98
104
  const code = functionName + '(' + text + ', ' + substring + ')';
99
105
  return [code, Lua.ORDER_HIGH];
@@ -105,14 +111,15 @@ Lua['text_charAt'] = function(block) {
105
111
  const where = block.getFieldValue('WHERE') || 'FROM_START';
106
112
  const atOrder = (where === 'FROM_END') ? Lua.ORDER_UNARY : Lua.ORDER_NONE;
107
113
  const at = Lua.valueToCode(block, 'AT', atOrder) || '1';
108
- const text = Lua.valueToCode(block, 'VALUE', Lua.ORDER_NONE) || '\'\'';
114
+ const text = Lua.valueToCode(block, 'VALUE', Lua.ORDER_NONE) || "''";
109
115
  let code;
110
116
  if (where === 'RANDOM') {
111
- const functionName = Lua.provideFunction_('text_random_letter', [
112
- 'function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(str)',
113
- ' local index = math.random(string.len(str))',
114
- ' return string.sub(str, index, index)', 'end'
115
- ]);
117
+ const functionName = Lua.provideFunction_('text_random_letter', `
118
+ function ${Lua.FUNCTION_NAME_PLACEHOLDER_}(str)
119
+ local index = math.random(string.len(str))
120
+ return string.sub(str, index, index)
121
+ end
122
+ `);
116
123
  code = functionName + '(' + text + ')';
117
124
  } else {
118
125
  let start;
@@ -133,10 +140,11 @@ Lua['text_charAt'] = function(block) {
133
140
  code = 'string.sub(' + text + ', ' + start + ', ' + start + ')';
134
141
  } else {
135
142
  // use function to avoid reevaluation
136
- const functionName = Lua.provideFunction_('text_char_at', [
137
- 'function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(str, index)',
138
- ' return string.sub(str, index, index)', 'end'
139
- ]);
143
+ const functionName = Lua.provideFunction_('text_char_at', `
144
+ function ${Lua.FUNCTION_NAME_PLACEHOLDER_}(str, index)
145
+ return string.sub(str, index, index)
146
+ end
147
+ `);
140
148
  code = functionName + '(' + text + ', ' + start + ')';
141
149
  }
142
150
  }
@@ -145,7 +153,7 @@ Lua['text_charAt'] = function(block) {
145
153
 
146
154
  Lua['text_getSubstring'] = function(block) {
147
155
  // Get substring.
148
- const text = Lua.valueToCode(block, 'STRING', Lua.ORDER_NONE) || '\'\'';
156
+ const text = Lua.valueToCode(block, 'STRING', Lua.ORDER_NONE) || "''";
149
157
 
150
158
  // Get start index.
151
159
  const where1 = block.getFieldValue('WHERE1');
@@ -183,28 +191,35 @@ Lua['text_getSubstring'] = function(block) {
183
191
  Lua['text_changeCase'] = function(block) {
184
192
  // Change capitalization.
185
193
  const operator = block.getFieldValue('CASE');
186
- const text = Lua.valueToCode(block, 'TEXT', Lua.ORDER_NONE) || '\'\'';
194
+ const text = Lua.valueToCode(block, 'TEXT', Lua.ORDER_NONE) || "''";
187
195
  let functionName;
188
196
  if (operator === 'UPPERCASE') {
189
197
  functionName = 'string.upper';
190
198
  } else if (operator === 'LOWERCASE') {
191
199
  functionName = 'string.lower';
192
200
  } else if (operator === 'TITLECASE') {
193
- functionName = Lua.provideFunction_(
194
- 'text_titlecase',
195
- // There are shorter versions at
196
- // http://lua-users.org/wiki/SciteTitleCase
197
- // that do not preserve whitespace.
198
- [
199
- 'function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(str)',
200
- ' local buf = {}', ' local inWord = false', ' for i = 1, #str do',
201
- ' local c = string.sub(str, i, i)', ' if inWord then',
202
- ' table.insert(buf, string.lower(c))',
203
- ' if string.find(c, "%s") then', ' inWord = false',
204
- ' end', ' else', ' table.insert(buf, string.upper(c))',
205
- ' inWord = true', ' end', ' end',
206
- ' return table.concat(buf)', 'end'
207
- ]);
201
+ // There are shorter versions at
202
+ // http://lua-users.org/wiki/SciteTitleCase
203
+ // that do not preserve whitespace.
204
+ functionName = Lua.provideFunction_('text_titlecase', `
205
+ function ${Lua.FUNCTION_NAME_PLACEHOLDER_}(str)
206
+ local buf = {}
207
+ local inWord = false
208
+ for i = 1, #str do
209
+ local c = string.sub(str, i, i)
210
+ if inWord then
211
+ table.insert(buf, string.lower(c))
212
+ if string.find(c, "%s") then
213
+ inWord = false
214
+ end
215
+ else
216
+ table.insert(buf, string.upper(c))
217
+ inWord = true
218
+ end
219
+ end
220
+ return table.concat(buf)
221
+ end
222
+ `);
208
223
  }
209
224
  const code = functionName + '(' + text + ')';
210
225
  return [code, Lua.ORDER_HIGH];
@@ -214,14 +229,14 @@ Lua['text_trim'] = function(block) {
214
229
  // Trim spaces.
215
230
  const OPERATORS = {LEFT: '^%s*(,-)', RIGHT: '(.-)%s*$', BOTH: '^%s*(.-)%s*$'};
216
231
  const operator = OPERATORS[block.getFieldValue('MODE')];
217
- const text = Lua.valueToCode(block, 'TEXT', Lua.ORDER_NONE) || '\'\'';
232
+ const text = Lua.valueToCode(block, 'TEXT', Lua.ORDER_NONE) || "''";
218
233
  const code = 'string.gsub(' + text + ', "' + operator + '", "%1")';
219
234
  return [code, Lua.ORDER_HIGH];
220
235
  };
221
236
 
222
237
  Lua['text_print'] = function(block) {
223
238
  // Print statement.
224
- const msg = Lua.valueToCode(block, 'TEXT', Lua.ORDER_NONE) || '\'\'';
239
+ const msg = Lua.valueToCode(block, 'TEXT', Lua.ORDER_NONE) || "''";
225
240
  return 'print(' + msg + ')\n';
226
241
  };
227
242
 
@@ -233,13 +248,16 @@ Lua['text_prompt_ext'] = function(block) {
233
248
  msg = Lua.quote_(block.getFieldValue('TEXT'));
234
249
  } else {
235
250
  // External message.
236
- msg = Lua.valueToCode(block, 'TEXT', Lua.ORDER_NONE) || '\'\'';
251
+ msg = Lua.valueToCode(block, 'TEXT', Lua.ORDER_NONE) || "''";
237
252
  }
238
253
 
239
- const functionName = Lua.provideFunction_('text_prompt', [
240
- 'function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(msg)', ' io.write(msg)',
241
- ' io.flush()', ' return io.read()', 'end'
242
- ]);
254
+ const functionName = Lua.provideFunction_('text_prompt', `
255
+ function ${Lua.FUNCTION_NAME_PLACEHOLDER_}(msg)
256
+ io.write(msg)
257
+ io.flush()
258
+ return io.read()
259
+ end
260
+ `);
243
261
  let code = functionName + '(' + msg + ')';
244
262
 
245
263
  const toNumber = block.getFieldValue('TYPE') === 'NUMBER';
@@ -252,59 +270,58 @@ Lua['text_prompt_ext'] = function(block) {
252
270
  Lua['text_prompt'] = Lua['text_prompt_ext'];
253
271
 
254
272
  Lua['text_count'] = function(block) {
255
- const text = Lua.valueToCode(block, 'TEXT', Lua.ORDER_NONE) || '\'\'';
256
- const sub = Lua.valueToCode(block, 'SUB', Lua.ORDER_NONE) || '\'\'';
257
- const functionName = Lua.provideFunction_('text_count', [
258
- 'function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(haystack, needle)',
259
- ' if #needle == 0 then',
260
- ' return #haystack + 1',
261
- ' end',
262
- ' local i = 1',
263
- ' local count = 0',
264
- ' while true do',
265
- ' i = string.find(haystack, needle, i, true)',
266
- ' if i == nil then',
267
- ' break',
268
- ' end',
269
- ' count = count + 1',
270
- ' i = i + #needle',
271
- ' end',
272
- ' return count',
273
- 'end',
274
- ]);
273
+ const text = Lua.valueToCode(block, 'TEXT', Lua.ORDER_NONE) || "''";
274
+ const sub = Lua.valueToCode(block, 'SUB', Lua.ORDER_NONE) || "''";
275
+ const functionName = Lua.provideFunction_('text_count', `
276
+ function ${Lua.FUNCTION_NAME_PLACEHOLDER_}(haystack, needle)
277
+ if #needle == 0 then
278
+ return #haystack + 1
279
+ end
280
+ local i = 1
281
+ local count = 0
282
+ while true do
283
+ i = string.find(haystack, needle, i, true)
284
+ if i == nil then
285
+ break
286
+ end
287
+ count = count + 1
288
+ i = i + #needle
289
+ end
290
+ return count
291
+ end
292
+ `);
275
293
  const code = functionName + '(' + text + ', ' + sub + ')';
276
294
  return [code, Lua.ORDER_HIGH];
277
295
  };
278
296
 
279
297
  Lua['text_replace'] = function(block) {
280
- const text = Lua.valueToCode(block, 'TEXT', Lua.ORDER_NONE) || '\'\'';
281
- const from = Lua.valueToCode(block, 'FROM', Lua.ORDER_NONE) || '\'\'';
282
- const to = Lua.valueToCode(block, 'TO', Lua.ORDER_NONE) || '\'\'';
283
- const functionName = Lua.provideFunction_('text_replace', [
284
- 'function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ +
285
- '(haystack, needle, replacement)',
286
- ' local buf = {}',
287
- ' local i = 1',
288
- ' while i <= #haystack do',
289
- ' if string.sub(haystack, i, i + #needle - 1) == needle then',
290
- ' for j = 1, #replacement do',
291
- ' table.insert(buf, string.sub(replacement, j, j))',
292
- ' end',
293
- ' i = i + #needle',
294
- ' else',
295
- ' table.insert(buf, string.sub(haystack, i, i))',
296
- ' i = i + 1',
297
- ' end',
298
- ' end',
299
- ' return table.concat(buf)',
300
- 'end',
301
- ]);
298
+ const text = Lua.valueToCode(block, 'TEXT', Lua.ORDER_NONE) || "''";
299
+ const from = Lua.valueToCode(block, 'FROM', Lua.ORDER_NONE) || "''";
300
+ const to = Lua.valueToCode(block, 'TO', Lua.ORDER_NONE) || "''";
301
+ const functionName = Lua.provideFunction_('text_replace', `
302
+ function ${Lua.FUNCTION_NAME_PLACEHOLDER_}(haystack, needle, replacement)
303
+ local buf = {}
304
+ local i = 1
305
+ while i <= #haystack do
306
+ if string.sub(haystack, i, i + #needle - 1) == needle then
307
+ for j = 1, #replacement do
308
+ table.insert(buf, string.sub(replacement, j, j))
309
+ end
310
+ i = i + #needle
311
+ else
312
+ table.insert(buf, string.sub(haystack, i, i))
313
+ i = i + 1
314
+ end
315
+ end
316
+ return table.concat(buf)
317
+ end
318
+ `);
302
319
  const code = functionName + '(' + text + ', ' + from + ', ' + to + ')';
303
320
  return [code, Lua.ORDER_HIGH];
304
321
  };
305
322
 
306
323
  Lua['text_reverse'] = function(block) {
307
- const text = Lua.valueToCode(block, 'TEXT', Lua.ORDER_NONE) || '\'\'';
324
+ const text = Lua.valueToCode(block, 'TEXT', Lua.ORDER_NONE) || "''";
308
325
  const code = 'string.reverse(' + text + ')';
309
326
  return [code, Lua.ORDER_HIGH];
310
327
  };
@@ -22,12 +22,11 @@ PHP['colour_picker'] = function(block) {
22
22
 
23
23
  PHP['colour_random'] = function(block) {
24
24
  // Generate a random colour.
25
- const functionName = PHP.provideFunction_('colour_random', [
26
- 'function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '() {',
27
- ' return \'#\' . str_pad(dechex(mt_rand(0, 0xFFFFFF)), ' +
28
- '6, \'0\', STR_PAD_LEFT);',
29
- '}'
30
- ]);
25
+ const functionName = PHP.provideFunction_('colour_random', `
26
+ function ${PHP.FUNCTION_NAME_PLACEHOLDER_}() {
27
+ return '#' . str_pad(dechex(mt_rand(0, 0xFFFFFF)), 6, '0', STR_PAD_LEFT);
28
+ }
29
+ `);
31
30
  const code = functionName + '()';
32
31
  return [code, PHP.ORDER_FUNCTION_CALL];
33
32
  };
@@ -37,39 +36,46 @@ PHP['colour_rgb'] = function(block) {
37
36
  const red = PHP.valueToCode(block, 'RED', PHP.ORDER_NONE) || 0;
38
37
  const green = PHP.valueToCode(block, 'GREEN', PHP.ORDER_NONE) || 0;
39
38
  const blue = PHP.valueToCode(block, 'BLUE', PHP.ORDER_NONE) || 0;
40
- const functionName = PHP.provideFunction_('colour_rgb', [
41
- 'function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '($r, $g, $b) {',
42
- ' $r = round(max(min($r, 100), 0) * 2.55);',
43
- ' $g = round(max(min($g, 100), 0) * 2.55);',
44
- ' $b = round(max(min($b, 100), 0) * 2.55);', ' $hex = \'#\';',
45
- ' $hex .= str_pad(dechex($r), 2, \'0\', STR_PAD_LEFT);',
46
- ' $hex .= str_pad(dechex($g), 2, \'0\', STR_PAD_LEFT);',
47
- ' $hex .= str_pad(dechex($b), 2, \'0\', STR_PAD_LEFT);', ' return $hex;',
48
- '}'
49
- ]);
39
+ const functionName = PHP.provideFunction_('colour_rgb', `
40
+ function ${PHP.FUNCTION_NAME_PLACEHOLDER_}($r, $g, $b) {
41
+ $r = round(max(min($r, 100), 0) * 2.55);
42
+ $g = round(max(min($g, 100), 0) * 2.55);
43
+ $b = round(max(min($b, 100), 0) * 2.55);
44
+ $hex = '#';
45
+ $hex .= str_pad(dechex($r), 2, '0', STR_PAD_LEFT);
46
+ $hex .= str_pad(dechex($g), 2, '0', STR_PAD_LEFT);
47
+ $hex .= str_pad(dechex($b), 2, '0', STR_PAD_LEFT);
48
+ return $hex;
49
+ }
50
+ `);
50
51
  const code = functionName + '(' + red + ', ' + green + ', ' + blue + ')';
51
52
  return [code, PHP.ORDER_FUNCTION_CALL];
52
53
  };
53
54
 
54
55
  PHP['colour_blend'] = function(block) {
55
56
  // Blend two colours together.
56
- const c1 = PHP.valueToCode(block, 'COLOUR1', PHP.ORDER_NONE) || '\'#000000\'';
57
- const c2 = PHP.valueToCode(block, 'COLOUR2', PHP.ORDER_NONE) || '\'#000000\'';
57
+ const c1 = PHP.valueToCode(block, 'COLOUR1', PHP.ORDER_NONE) || "'#000000'";
58
+ const c2 = PHP.valueToCode(block, 'COLOUR2', PHP.ORDER_NONE) || "'#000000'";
58
59
  const ratio = PHP.valueToCode(block, 'RATIO', PHP.ORDER_NONE) || 0.5;
59
- const functionName = PHP.provideFunction_('colour_blend', [
60
- 'function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '($c1, $c2, $ratio) {',
61
- ' $ratio = max(min($ratio, 1), 0);', ' $r1 = hexdec(substr($c1, 1, 2));',
62
- ' $g1 = hexdec(substr($c1, 3, 2));', ' $b1 = hexdec(substr($c1, 5, 2));',
63
- ' $r2 = hexdec(substr($c2, 1, 2));', ' $g2 = hexdec(substr($c2, 3, 2));',
64
- ' $b2 = hexdec(substr($c2, 5, 2));',
65
- ' $r = round($r1 * (1 - $ratio) + $r2 * $ratio);',
66
- ' $g = round($g1 * (1 - $ratio) + $g2 * $ratio);',
67
- ' $b = round($b1 * (1 - $ratio) + $b2 * $ratio);', ' $hex = \'#\';',
68
- ' $hex .= str_pad(dechex($r), 2, \'0\', STR_PAD_LEFT);',
69
- ' $hex .= str_pad(dechex($g), 2, \'0\', STR_PAD_LEFT);',
70
- ' $hex .= str_pad(dechex($b), 2, \'0\', STR_PAD_LEFT);', ' return $hex;',
71
- '}'
72
- ]);
60
+ const functionName = PHP.provideFunction_('colour_blend', `
61
+ function ${PHP.FUNCTION_NAME_PLACEHOLDER_}($c1, $c2, $ratio) {
62
+ $ratio = max(min($ratio, 1), 0);
63
+ $r1 = hexdec(substr($c1, 1, 2));
64
+ $g1 = hexdec(substr($c1, 3, 2));
65
+ $b1 = hexdec(substr($c1, 5, 2));
66
+ $r2 = hexdec(substr($c2, 1, 2));
67
+ $g2 = hexdec(substr($c2, 3, 2));
68
+ $b2 = hexdec(substr($c2, 5, 2));
69
+ $r = round($r1 * (1 - $ratio) + $r2 * $ratio);
70
+ $g = round($g1 * (1 - $ratio) + $g2 * $ratio);
71
+ $b = round($b1 * (1 - $ratio) + $b2 * $ratio);
72
+ $hex = '#';
73
+ $hex .= str_pad(dechex($r), 2, '0', STR_PAD_LEFT);
74
+ $hex .= str_pad(dechex($g), 2, '0', STR_PAD_LEFT);
75
+ $hex .= str_pad(dechex($b), 2, '0', STR_PAD_LEFT);
76
+ return $hex;
77
+ }
78
+ `);
73
79
  const code = functionName + '(' + c1 + ', ' + c2 + ', ' + ratio + ')';
74
80
  return [code, PHP.ORDER_FUNCTION_CALL];
75
81
  };