blockly 7.20211209.4 → 8.0.1
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.
- package/blockly.d.ts +18963 -18432
- package/blockly.min.js +5 -4
- package/blockly_compressed.js +4 -3
- package/blockly_compressed.js.map +1 -1
- package/blocks/blocks.js +47 -0
- package/blocks/colour.js +13 -3
- package/blocks/lists.js +22 -13
- package/blocks/logic.js +13 -3
- package/blocks/loops.js +24 -11
- package/blocks/math.js +12 -3
- package/blocks/procedures.js +45 -32
- package/blocks/text.js +22 -13
- package/blocks/variables.js +14 -3
- package/blocks/variables_dynamic.js +13 -3
- package/blocks_compressed.js +1 -1
- package/blocks_compressed.js.map +1 -1
- package/core/block.js +1869 -1814
- package/core/block_drag_surface.js +201 -200
- package/core/block_dragger.js +377 -373
- package/core/block_svg.js +1593 -1479
- package/core/blockly.js +8 -22
- package/core/blocks.js +9 -2
- package/core/browser_events.js +22 -5
- package/core/bubble.js +841 -797
- package/core/bubble_dragger.js +213 -206
- package/core/bump_objects.js +2 -2
- package/core/clipboard.js +9 -9
- package/core/comment.js +353 -332
- package/core/common.js +46 -17
- package/core/component_manager.js +181 -174
- package/core/config.js +87 -0
- package/core/connection.js +595 -584
- package/core/connection_checker.js +242 -244
- package/core/connection_db.js +235 -230
- package/core/contextmenu.js +9 -6
- package/core/contextmenu_items.js +1 -2
- package/core/contextmenu_registry.js +93 -89
- package/core/css.js +474 -474
- package/core/delete_area.js +45 -42
- package/core/drag_target.js +57 -56
- package/core/dropdowndiv.js +153 -163
- package/core/events/events.js +2 -2
- package/core/events/events_abstract.js +89 -77
- package/core/events/events_block_base.js +37 -36
- package/core/events/events_block_change.js +130 -124
- package/core/events/events_block_create.js +73 -71
- package/core/events/events_block_delete.js +84 -82
- package/core/events/events_block_drag.js +50 -49
- package/core/events/events_block_move.js +147 -140
- package/core/events/events_bubble_open.js +51 -50
- package/core/events/events_click.js +48 -44
- package/core/events/events_comment_base.js +72 -69
- package/core/events/events_comment_change.js +63 -61
- package/core/events/events_comment_create.js +44 -42
- package/core/events/events_comment_delete.js +42 -40
- package/core/events/events_comment_move.js +106 -104
- package/core/events/events_marker_move.js +65 -64
- package/core/events/events_selected.js +46 -45
- package/core/events/events_theme_change.js +36 -35
- package/core/events/events_toolbox_item_select.js +46 -45
- package/core/events/events_trashcan_open.js +37 -36
- package/core/events/events_ui.js +47 -46
- package/core/events/events_ui_base.js +30 -29
- package/core/events/events_var_base.js +37 -36
- package/core/events/events_var_create.js +50 -48
- package/core/events/events_var_delete.js +50 -48
- package/core/events/events_var_rename.js +51 -49
- package/core/events/events_viewport.js +66 -65
- package/core/events/utils.js +29 -14
- package/core/events/workspace_events.js +49 -55
- package/core/extensions.js +4 -3
- package/core/field.js +1061 -997
- package/core/field_angle.js +462 -442
- package/core/field_checkbox.js +194 -182
- package/core/field_colour.js +519 -505
- package/core/field_dropdown.js +617 -598
- package/core/field_image.js +229 -220
- package/core/field_label.js +102 -91
- package/core/field_label_serializable.js +42 -41
- package/core/field_multilineinput.js +372 -358
- package/core/field_number.js +272 -253
- package/core/field_textinput.js +499 -467
- package/core/field_variable.js +458 -420
- package/core/flyout_base.js +1005 -952
- package/core/flyout_button.js +277 -260
- package/core/flyout_horizontal.js +304 -302
- package/core/flyout_metrics_manager.js +64 -64
- package/core/flyout_vertical.js +306 -300
- package/core/generator.js +459 -446
- package/core/gesture.js +829 -813
- package/core/grid.js +166 -163
- package/core/icon.js +168 -159
- package/core/inject.js +7 -5
- package/core/input.js +257 -248
- package/core/insertion_marker_manager.js +655 -624
- package/core/internal_constants.js +0 -129
- package/core/keyboard_nav/ast_node.js +605 -596
- package/core/keyboard_nav/basic_cursor.js +166 -165
- package/core/keyboard_nav/cursor.js +99 -97
- package/core/keyboard_nav/marker.js +83 -79
- package/core/keyboard_nav/tab_navigate_cursor.js +18 -23
- package/core/marker_manager.js +153 -141
- package/core/menu.js +377 -372
- package/core/menuitem.js +223 -217
- package/core/metrics_manager.js +403 -390
- package/core/mutator.js +468 -437
- package/core/names.js +229 -188
- package/core/options.js +290 -284
- package/core/procedures.js +29 -17
- package/core/registry.js +19 -16
- package/core/rendered_connection.js +482 -463
- package/core/renderers/common/block_rendering.js +9 -3
- package/core/renderers/common/constants.js +1119 -1112
- package/core/renderers/common/debug.js +14 -0
- package/core/renderers/common/debugger.js +338 -316
- package/core/renderers/common/drawer.js +380 -370
- package/core/renderers/common/i_path_object.js +2 -2
- package/core/renderers/common/info.js +626 -618
- package/core/renderers/common/marker_svg.js +579 -541
- package/core/renderers/common/path_object.js +203 -200
- package/core/renderers/common/renderer.js +220 -218
- package/core/renderers/geras/constants.js +36 -36
- package/core/renderers/geras/drawer.js +155 -147
- package/core/renderers/geras/highlight_constants.js +244 -238
- package/core/renderers/geras/highlighter.js +231 -179
- package/core/renderers/geras/info.js +392 -369
- package/core/renderers/geras/measurables/inline_input.js +25 -19
- package/core/renderers/geras/measurables/statement_input.js +23 -17
- package/core/renderers/geras/path_object.js +106 -121
- package/core/renderers/geras/renderer.js +96 -98
- package/core/renderers/measurables/base.js +30 -18
- package/core/renderers/measurables/bottom_row.js +83 -80
- package/core/renderers/measurables/connection.js +22 -15
- package/core/renderers/measurables/external_value_input.js +35 -22
- package/core/renderers/measurables/field.js +35 -20
- package/core/renderers/measurables/hat.js +18 -13
- package/core/renderers/measurables/icon.js +24 -17
- package/core/renderers/measurables/in_row_spacer.js +15 -13
- package/core/renderers/measurables/inline_input.js +43 -33
- package/core/renderers/measurables/input_connection.js +41 -28
- package/core/renderers/measurables/input_row.js +50 -44
- package/core/renderers/measurables/jagged_edge.js +14 -12
- package/core/renderers/measurables/next_connection.js +16 -14
- package/core/renderers/measurables/output_connection.js +26 -20
- package/core/renderers/measurables/previous_connection.js +16 -15
- package/core/renderers/measurables/round_corner.js +20 -18
- package/core/renderers/measurables/row.js +184 -168
- package/core/renderers/measurables/spacer_row.js +38 -23
- package/core/renderers/measurables/square_corner.js +18 -16
- package/core/renderers/measurables/statement_input.js +23 -20
- package/core/renderers/measurables/top_row.js +88 -85
- package/core/renderers/minimalist/constants.js +8 -7
- package/core/renderers/minimalist/drawer.js +11 -10
- package/core/renderers/minimalist/info.js +18 -18
- package/core/renderers/minimalist/renderer.js +40 -39
- package/core/renderers/thrasos/info.js +258 -248
- package/core/renderers/thrasos/renderer.js +20 -20
- package/core/renderers/zelos/constants.js +898 -873
- package/core/renderers/zelos/drawer.js +186 -169
- package/core/renderers/zelos/info.js +502 -479
- package/core/renderers/zelos/marker_svg.js +129 -115
- package/core/renderers/zelos/measurables/bottom_row.js +31 -30
- package/core/renderers/zelos/measurables/inputs.js +22 -21
- package/core/renderers/zelos/measurables/row_elements.js +14 -13
- package/core/renderers/zelos/measurables/top_row.js +34 -33
- package/core/renderers/zelos/path_object.js +181 -180
- package/core/renderers/zelos/renderer.js +91 -92
- package/core/scrollbar.js +759 -713
- package/core/scrollbar_pair.js +250 -245
- package/core/serialization/blocks.js +26 -10
- package/core/serialization/workspaces.js +3 -2
- package/core/shortcut_registry.js +286 -277
- package/core/sprites.js +31 -0
- package/core/theme.js +135 -141
- package/core/theme_manager.js +147 -143
- package/core/toolbox/category.js +602 -576
- package/core/toolbox/collapsible_category.js +226 -227
- package/core/toolbox/separator.js +70 -61
- package/core/toolbox/toolbox.js +934 -927
- package/core/toolbox/toolbox_item.js +115 -99
- package/core/tooltip.js +108 -35
- package/core/touch.js +8 -3
- package/core/touch_gesture.js +254 -251
- package/core/trashcan.js +606 -595
- package/core/utils/coordinate.js +97 -95
- package/core/utils/dom.js +2 -2
- package/core/utils/global.js +2 -0
- package/core/utils/rect.js +41 -37
- package/core/utils/sentinel.js +25 -0
- package/core/utils/size.js +30 -27
- package/core/utils/svg.js +18 -16
- package/core/variable_map.js +325 -341
- package/core/variable_model.js +55 -54
- package/core/variables.js +9 -2
- package/core/variables_dynamic.js +3 -1
- package/core/warning.js +126 -120
- package/core/widgetdiv.js +4 -4
- package/core/workspace.js +685 -664
- package/core/workspace_audio.js +124 -118
- package/core/workspace_comment.js +308 -298
- package/core/workspace_comment_svg.js +1029 -951
- package/core/workspace_drag_surface_svg.js +147 -140
- package/core/workspace_dragger.js +70 -71
- package/core/workspace_svg.js +2322 -2297
- package/core/xml.js +30 -20
- package/core/zoom_controls.js +431 -439
- package/generators/dart/colour.js +56 -64
- package/generators/dart/lists.js +61 -50
- package/generators/dart/math.js +160 -148
- package/generators/dart/text.js +83 -61
- package/generators/javascript/colour.js +37 -34
- package/generators/javascript/lists.js +50 -43
- package/generators/javascript/math.js +123 -139
- package/generators/javascript/text.js +67 -81
- package/generators/lua/colour.js +25 -23
- package/generators/lua/lists.js +97 -69
- package/generators/lua/logic.js +1 -2
- package/generators/lua/math.js +182 -144
- package/generators/lua/text.js +116 -99
- package/generators/php/colour.js +38 -32
- package/generators/php/lists.js +109 -89
- package/generators/php/math.js +90 -81
- package/generators/php/text.js +63 -61
- package/generators/python/colour.js +18 -18
- package/generators/python/lists.js +38 -30
- package/generators/python/loops.js +12 -8
- package/generators/python/math.js +104 -106
- package/generators/python/text.js +34 -30
- package/msg/smn.js +436 -0
- package/package.json +7 -6
- package/blocks/all.js +0 -23
package/generators/php/text.js
CHANGED
|
@@ -32,22 +32,22 @@ PHP['text_multiline'] = function(block) {
|
|
|
32
32
|
PHP['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 ['
|
|
35
|
+
return ["''", PHP.ORDER_ATOMIC];
|
|
36
36
|
} else if (block.itemCount_ === 1) {
|
|
37
|
-
const element = PHP.valueToCode(block, 'ADD0', PHP.ORDER_NONE) || '
|
|
37
|
+
const element = PHP.valueToCode(block, 'ADD0', PHP.ORDER_NONE) || "''";
|
|
38
38
|
const code = element;
|
|
39
39
|
return [code, PHP.ORDER_NONE];
|
|
40
40
|
} else if (block.itemCount_ === 2) {
|
|
41
41
|
const element0 =
|
|
42
|
-
PHP.valueToCode(block, 'ADD0', PHP.ORDER_STRING_CONCAT) || '
|
|
42
|
+
PHP.valueToCode(block, 'ADD0', PHP.ORDER_STRING_CONCAT) || "''";
|
|
43
43
|
const element1 =
|
|
44
|
-
PHP.valueToCode(block, 'ADD1', PHP.ORDER_STRING_CONCAT) || '
|
|
44
|
+
PHP.valueToCode(block, 'ADD1', PHP.ORDER_STRING_CONCAT) || "''";
|
|
45
45
|
const code = element0 + ' . ' + element1;
|
|
46
46
|
return [code, PHP.ORDER_STRING_CONCAT];
|
|
47
47
|
} else {
|
|
48
48
|
const elements = new Array(block.itemCount_);
|
|
49
49
|
for (let i = 0; i < block.itemCount_; i++) {
|
|
50
|
-
elements[i] = PHP.valueToCode(block, 'ADD' + i, PHP.ORDER_NONE) || '
|
|
50
|
+
elements[i] = PHP.valueToCode(block, 'ADD' + i, PHP.ORDER_NONE) || "''";
|
|
51
51
|
}
|
|
52
52
|
const code = 'implode(\'\', array(' + elements.join(',') + '))';
|
|
53
53
|
return [code, PHP.ORDER_FUNCTION_CALL];
|
|
@@ -58,24 +58,27 @@ PHP['text_append'] = function(block) {
|
|
|
58
58
|
// Append to a variable in place.
|
|
59
59
|
const varName =
|
|
60
60
|
PHP.nameDB_.getName(block.getFieldValue('VAR'), NameType.VARIABLE);
|
|
61
|
-
const value = PHP.valueToCode(block, 'TEXT', PHP.ORDER_ASSIGNMENT) || '
|
|
61
|
+
const value = PHP.valueToCode(block, 'TEXT', PHP.ORDER_ASSIGNMENT) || "''";
|
|
62
62
|
return varName + ' .= ' + value + ';\n';
|
|
63
63
|
};
|
|
64
64
|
|
|
65
65
|
PHP['text_length'] = function(block) {
|
|
66
66
|
// String or array length.
|
|
67
|
-
const functionName = PHP.provideFunction_('length',
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
67
|
+
const functionName = PHP.provideFunction_('length', `
|
|
68
|
+
function ${PHP.FUNCTION_NAME_PLACEHOLDER_}($value) {
|
|
69
|
+
if (is_string($value)) {
|
|
70
|
+
return strlen($value);
|
|
71
|
+
}
|
|
72
|
+
return count($value);
|
|
73
|
+
}
|
|
74
|
+
`);
|
|
75
|
+
const text = PHP.valueToCode(block, 'VALUE', PHP.ORDER_NONE) || "''";
|
|
73
76
|
return [functionName + '(' + text + ')', PHP.ORDER_FUNCTION_CALL];
|
|
74
77
|
};
|
|
75
78
|
|
|
76
79
|
PHP['text_isEmpty'] = function(block) {
|
|
77
80
|
// Is the string null or array empty?
|
|
78
|
-
const text = PHP.valueToCode(block, 'VALUE', PHP.ORDER_NONE) || '
|
|
81
|
+
const text = PHP.valueToCode(block, 'VALUE', PHP.ORDER_NONE) || "''";
|
|
79
82
|
return ['empty(' + text + ')', PHP.ORDER_FUNCTION_CALL];
|
|
80
83
|
};
|
|
81
84
|
|
|
@@ -83,8 +86,8 @@ PHP['text_indexOf'] = function(block) {
|
|
|
83
86
|
// Search the text for a substring.
|
|
84
87
|
const operator =
|
|
85
88
|
block.getFieldValue('END') === 'FIRST' ? 'strpos' : 'strrpos';
|
|
86
|
-
const substring = PHP.valueToCode(block, 'FIND', PHP.ORDER_NONE) || '
|
|
87
|
-
const text = PHP.valueToCode(block, 'VALUE', PHP.ORDER_NONE) || '
|
|
89
|
+
const substring = PHP.valueToCode(block, 'FIND', PHP.ORDER_NONE) || "''";
|
|
90
|
+
const text = PHP.valueToCode(block, 'VALUE', PHP.ORDER_NONE) || "''";
|
|
88
91
|
let errorIndex = ' -1';
|
|
89
92
|
let indexAdjustment = '';
|
|
90
93
|
if (block.workspace.options.oneBasedIndex) {
|
|
@@ -94,13 +97,12 @@ PHP['text_indexOf'] = function(block) {
|
|
|
94
97
|
const functionName = PHP.provideFunction_(
|
|
95
98
|
block.getFieldValue('END') === 'FIRST' ? 'text_indexOf' :
|
|
96
99
|
'text_lastIndexOf',
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
]);
|
|
100
|
+
`
|
|
101
|
+
function ${PHP.FUNCTION_NAME_PLACEHOLDER_}($text, $search) {
|
|
102
|
+
$pos = ${operator}($text, $search);
|
|
103
|
+
return $pos === false ? ${errorIndex} : $pos${indexAdjustment};
|
|
104
|
+
}
|
|
105
|
+
`);
|
|
104
106
|
const code = functionName + '(' + text + ', ' + substring + ')';
|
|
105
107
|
return [code, PHP.ORDER_FUNCTION_CALL];
|
|
106
108
|
};
|
|
@@ -109,7 +111,7 @@ PHP['text_charAt'] = function(block) {
|
|
|
109
111
|
// Get letter at index.
|
|
110
112
|
const where = block.getFieldValue('WHERE') || 'FROM_START';
|
|
111
113
|
const textOrder = (where === 'RANDOM') ? PHP.ORDER_NONE : PHP.ORDER_NONE;
|
|
112
|
-
const text = PHP.valueToCode(block, 'VALUE', textOrder) || '
|
|
114
|
+
const text = PHP.valueToCode(block, 'VALUE', textOrder) || "''";
|
|
113
115
|
switch (where) {
|
|
114
116
|
case 'FIRST': {
|
|
115
117
|
const code = 'substr(' + text + ', 0, 1)';
|
|
@@ -130,10 +132,11 @@ PHP['text_charAt'] = function(block) {
|
|
|
130
132
|
return [code, PHP.ORDER_FUNCTION_CALL];
|
|
131
133
|
}
|
|
132
134
|
case 'RANDOM': {
|
|
133
|
-
const functionName = PHP.provideFunction_('text_random_letter',
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
135
|
+
const functionName = PHP.provideFunction_('text_random_letter', `
|
|
136
|
+
function ${PHP.FUNCTION_NAME_PLACEHOLDER_}($text) {
|
|
137
|
+
return $text[rand(0, strlen($text) - 1)];
|
|
138
|
+
}
|
|
139
|
+
`);
|
|
137
140
|
const code = functionName + '(' + text + ')';
|
|
138
141
|
return [code, PHP.ORDER_FUNCTION_CALL];
|
|
139
142
|
}
|
|
@@ -145,36 +148,35 @@ PHP['text_getSubstring'] = function(block) {
|
|
|
145
148
|
// Get substring.
|
|
146
149
|
const where1 = block.getFieldValue('WHERE1');
|
|
147
150
|
const where2 = block.getFieldValue('WHERE2');
|
|
148
|
-
const text = PHP.valueToCode(block, 'STRING', PHP.ORDER_NONE) || '
|
|
151
|
+
const text = PHP.valueToCode(block, 'STRING', PHP.ORDER_NONE) || "''";
|
|
149
152
|
if (where1 === 'FIRST' && where2 === 'LAST') {
|
|
150
153
|
const code = text;
|
|
151
154
|
return [code, PHP.ORDER_NONE];
|
|
152
155
|
} else {
|
|
153
156
|
const at1 = PHP.getAdjusted(block, 'AT1');
|
|
154
157
|
const at2 = PHP.getAdjusted(block, 'AT2');
|
|
155
|
-
const functionName = PHP.provideFunction_('text_get_substring',
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
]);
|
|
158
|
+
const functionName = PHP.provideFunction_('text_get_substring', `
|
|
159
|
+
function ${PHP.FUNCTION_NAME_PLACEHOLDER_}($text, $where1, $at1, $where2, $at2) {
|
|
160
|
+
if ($where1 == 'FROM_END') {
|
|
161
|
+
$at1 = strlen($text) - 1 - $at1;
|
|
162
|
+
} else if ($where1 == 'FIRST') {
|
|
163
|
+
$at1 = 0;
|
|
164
|
+
} else if ($where1 != 'FROM_START') {
|
|
165
|
+
throw new Exception('Unhandled option (text_get_substring).');
|
|
166
|
+
}
|
|
167
|
+
$length = 0;
|
|
168
|
+
if ($where2 == 'FROM_START') {
|
|
169
|
+
$length = $at2 - $at1 + 1;
|
|
170
|
+
} else if ($where2 == 'FROM_END') {
|
|
171
|
+
$length = strlen($text) - $at1 - $at2;
|
|
172
|
+
} else if ($where2 == 'LAST') {
|
|
173
|
+
$length = strlen($text) - $at1;
|
|
174
|
+
} else {
|
|
175
|
+
throw new Exception('Unhandled option (text_get_substring).');
|
|
176
|
+
}
|
|
177
|
+
return substr($text, $at1, $length);
|
|
178
|
+
}
|
|
179
|
+
`);
|
|
178
180
|
const code = functionName + '(' + text + ', \'' + where1 + '\', ' + at1 +
|
|
179
181
|
', \'' + where2 + '\', ' + at2 + ')';
|
|
180
182
|
return [code, PHP.ORDER_FUNCTION_CALL];
|
|
@@ -183,7 +185,7 @@ PHP['text_getSubstring'] = function(block) {
|
|
|
183
185
|
|
|
184
186
|
PHP['text_changeCase'] = function(block) {
|
|
185
187
|
// Change capitalization.
|
|
186
|
-
const text = PHP.valueToCode(block, 'TEXT', PHP.ORDER_NONE) || '
|
|
188
|
+
const text = PHP.valueToCode(block, 'TEXT', PHP.ORDER_NONE) || "''";
|
|
187
189
|
let code;
|
|
188
190
|
if (block.getFieldValue('CASE') === 'UPPERCASE') {
|
|
189
191
|
code = 'strtoupper(' + text + ')';
|
|
@@ -199,13 +201,13 @@ PHP['text_trim'] = function(block) {
|
|
|
199
201
|
// Trim spaces.
|
|
200
202
|
const OPERATORS = {'LEFT': 'ltrim', 'RIGHT': 'rtrim', 'BOTH': 'trim'};
|
|
201
203
|
const operator = OPERATORS[block.getFieldValue('MODE')];
|
|
202
|
-
const text = PHP.valueToCode(block, 'TEXT', PHP.ORDER_NONE) || '
|
|
204
|
+
const text = PHP.valueToCode(block, 'TEXT', PHP.ORDER_NONE) || "''";
|
|
203
205
|
return [operator + '(' + text + ')', PHP.ORDER_FUNCTION_CALL];
|
|
204
206
|
};
|
|
205
207
|
|
|
206
208
|
PHP['text_print'] = function(block) {
|
|
207
209
|
// Print statement.
|
|
208
|
-
const msg = PHP.valueToCode(block, 'TEXT', PHP.ORDER_NONE) || '
|
|
210
|
+
const msg = PHP.valueToCode(block, 'TEXT', PHP.ORDER_NONE) || "''";
|
|
209
211
|
return 'print(' + msg + ');\n';
|
|
210
212
|
};
|
|
211
213
|
|
|
@@ -217,7 +219,7 @@ PHP['text_prompt_ext'] = function(block) {
|
|
|
217
219
|
msg = PHP.quote_(block.getFieldValue('TEXT'));
|
|
218
220
|
} else {
|
|
219
221
|
// External message.
|
|
220
|
-
msg = PHP.valueToCode(block, 'TEXT', PHP.ORDER_NONE) || '
|
|
222
|
+
msg = PHP.valueToCode(block, 'TEXT', PHP.ORDER_NONE) || "''";
|
|
221
223
|
}
|
|
222
224
|
let code = 'readline(' + msg + ')';
|
|
223
225
|
const toNumber = block.getFieldValue('TYPE') === 'NUMBER';
|
|
@@ -230,8 +232,8 @@ PHP['text_prompt_ext'] = function(block) {
|
|
|
230
232
|
PHP['text_prompt'] = PHP['text_prompt_ext'];
|
|
231
233
|
|
|
232
234
|
PHP['text_count'] = function(block) {
|
|
233
|
-
const text = PHP.valueToCode(block, 'TEXT', PHP.ORDER_NONE) || '
|
|
234
|
-
const sub = PHP.valueToCode(block, 'SUB', PHP.ORDER_NONE) || '
|
|
235
|
+
const text = PHP.valueToCode(block, 'TEXT', PHP.ORDER_NONE) || "''";
|
|
236
|
+
const sub = PHP.valueToCode(block, 'SUB', PHP.ORDER_NONE) || "''";
|
|
235
237
|
const code = 'strlen(' + sub + ') === 0' +
|
|
236
238
|
' ? strlen(' + text + ') + 1' +
|
|
237
239
|
' : substr_count(' + text + ', ' + sub + ')';
|
|
@@ -239,15 +241,15 @@ PHP['text_count'] = function(block) {
|
|
|
239
241
|
};
|
|
240
242
|
|
|
241
243
|
PHP['text_replace'] = function(block) {
|
|
242
|
-
const text = PHP.valueToCode(block, 'TEXT', PHP.ORDER_NONE) || '
|
|
243
|
-
const from = PHP.valueToCode(block, 'FROM', PHP.ORDER_NONE) || '
|
|
244
|
-
const to = PHP.valueToCode(block, 'TO', PHP.ORDER_NONE) || '
|
|
244
|
+
const text = PHP.valueToCode(block, 'TEXT', PHP.ORDER_NONE) || "''";
|
|
245
|
+
const from = PHP.valueToCode(block, 'FROM', PHP.ORDER_NONE) || "''";
|
|
246
|
+
const to = PHP.valueToCode(block, 'TO', PHP.ORDER_NONE) || "''";
|
|
245
247
|
const code = 'str_replace(' + from + ', ' + to + ', ' + text + ')';
|
|
246
248
|
return [code, PHP.ORDER_FUNCTION_CALL];
|
|
247
249
|
};
|
|
248
250
|
|
|
249
251
|
PHP['text_reverse'] = function(block) {
|
|
250
|
-
const text = PHP.valueToCode(block, 'TEXT', PHP.ORDER_NONE) || '
|
|
252
|
+
const text = PHP.valueToCode(block, 'TEXT', PHP.ORDER_NONE) || "''";
|
|
251
253
|
const code = 'strrev(' + text + ')';
|
|
252
254
|
return [code, PHP.ORDER_FUNCTION_CALL];
|
|
253
255
|
};
|
|
@@ -29,13 +29,13 @@ Python['colour_random'] = function(block) {
|
|
|
29
29
|
|
|
30
30
|
Python['colour_rgb'] = function(block) {
|
|
31
31
|
// Compose a colour from RGB components expressed as percentages.
|
|
32
|
-
const functionName = Python.provideFunction_('colour_rgb',
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
32
|
+
const functionName = Python.provideFunction_('colour_rgb', `
|
|
33
|
+
def ${Python.FUNCTION_NAME_PLACEHOLDER_}(r, g, b):
|
|
34
|
+
r = round(min(100, max(0, r)) * 2.55)
|
|
35
|
+
g = round(min(100, max(0, g)) * 2.55)
|
|
36
|
+
b = round(min(100, max(0, b)) * 2.55)
|
|
37
|
+
return \'#%02x%02x%02x\' % (r, g, b)
|
|
38
|
+
`);
|
|
39
39
|
const r = Python.valueToCode(block, 'RED', Python.ORDER_NONE) || 0;
|
|
40
40
|
const g = Python.valueToCode(block, 'GREEN', Python.ORDER_NONE) || 0;
|
|
41
41
|
const b = Python.valueToCode(block, 'BLUE', Python.ORDER_NONE) || 0;
|
|
@@ -45,17 +45,17 @@ Python['colour_rgb'] = function(block) {
|
|
|
45
45
|
|
|
46
46
|
Python['colour_blend'] = function(block) {
|
|
47
47
|
// Blend two colours together.
|
|
48
|
-
const functionName = Python.provideFunction_('colour_blend',
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
48
|
+
const functionName = Python.provideFunction_('colour_blend', `
|
|
49
|
+
def ${Python.FUNCTION_NAME_PLACEHOLDER_}(colour1, colour2, ratio):
|
|
50
|
+
r1, r2 = int(colour1[1:3], 16), int(colour2[1:3], 16)
|
|
51
|
+
g1, g2 = int(colour1[3:5], 16), int(colour2[3:5], 16)
|
|
52
|
+
b1, b2 = int(colour1[5:7], 16), int(colour2[5:7], 16)
|
|
53
|
+
ratio = min(1, max(0, ratio))
|
|
54
|
+
r = round(r1 * (1 - ratio) + r2 * ratio)
|
|
55
|
+
g = round(g1 * (1 - ratio) + g2 * ratio)
|
|
56
|
+
b = round(b1 * (1 - ratio) + b2 * ratio)
|
|
57
|
+
return \'#%02x%02x%02x\' % (r, g, b)
|
|
58
|
+
`);
|
|
59
59
|
const colour1 =
|
|
60
60
|
Python.valueToCode(block, 'COLOUR1', Python.ORDER_NONE) || '\'#000000\'';
|
|
61
61
|
const colour2 =
|
|
@@ -57,7 +57,7 @@ Python['lists_isEmpty'] = function(block) {
|
|
|
57
57
|
Python['lists_indexOf'] = function(block) {
|
|
58
58
|
// Find an item in the list.
|
|
59
59
|
const item = Python.valueToCode(block, 'FIND', Python.ORDER_NONE) || '[]';
|
|
60
|
-
const list = Python.valueToCode(block, 'VALUE', Python.ORDER_NONE) || '
|
|
60
|
+
const list = Python.valueToCode(block, 'VALUE', Python.ORDER_NONE) || "''";
|
|
61
61
|
let errorIndex = ' -1';
|
|
62
62
|
let firstIndexAdjustment = '';
|
|
63
63
|
let lastIndexAdjustment = ' - 1';
|
|
@@ -68,21 +68,22 @@ Python['lists_indexOf'] = function(block) {
|
|
|
68
68
|
lastIndexAdjustment = '';
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
let functionName;
|
|
71
72
|
if (block.getFieldValue('END') === 'FIRST') {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
73
|
+
functionName = Python.provideFunction_('first_index', `
|
|
74
|
+
def ${Python.FUNCTION_NAME_PLACEHOLDER_}(my_list, elem):
|
|
75
|
+
try: index = my_list.index(elem)${firstIndexAdjustment}
|
|
76
|
+
except: index =${errorIndex}
|
|
77
|
+
return index
|
|
78
|
+
`);
|
|
79
|
+
} else {
|
|
80
|
+
functionName = Python.provideFunction_('last_index', `
|
|
81
|
+
def ${Python.FUNCTION_NAME_PLACEHOLDER_}(my_list, elem):
|
|
82
|
+
try: index = len(my_list) - my_list[::-1].index(elem)${lastIndexAdjustment}
|
|
83
|
+
except: index =${errorIndex}
|
|
84
|
+
return index
|
|
85
|
+
`);
|
|
79
86
|
}
|
|
80
|
-
const functionName = Python.provideFunction_('last_index', [
|
|
81
|
-
'def ' + Python.FUNCTION_NAME_PLACEHOLDER_ + '(my_list, elem):',
|
|
82
|
-
' try: index = len(my_list) - my_list[::-1].index(elem)' +
|
|
83
|
-
lastIndexAdjustment,
|
|
84
|
-
' except: index =' + errorIndex, ' return index'
|
|
85
|
-
]);
|
|
86
87
|
const code = functionName + '(' + list + ', ' + item + ')';
|
|
87
88
|
return [code, Python.ORDER_FUNCTION_CALL];
|
|
88
89
|
};
|
|
@@ -152,11 +153,11 @@ Python['lists_getIndex'] = function(block) {
|
|
|
152
153
|
return [code, Python.ORDER_FUNCTION_CALL];
|
|
153
154
|
} else {
|
|
154
155
|
const functionName =
|
|
155
|
-
Python.provideFunction_('lists_remove_random_item',
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
156
|
+
Python.provideFunction_('lists_remove_random_item', `
|
|
157
|
+
def ${Python.FUNCTION_NAME_PLACEHOLDER_}(myList):
|
|
158
|
+
x = int(random.random() * len(myList))
|
|
159
|
+
return myList.pop(x)
|
|
160
|
+
`);
|
|
160
161
|
const code = functionName + '(' + list + ')';
|
|
161
162
|
if (mode === 'GET_REMOVE') {
|
|
162
163
|
return [code, Python.ORDER_FUNCTION_CALL];
|
|
@@ -294,15 +295,22 @@ Python['lists_sort'] = function(block) {
|
|
|
294
295
|
const list = (Python.valueToCode(block, 'LIST', Python.ORDER_NONE) || '[]');
|
|
295
296
|
const type = block.getFieldValue('TYPE');
|
|
296
297
|
const reverse = block.getFieldValue('DIRECTION') === '1' ? 'False' : 'True';
|
|
297
|
-
const sortFunctionName = Python.provideFunction_('lists_sort',
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
298
|
+
const sortFunctionName = Python.provideFunction_('lists_sort', `
|
|
299
|
+
def ${Python.FUNCTION_NAME_PLACEHOLDER_}(my_list, type, reverse):
|
|
300
|
+
def try_float(s):
|
|
301
|
+
try:
|
|
302
|
+
return float(s)
|
|
303
|
+
except:
|
|
304
|
+
return 0
|
|
305
|
+
key_funcs = {
|
|
306
|
+
"NUMERIC": try_float,
|
|
307
|
+
"TEXT": str,
|
|
308
|
+
"IGNORE_CASE": lambda s: str(s).lower()
|
|
309
|
+
}
|
|
310
|
+
key_func = key_funcs[type]
|
|
311
|
+
list_cpy = list(my_list)
|
|
312
|
+
return sorted(list_cpy, key=key_func, reverse=reverse)
|
|
313
|
+
`);
|
|
306
314
|
|
|
307
315
|
const code =
|
|
308
316
|
sortFunctionName + '(' + list + ', "' + type + '", ' + reverse + ')';
|
|
@@ -315,14 +323,14 @@ Python['lists_split'] = function(block) {
|
|
|
315
323
|
let code;
|
|
316
324
|
if (mode === 'SPLIT') {
|
|
317
325
|
const value_input =
|
|
318
|
-
Python.valueToCode(block, 'INPUT', Python.ORDER_MEMBER) || '
|
|
326
|
+
Python.valueToCode(block, 'INPUT', Python.ORDER_MEMBER) || "''";
|
|
319
327
|
const value_delim = Python.valueToCode(block, 'DELIM', Python.ORDER_NONE);
|
|
320
328
|
code = value_input + '.split(' + value_delim + ')';
|
|
321
329
|
} else if (mode === 'JOIN') {
|
|
322
330
|
const value_input =
|
|
323
331
|
Python.valueToCode(block, 'INPUT', Python.ORDER_NONE) || '[]';
|
|
324
332
|
const value_delim =
|
|
325
|
-
Python.valueToCode(block, 'DELIM', Python.ORDER_MEMBER) || '
|
|
333
|
+
Python.valueToCode(block, 'DELIM', Python.ORDER_MEMBER) || "''";
|
|
326
334
|
code = value_delim + '.join(' + value_input + ')';
|
|
327
335
|
} else {
|
|
328
336
|
throw Error('Unknown mode: ' + mode);
|
|
@@ -70,16 +70,20 @@ Python['controls_for'] = function(block) {
|
|
|
70
70
|
|
|
71
71
|
// Helper functions.
|
|
72
72
|
const defineUpRange = function() {
|
|
73
|
-
return Python.provideFunction_('upRange',
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
return Python.provideFunction_('upRange', `
|
|
74
|
+
def ${Python.FUNCTION_NAME_PLACEHOLDER_}(start, stop, step):
|
|
75
|
+
while start <= stop:
|
|
76
|
+
yield start
|
|
77
|
+
start += abs(step)
|
|
78
|
+
`);
|
|
77
79
|
};
|
|
78
80
|
const defineDownRange = function() {
|
|
79
|
-
return Python.provideFunction_('downRange',
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
return Python.provideFunction_('downRange', `
|
|
82
|
+
def ${Python.FUNCTION_NAME_PLACEHOLDER_}(start, stop, step):
|
|
83
|
+
while start >= stop:
|
|
84
|
+
yield start
|
|
85
|
+
start -= abs(step)
|
|
86
|
+
`);
|
|
83
87
|
};
|
|
84
88
|
// Arguments are legal Python code (numbers or strings returned by scrub()).
|
|
85
89
|
const generateUpDownRange = function(start, end, inc) {
|