blockly 7.20211209.2 → 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.
- package/blockly.d.ts +18963 -18432
- package/blockly.min.js +852 -844
- package/blockly_compressed.js +669 -664
- 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 +41 -27
- package/blocks/text.js +22 -13
- package/blocks/variables.js +14 -3
- package/blocks/variables_dynamic.js +13 -3
- package/blocks_compressed.js +146 -141
- 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 +19 -9
- 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/dart_compressed.js +40 -43
- package/dart_compressed.js.map +1 -1
- 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/javascript_compressed.js +37 -39
- package/javascript_compressed.js.map +1 -1
- package/lua_compressed.js +39 -42
- package/lua_compressed.js.map +1 -1
- package/msg/az.js +2 -2
- package/msg/be.js +4 -4
- package/msg/cs.js +15 -15
- package/msg/de.js +1 -1
- package/msg/diq.js +1 -1
- package/msg/eo.js +1 -1
- package/msg/es.js +1 -1
- package/msg/fa.js +1 -1
- package/msg/fr.js +4 -4
- package/msg/he.js +1 -1
- package/msg/hr.js +2 -2
- package/msg/hy.js +2 -2
- package/msg/id.js +12 -12
- package/msg/inh.js +14 -14
- package/msg/ja.js +7 -7
- package/msg/lv.js +29 -29
- package/msg/pa.js +3 -3
- package/msg/smn.js +436 -0
- package/msg/te.js +1 -1
- package/msg/yue.js +1 -1
- package/msg/zh-hans.js +3 -3
- package/msg/zh-hant.js +3 -3
- package/package.json +7 -6
- package/php_compressed.js +38 -42
- package/php_compressed.js.map +1 -1
- package/python_compressed.js +26 -25
- package/python_compressed.js.map +1 -1
- package/blocks/all.js +0 -23
package/core/field_number.js
CHANGED
|
@@ -17,304 +17,323 @@ goog.module('Blockly.FieldNumber');
|
|
|
17
17
|
|
|
18
18
|
const aria = goog.require('Blockly.utils.aria');
|
|
19
19
|
const fieldRegistry = goog.require('Blockly.fieldRegistry');
|
|
20
|
-
const
|
|
20
|
+
const {Field} = goog.require('Blockly.Field');
|
|
21
21
|
const {FieldTextInput} = goog.require('Blockly.FieldTextInput');
|
|
22
|
+
/* eslint-disable-next-line no-unused-vars */
|
|
23
|
+
const {Sentinel} = goog.requireType('Blockly.utils.Sentinel');
|
|
22
24
|
|
|
23
25
|
|
|
24
26
|
/**
|
|
25
27
|
* Class for an editable number field.
|
|
26
|
-
* @param {string|number=} opt_value The initial value of the field. Should cast
|
|
27
|
-
* to a number. Defaults to 0.
|
|
28
|
-
* @param {?(string|number)=} opt_min Minimum value.
|
|
29
|
-
* @param {?(string|number)=} opt_max Maximum value.
|
|
30
|
-
* @param {?(string|number)=} opt_precision Precision for value.
|
|
31
|
-
* @param {?Function=} opt_validator A function that is called to validate
|
|
32
|
-
* changes to the field's value. Takes in a number & returns a validated
|
|
33
|
-
* number, or null to abort the change.
|
|
34
|
-
* @param {Object=} opt_config A map of options used to configure the field.
|
|
35
|
-
* See the [field creation documentation]{@link
|
|
36
|
-
* https://developers.google.com/blockly/guides/create-custom-blocks/fields/built-in-fields/number#creation}
|
|
37
|
-
* for a list of properties this parameter supports.
|
|
38
28
|
* @extends {FieldTextInput}
|
|
39
|
-
* @constructor
|
|
40
29
|
* @alias Blockly.FieldNumber
|
|
41
30
|
*/
|
|
42
|
-
|
|
43
|
-
opt_value, opt_min, opt_max, opt_precision, opt_validator, opt_config) {
|
|
31
|
+
class FieldNumber extends FieldTextInput {
|
|
44
32
|
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
33
|
+
* @param {(string|number|!Sentinel)=} opt_value The initial value of
|
|
34
|
+
* the field. Should cast to a number. Defaults to 0.
|
|
35
|
+
* Also accepts Field.SKIP_SETUP if you wish to skip setup (only used by
|
|
36
|
+
* subclasses that want to handle configuration and setting the field
|
|
37
|
+
* value after their own constructors have run).
|
|
38
|
+
* @param {?(string|number)=} opt_min Minimum value. Will only be used if
|
|
39
|
+
* opt_config is not provided.
|
|
40
|
+
* @param {?(string|number)=} opt_max Maximum value. Will only be used if
|
|
41
|
+
* opt_config is not provided.
|
|
42
|
+
* @param {?(string|number)=} opt_precision Precision for value. Will only be
|
|
43
|
+
* used if opt_config is not provided.
|
|
44
|
+
* @param {?Function=} opt_validator A function that is called to validate
|
|
45
|
+
* changes to the field's value. Takes in a number & returns a validated
|
|
46
|
+
* number, or null to abort the change.
|
|
47
|
+
* @param {Object=} opt_config A map of options used to configure the field.
|
|
48
|
+
* See the [field creation documentation]{@link
|
|
49
|
+
* https://developers.google.com/blockly/guides/create-custom-blocks/fields/built-in-fields/number#creation}
|
|
50
|
+
* for a list of properties this parameter supports.
|
|
48
51
|
*/
|
|
49
|
-
|
|
52
|
+
constructor(
|
|
53
|
+
opt_value, opt_min, opt_max, opt_precision, opt_validator, opt_config) {
|
|
54
|
+
// Pass SENTINEL so that we can define properties before value validation.
|
|
55
|
+
super(Field.SKIP_SETUP);
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The minimum value this number field can contain.
|
|
59
|
+
* @type {number}
|
|
60
|
+
* @protected
|
|
61
|
+
*/
|
|
62
|
+
this.min_ = -Infinity;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The maximum value this number field can contain.
|
|
66
|
+
* @type {number}
|
|
67
|
+
* @protected
|
|
68
|
+
*/
|
|
69
|
+
this.max_ = Infinity;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The multiple to which this fields value is rounded.
|
|
73
|
+
* @type {number}
|
|
74
|
+
* @protected
|
|
75
|
+
*/
|
|
76
|
+
this.precision_ = 0;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* The number of decimal places to allow, or null to allow any number of
|
|
80
|
+
* decimal digits.
|
|
81
|
+
* @type {?number}
|
|
82
|
+
* @private
|
|
83
|
+
*/
|
|
84
|
+
this.decimalPlaces_ = null;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Serializable fields are saved by the serializer, non-serializable fields
|
|
88
|
+
* are not. Editable fields should also be serializable.
|
|
89
|
+
* @type {boolean}
|
|
90
|
+
*/
|
|
91
|
+
this.SERIALIZABLE = true;
|
|
92
|
+
|
|
93
|
+
if (opt_value === Field.SKIP_SETUP) return;
|
|
94
|
+
if (opt_config) {
|
|
95
|
+
this.configure_(opt_config);
|
|
96
|
+
} else {
|
|
97
|
+
this.setConstraints(opt_min, opt_max, opt_precision);
|
|
98
|
+
}
|
|
99
|
+
this.setValue(opt_value);
|
|
100
|
+
if (opt_validator) this.setValidator(opt_validator);
|
|
101
|
+
}
|
|
50
102
|
|
|
51
103
|
/**
|
|
52
|
-
*
|
|
53
|
-
* @
|
|
104
|
+
* Configure the field based on the given map of options.
|
|
105
|
+
* @param {!Object} config A map of options to configure the field based on.
|
|
54
106
|
* @protected
|
|
107
|
+
* @override
|
|
55
108
|
*/
|
|
56
|
-
|
|
109
|
+
configure_(config) {
|
|
110
|
+
super.configure_(config);
|
|
111
|
+
this.setMinInternal_(config['min']);
|
|
112
|
+
this.setMaxInternal_(config['max']);
|
|
113
|
+
this.setPrecisionInternal_(config['precision']);
|
|
114
|
+
}
|
|
57
115
|
|
|
58
116
|
/**
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
117
|
+
* Set the maximum, minimum and precision constraints on this field.
|
|
118
|
+
* Any of these properties may be undefined or NaN to be disabled.
|
|
119
|
+
* Setting precision (usually a power of 10) enforces a minimum step between
|
|
120
|
+
* values. That is, the user's value will rounded to the closest multiple of
|
|
121
|
+
* precision. The least significant digit place is inferred from the
|
|
122
|
+
* precision. Integers values can be enforces by choosing an integer
|
|
123
|
+
* precision.
|
|
124
|
+
* @param {?(number|string|undefined)} min Minimum value.
|
|
125
|
+
* @param {?(number|string|undefined)} max Maximum value.
|
|
126
|
+
* @param {?(number|string|undefined)} precision Precision for value.
|
|
62
127
|
*/
|
|
63
|
-
|
|
128
|
+
setConstraints(min, max, precision) {
|
|
129
|
+
this.setMinInternal_(min);
|
|
130
|
+
this.setMaxInternal_(max);
|
|
131
|
+
this.setPrecisionInternal_(precision);
|
|
132
|
+
this.setValue(this.getValue());
|
|
133
|
+
}
|
|
64
134
|
|
|
65
135
|
/**
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
* @
|
|
69
|
-
* @private
|
|
136
|
+
* Sets the minimum value this field can contain. Updates the value to
|
|
137
|
+
* reflect.
|
|
138
|
+
* @param {?(number|string|undefined)} min Minimum value.
|
|
70
139
|
*/
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
this, opt_value, opt_validator, opt_config);
|
|
75
|
-
|
|
76
|
-
if (!opt_config) { // Only do one kind of configuration or the other.
|
|
77
|
-
this.setConstraints(opt_min, opt_max, opt_precision);
|
|
140
|
+
setMin(min) {
|
|
141
|
+
this.setMinInternal_(min);
|
|
142
|
+
this.setValue(this.getValue());
|
|
78
143
|
}
|
|
79
|
-
};
|
|
80
|
-
object.inherits(FieldNumber, FieldTextInput);
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* The default value for this field.
|
|
84
|
-
* @type {*}
|
|
85
|
-
* @protected
|
|
86
|
-
*/
|
|
87
|
-
FieldNumber.prototype.DEFAULT_VALUE = 0;
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Construct a FieldNumber from a JSON arg object.
|
|
91
|
-
* @param {!Object} options A JSON object with options (value, min, max, and
|
|
92
|
-
* precision).
|
|
93
|
-
* @return {!FieldNumber} The new field instance.
|
|
94
|
-
* @package
|
|
95
|
-
* @nocollapse
|
|
96
|
-
*/
|
|
97
|
-
FieldNumber.fromJson = function(options) {
|
|
98
|
-
// `this` might be a subclass of FieldNumber if that class doesn't override
|
|
99
|
-
// the static fromJson method.
|
|
100
|
-
return new this(
|
|
101
|
-
options['value'], undefined, undefined, undefined, undefined, options);
|
|
102
|
-
};
|
|
103
144
|
|
|
104
|
-
/**
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
this.setMaxInternal_(config['max']);
|
|
121
|
-
this.setPrecisionInternal_(config['precision']);
|
|
122
|
-
};
|
|
145
|
+
/**
|
|
146
|
+
* Sets the minimum value this field can contain. Called internally to avoid
|
|
147
|
+
* value updates.
|
|
148
|
+
* @param {?(number|string|undefined)} min Minimum value.
|
|
149
|
+
* @private
|
|
150
|
+
*/
|
|
151
|
+
setMinInternal_(min) {
|
|
152
|
+
if (min == null) {
|
|
153
|
+
this.min_ = -Infinity;
|
|
154
|
+
} else {
|
|
155
|
+
min = Number(min);
|
|
156
|
+
if (!isNaN(min)) {
|
|
157
|
+
this.min_ = min;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
123
161
|
|
|
124
|
-
/**
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
* @param {?(number|string|undefined)} max Maximum value.
|
|
133
|
-
* @param {?(number|string|undefined)} precision Precision for value.
|
|
134
|
-
*/
|
|
135
|
-
FieldNumber.prototype.setConstraints = function(min, max, precision) {
|
|
136
|
-
this.setMinInternal_(min);
|
|
137
|
-
this.setMaxInternal_(max);
|
|
138
|
-
this.setPrecisionInternal_(precision);
|
|
139
|
-
this.setValue(this.getValue());
|
|
140
|
-
};
|
|
162
|
+
/**
|
|
163
|
+
* Returns the current minimum value this field can contain. Default is
|
|
164
|
+
* -Infinity.
|
|
165
|
+
* @return {number} The current minimum value this field can contain.
|
|
166
|
+
*/
|
|
167
|
+
getMin() {
|
|
168
|
+
return this.min_;
|
|
169
|
+
}
|
|
141
170
|
|
|
142
|
-
/**
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
171
|
+
/**
|
|
172
|
+
* Sets the maximum value this field can contain. Updates the value to
|
|
173
|
+
* reflect.
|
|
174
|
+
* @param {?(number|string|undefined)} max Maximum value.
|
|
175
|
+
*/
|
|
176
|
+
setMax(max) {
|
|
177
|
+
this.setMaxInternal_(max);
|
|
178
|
+
this.setValue(this.getValue());
|
|
179
|
+
}
|
|
150
180
|
|
|
151
|
-
/**
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
181
|
+
/**
|
|
182
|
+
* Sets the maximum value this field can contain. Called internally to avoid
|
|
183
|
+
* value updates.
|
|
184
|
+
* @param {?(number|string|undefined)} max Maximum value.
|
|
185
|
+
* @private
|
|
186
|
+
*/
|
|
187
|
+
setMaxInternal_(max) {
|
|
188
|
+
if (max == null) {
|
|
189
|
+
this.max_ = Infinity;
|
|
190
|
+
} else {
|
|
191
|
+
max = Number(max);
|
|
192
|
+
if (!isNaN(max)) {
|
|
193
|
+
this.max_ = max;
|
|
194
|
+
}
|
|
164
195
|
}
|
|
165
196
|
}
|
|
166
|
-
};
|
|
167
197
|
|
|
168
|
-
/**
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
198
|
+
/**
|
|
199
|
+
* Returns the current maximum value this field can contain. Default is
|
|
200
|
+
* Infinity.
|
|
201
|
+
* @return {number} The current maximum value this field can contain.
|
|
202
|
+
*/
|
|
203
|
+
getMax() {
|
|
204
|
+
return this.max_;
|
|
205
|
+
}
|
|
176
206
|
|
|
177
|
-
/**
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
207
|
+
/**
|
|
208
|
+
* Sets the precision of this field's value, i.e. the number to which the
|
|
209
|
+
* value is rounded. Updates the field to reflect.
|
|
210
|
+
* @param {?(number|string|undefined)} precision The number to which the
|
|
211
|
+
* field's value is rounded.
|
|
212
|
+
*/
|
|
213
|
+
setPrecision(precision) {
|
|
214
|
+
this.setPrecisionInternal_(precision);
|
|
215
|
+
this.setValue(this.getValue());
|
|
216
|
+
}
|
|
185
217
|
|
|
186
|
-
/**
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
this.
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
218
|
+
/**
|
|
219
|
+
* Sets the precision of this field's value. Called internally to avoid
|
|
220
|
+
* value updates.
|
|
221
|
+
* @param {?(number|string|undefined)} precision The number to which the
|
|
222
|
+
* field's value is rounded.
|
|
223
|
+
* @private
|
|
224
|
+
*/
|
|
225
|
+
setPrecisionInternal_(precision) {
|
|
226
|
+
this.precision_ = Number(precision) || 0;
|
|
227
|
+
let precisionString = String(this.precision_);
|
|
228
|
+
if (precisionString.indexOf('e') !== -1) {
|
|
229
|
+
// String() is fast. But it turns .0000001 into '1e-7'.
|
|
230
|
+
// Use the much slower toLocaleString to access all the digits.
|
|
231
|
+
precisionString =
|
|
232
|
+
this.precision_.toLocaleString('en-US', {maximumFractionDigits: 20});
|
|
233
|
+
}
|
|
234
|
+
const decimalIndex = precisionString.indexOf('.');
|
|
235
|
+
if (decimalIndex === -1) {
|
|
236
|
+
// If the precision is 0 (float) allow any number of decimals,
|
|
237
|
+
// otherwise allow none.
|
|
238
|
+
this.decimalPlaces_ = precision ? 0 : null;
|
|
239
|
+
} else {
|
|
240
|
+
this.decimalPlaces_ = precisionString.length - decimalIndex - 1;
|
|
199
241
|
}
|
|
200
242
|
}
|
|
201
|
-
};
|
|
202
243
|
|
|
203
|
-
/**
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
244
|
+
/**
|
|
245
|
+
* Returns the current precision of this field. The precision being the
|
|
246
|
+
* number to which the field's value is rounded. A precision of 0 means that
|
|
247
|
+
* the value is not rounded.
|
|
248
|
+
* @return {number} The number to which this field's value is rounded.
|
|
249
|
+
*/
|
|
250
|
+
getPrecision() {
|
|
251
|
+
return this.precision_;
|
|
252
|
+
}
|
|
211
253
|
|
|
212
|
-
/**
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
254
|
+
/**
|
|
255
|
+
* Ensure that the input value is a valid number (must fulfill the
|
|
256
|
+
* constraints placed on the field).
|
|
257
|
+
* @param {*=} opt_newValue The input value.
|
|
258
|
+
* @return {?number} A valid number, or null if invalid.
|
|
259
|
+
* @protected
|
|
260
|
+
* @override
|
|
261
|
+
*/
|
|
262
|
+
doClassValidation_(opt_newValue) {
|
|
263
|
+
if (opt_newValue === null) {
|
|
264
|
+
return null;
|
|
265
|
+
}
|
|
266
|
+
// Clean up text.
|
|
267
|
+
let newValue = String(opt_newValue);
|
|
268
|
+
// TODO: Handle cases like 'ten', '1.203,14', etc.
|
|
269
|
+
// 'O' is sometimes mistaken for '0' by inexperienced users.
|
|
270
|
+
newValue = newValue.replace(/O/ig, '0');
|
|
271
|
+
// Strip out thousands separators.
|
|
272
|
+
newValue = newValue.replace(/,/g, '');
|
|
273
|
+
// Ignore case of 'Infinity'.
|
|
274
|
+
newValue = newValue.replace(/infinity/i, 'Infinity');
|
|
222
275
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
//
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
if (decimalIndex === -1) {
|
|
241
|
-
// If the precision is 0 (float) allow any number of decimals,
|
|
242
|
-
// otherwise allow none.
|
|
243
|
-
this.decimalPlaces_ = precision ? 0 : null;
|
|
244
|
-
} else {
|
|
245
|
-
this.decimalPlaces_ = precisionString.length - decimalIndex - 1;
|
|
276
|
+
// Clean up number.
|
|
277
|
+
let n = Number(newValue || 0);
|
|
278
|
+
if (isNaN(n)) {
|
|
279
|
+
// Invalid number.
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
// Get the value in range.
|
|
283
|
+
n = Math.min(Math.max(n, this.min_), this.max_);
|
|
284
|
+
// Round to nearest multiple of precision.
|
|
285
|
+
if (this.precision_ && isFinite(n)) {
|
|
286
|
+
n = Math.round(n / this.precision_) * this.precision_;
|
|
287
|
+
}
|
|
288
|
+
// Clean up floating point errors.
|
|
289
|
+
if (this.decimalPlaces_ !== null) {
|
|
290
|
+
n = Number(n.toFixed(this.decimalPlaces_));
|
|
291
|
+
}
|
|
292
|
+
return n;
|
|
246
293
|
}
|
|
247
|
-
};
|
|
248
294
|
|
|
249
|
-
/**
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
};
|
|
295
|
+
/**
|
|
296
|
+
* Create the number input editor widget.
|
|
297
|
+
* @return {!HTMLElement} The newly created number input editor.
|
|
298
|
+
* @protected
|
|
299
|
+
* @override
|
|
300
|
+
*/
|
|
301
|
+
widgetCreate_() {
|
|
302
|
+
const htmlInput = super.widgetCreate_();
|
|
258
303
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
FieldNumber.prototype.doClassValidation_ = function(opt_newValue) {
|
|
268
|
-
if (opt_newValue === null) {
|
|
269
|
-
return null;
|
|
304
|
+
// Set the accessibility state
|
|
305
|
+
if (this.min_ > -Infinity) {
|
|
306
|
+
aria.setState(htmlInput, aria.State.VALUEMIN, this.min_);
|
|
307
|
+
}
|
|
308
|
+
if (this.max_ < Infinity) {
|
|
309
|
+
aria.setState(htmlInput, aria.State.VALUEMAX, this.max_);
|
|
310
|
+
}
|
|
311
|
+
return htmlInput;
|
|
270
312
|
}
|
|
271
|
-
// Clean up text.
|
|
272
|
-
let newValue = String(opt_newValue);
|
|
273
|
-
// TODO: Handle cases like 'ten', '1.203,14', etc.
|
|
274
|
-
// 'O' is sometimes mistaken for '0' by inexperienced users.
|
|
275
|
-
newValue = newValue.replace(/O/ig, '0');
|
|
276
|
-
// Strip out thousands separators.
|
|
277
|
-
newValue = newValue.replace(/,/g, '');
|
|
278
|
-
// Ignore case of 'Infinity'.
|
|
279
|
-
newValue = newValue.replace(/infinity/i, 'Infinity');
|
|
280
313
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
n = Number(n.toFixed(this.decimalPlaces_));
|
|
314
|
+
/**
|
|
315
|
+
* Construct a FieldNumber from a JSON arg object.
|
|
316
|
+
* @param {!Object} options A JSON object with options (value, min, max, and
|
|
317
|
+
* precision).
|
|
318
|
+
* @return {!FieldNumber} The new field instance.
|
|
319
|
+
* @package
|
|
320
|
+
* @nocollapse
|
|
321
|
+
* @override
|
|
322
|
+
*/
|
|
323
|
+
static fromJson(options) {
|
|
324
|
+
// `this` might be a subclass of FieldNumber if that class doesn't override
|
|
325
|
+
// the static fromJson method.
|
|
326
|
+
return new this(
|
|
327
|
+
options['value'], undefined, undefined, undefined, undefined, options);
|
|
296
328
|
}
|
|
297
|
-
|
|
298
|
-
};
|
|
329
|
+
}
|
|
299
330
|
|
|
300
331
|
/**
|
|
301
|
-
*
|
|
302
|
-
* @
|
|
332
|
+
* The default value for this field.
|
|
333
|
+
* @type {*}
|
|
303
334
|
* @protected
|
|
304
|
-
* @override
|
|
305
335
|
*/
|
|
306
|
-
FieldNumber.prototype.
|
|
307
|
-
const htmlInput = FieldNumber.superClass_.widgetCreate_.call(this);
|
|
308
|
-
|
|
309
|
-
// Set the accessibility state
|
|
310
|
-
if (this.min_ > -Infinity) {
|
|
311
|
-
aria.setState(htmlInput, aria.State.VALUEMIN, this.min_);
|
|
312
|
-
}
|
|
313
|
-
if (this.max_ < Infinity) {
|
|
314
|
-
aria.setState(htmlInput, aria.State.VALUEMAX, this.max_);
|
|
315
|
-
}
|
|
316
|
-
return htmlInput;
|
|
317
|
-
};
|
|
336
|
+
FieldNumber.prototype.DEFAULT_VALUE = 0;
|
|
318
337
|
|
|
319
338
|
fieldRegistry.register('field_number', FieldNumber);
|
|
320
339
|
|