diff --git a/core/field.js b/core/field.js
index 7f637445d..6739e435e 100644
--- a/core/field.js
+++ b/core/field.js
@@ -51,15 +51,38 @@ goog.require('Blockly.utils.style');
* @constructor
*/
Blockly.Field = function(value, opt_validator, opt_config) {
+ /**
+ * A generic value possessed by the field.
+ * Should generally be non-null, only null when the field is created.
+ * @type {*}
+ * @protected
+ */
+ this.value_ = null;
+
+ /**
+ * Validation function called when user edits an editable field.
+ * @type {Function}
+ * @protected
+ */
+ this.validator_ = null;
+
+ /**
+ * Used to cache the field's tooltip value if setTooltip is called when the
+ * field is not yet initialized. Is *not* guaranteed to be accurate.
+ * @type {string|Function|!Element}
+ * @private
+ */
+ this.tooltip_ = null;
+
/**
* The size of the area rendered by the field.
- * @type {Blockly.utils.Size}
+ * @type {!Blockly.utils.Size}
* @protected
*/
this.size_ = new Blockly.utils.Size(0, 0);
+ opt_config && this.configure_(opt_config);
this.setValue(value);
- this.setValidator(opt_validator);
- this.configure_(opt_config);
+ opt_validator && this.setValidator(opt_validator);
};
/**
@@ -117,22 +140,6 @@ Blockly.Field.prototype.disposed = false;
*/
Blockly.Field.prototype.maxDisplayLength = 50;
-/**
- * A generic value possessed by the field.
- * Should generally be non-null, only null when the field is created.
- * @type {*}
- * @protected
- */
-Blockly.Field.prototype.value_ = null;
-
-/**
- * Used to cache the field's tooltip value if setTooltip is called when the
- * field is not yet initialized. Is *not* guaranteed to be accurate.
- * @type {?string}
- * @private
- */
-Blockly.Field.prototype.tooltip_ = null;
-
/**
* Block this field is attached to. Starts as null, then set in init.
* @type {Blockly.Block}
@@ -143,7 +150,7 @@ Blockly.Field.prototype.sourceBlock_ = null;
/**
* Does this block need to be re-rendered?
* @type {boolean}
- * @private
+ * @protected
*/
Blockly.Field.prototype.isDirty_ = true;
@@ -154,16 +161,9 @@ Blockly.Field.prototype.isDirty_ = true;
*/
Blockly.Field.prototype.visible_ = true;
-/**
- * Validation function called when user edits an editable field.
- * @type {Function}
- * @protected
- */
-Blockly.Field.prototype.validator_ = null;
-
/**
* The element the click handler is bound to.
- * @type {!Element}
+ * @type {Element}
* @private
*/
Blockly.Field.prototype.clickTarget_ = null;
@@ -203,20 +203,17 @@ Blockly.Field.prototype.EDITABLE = true;
Blockly.Field.prototype.SERIALIZABLE = false;
/**
- * Configure the field based on the given map of options.
- * @param {Object} opt_config The map of options to configure the field
- * based on.
- * @private
+ * Process the configuration map passed to the field.
+ * @param {!Object} config A map of options used to configure the field. See
+ * the individual field's documentation for a list of properties this
+ * parameter supports.
+ * @protected
*/
-Blockly.Field.prototype.configure_ = function(opt_config) {
- if (!opt_config) {
- return;
- }
-
- var tooltip = opt_config['tooltip'];
+Blockly.Field.prototype.configure_ = function(config) {
+ var tooltip = config['tooltip'];
if (typeof tooltip == 'string') {
tooltip = Blockly.utils.replaceMessageReferences(
- opt_config['tooltip']);
+ config['tooltip']);
}
tooltip && this.setTooltip(tooltip);
@@ -274,6 +271,14 @@ Blockly.Field.prototype.initView = function() {
this.createTextElement_();
};
+/**
+ * Initializes the model of the field after it has been installed on a block.
+ * No-op by default.
+ * @package
+ */
+Blockly.Field.prototype.initModel = function() {
+};
+
/**
* Create a field border rect element. Not to be overridden by subclasses.
* Instead modify the result of the function inside initView, or create a
@@ -327,14 +332,6 @@ Blockly.Field.prototype.bindEvents_ = function() {
this.getClickTarget_(), 'mousedown', this, this.onMouseDown_);
};
-/**
- * Initializes the model of the field after it has been installed on a block.
- * No-op by default.
- * @package
- */
-Blockly.Field.prototype.initModel = function() {
-};
-
/**
* Sets the field's value based on the given XML element. Should only be
* called by Blockly.Xml.
@@ -772,14 +769,18 @@ Blockly.Field.prototype.getValue = function() {
/**
* Used to validate a value. Returns input by default. Can be overridden by
* subclasses, see FieldDropdown.
- * @param {*} newValue The value to be validated.
+ * @param {*=} opt_newValue The value to be validated.
* @return {*} The validated value, same as input by default.
* @protected
+ * @suppress {deprecated}
*/
-Blockly.Field.prototype.doClassValidation_ = function(newValue) {
+Blockly.Field.prototype.doClassValidation_ = function(opt_newValue) {
+ if (opt_newValue === null || opt_newValue === undefined) {
+ return null;
+ }
// For backwards compatibility.
- newValue = this.classValidator(newValue);
- return newValue;
+ opt_newValue = this.classValidator(/** @type {string} */ (opt_newValue));
+ return opt_newValue;
};
/**
diff --git a/core/field_angle.js b/core/field_angle.js
index cd65d3d5a..af5e3dc4d 100644
--- a/core/field_angle.js
+++ b/core/field_angle.js
@@ -46,12 +46,8 @@ goog.require('Blockly.utils.userAgent');
* @constructor
*/
Blockly.FieldAngle = function(opt_value, opt_validator) {
- opt_value = this.doClassValidation_(opt_value);
- if (opt_value === null) {
- opt_value = 0;
- }
Blockly.FieldAngle.superClass_.constructor.call(
- this, opt_value, opt_validator);
+ this, opt_value || 0, opt_validator);
};
Blockly.utils.object.inherits(Blockly.FieldAngle, Blockly.FieldTextInput);
@@ -373,7 +369,7 @@ Blockly.FieldAngle.prototype.onHtmlInputKeyDown_ = function(e) {
/**
* Ensure that the input value is a valid angle.
- * @param {string|number=} opt_newValue The input value.
+ * @param {*=} opt_newValue The input value.
* @return {?number} A valid angle, or null if invalid.
* @protected
* @override
diff --git a/core/field_checkbox.js b/core/field_checkbox.js
index b71d6b0c1..5d3c0ecdd 100644
--- a/core/field_checkbox.js
+++ b/core/field_checkbox.js
@@ -50,15 +50,6 @@ goog.require('Blockly.utils.Size');
* @constructor
*/
Blockly.FieldCheckbox = function(opt_value, opt_validator, opt_config) {
- opt_value = this.doClassValidation_(opt_value);
- if (opt_value === null) {
- opt_value = 'FALSE';
- }
- Blockly.FieldCheckbox.superClass_.constructor.call(
- this, opt_value, opt_validator, opt_config);
-
- this.size_.width = Blockly.FieldCheckbox.WIDTH;
-
/**
* Character for the check mark. Used to apply a different check mark
* character to individual fields.
@@ -67,7 +58,14 @@ Blockly.FieldCheckbox = function(opt_value, opt_validator, opt_config) {
*/
this.checkChar_ = null;
- this.configure_(opt_config);
+ if (opt_value == null) {
+ opt_value = 'FALSE';
+ }
+ Blockly.FieldCheckbox.superClass_.constructor.call(
+ this, opt_value, opt_validator, opt_config);
+
+ this.size_.width = Blockly.FieldCheckbox.WIDTH;
+
};
Blockly.utils.object.inherits(Blockly.FieldCheckbox, Blockly.Field);
@@ -128,20 +126,19 @@ Blockly.FieldCheckbox.prototype.CURSOR = 'default';
* rendered. Checkbox fields are statically sized, and only need to be
* rendered at initialization.
* @type {boolean}
- * @private
+ * @protected
*/
Blockly.FieldCheckbox.prototype.isDirty_ = false;
/**
* Configure the field based on the given map of options.
- * @param {Object} opt_config A map of options to configure the field based on.
+ * @param {!Object} config A map of options to configure the field based on.
* @private
*/
-Blockly.FieldCheckbox.prototype.configure_ = function(opt_config) {
- if (opt_config) {
- if (opt_config['checkCharacter']) {
- this.checkChar_ = opt_config['checkCharacter'];
- }
+Blockly.FieldCheckbox.prototype.configure_ = function(config) {
+ Blockly.FieldCheckbox.superClass_.configure_.call(this, config);
+ if (config['checkCharacter']) {
+ this.checkChar_ = config['checkCharacter'];
}
};
@@ -183,7 +180,7 @@ Blockly.FieldCheckbox.prototype.showEditor_ = function() {
/**
* Ensure that the input value is valid ('TRUE' or 'FALSE').
- * @param {string|boolean=} opt_newValue The input value.
+ * @param {*=} opt_newValue The input value.
* @return {?string} A valid value ('TRUE' or 'FALSE), or null if invalid.
* @protected
*/
@@ -220,10 +217,10 @@ Blockly.FieldCheckbox.prototype.getValue = function() {
/**
* Get the boolean value of this field.
- * @return {string} The boolean value of this field.
+ * @return {boolean} The boolean value of this field.
*/
Blockly.FieldCheckbox.prototype.getValueBoolean = function() {
- return this.value_;
+ return /** @type {boolean} */ (this.value_);
};
/**
diff --git a/core/field_colour.js b/core/field_colour.js
index b8d2d0b91..3a05fbb70 100644
--- a/core/field_colour.js
+++ b/core/field_colour.js
@@ -53,14 +53,18 @@ goog.require('Blockly.utils.Size');
* @constructor
*/
Blockly.FieldColour = function(opt_value, opt_validator, opt_config) {
- opt_value = this.doClassValidation_(opt_value);
- if (opt_value === null) {
- opt_value = Blockly.FieldColour.COLOURS[0];
- }
Blockly.FieldColour.superClass_.constructor.call(
- this, opt_value, opt_validator, opt_config);
+ this, opt_value || Blockly.FieldColour.COLOURS[0],
+ opt_validator, opt_config);
- this.configure_(opt_config);
+ /**
+ * The size of the area rendered by the field.
+ * @type {Blockly.utils.Size}
+ * @protected
+ * @override
+ */
+ this.size_ = new Blockly.utils.Size(Blockly.FieldColour.DEFAULT_WIDTH,
+ Blockly.FieldColour.DEFAULT_HEIGHT);
};
Blockly.utils.object.inherits(Blockly.FieldColour, Blockly.Field);
@@ -109,7 +113,7 @@ Blockly.FieldColour.prototype.CURSOR = 'default';
* rendered. Colour fields are statically sized, and only need to be
* rendered at initialization.
* @type {boolean}
- * @private
+ * @protected
*/
Blockly.FieldColour.prototype.isDirty_ = false;
@@ -153,19 +157,17 @@ Blockly.FieldColour.prototype.DROPDOWN_BACKGROUND_COLOUR = 'white';
/**
* Configure the field based on the given map of options.
- * @param {Object} opt_config A map of options to configure the field based on.
+ * @param {!Object} config A map of options to configure the field based on.
* @private
*/
-Blockly.FieldColour.prototype.configure_ = function(opt_config) {
- if (!opt_config) {
- return;
+Blockly.FieldColour.prototype.configure_ = function(config) {
+ Blockly.FieldColour.superClass_.configure_.call(this, config);
+ if (config['colourOptions']) {
+ this.colours_ = config['colourOptions'];
+ this.titles_ = config['colourTitles'];
}
-
- if (opt_config['colourOptions']) {
- this.setColours(opt_config['colourOptions'], opt_config['colourTitles']);
- }
- if (opt_config['columns']) {
- this.setColumns(opt_config['columns']);
+ if (config['columns']) {
+ this.columns_ = config['columns'];
}
};
@@ -174,8 +176,6 @@ Blockly.FieldColour.prototype.configure_ = function(opt_config) {
* @package
*/
Blockly.FieldColour.prototype.initView = function() {
- this.size_ = new Blockly.utils.Size(Blockly.FieldColour.DEFAULT_WIDTH,
- Blockly.FieldColour.DEFAULT_HEIGHT);
this.createBorderRect_();
this.borderRect_.style['fillOpacity'] = 1;
this.borderRect_.style.fill = this.value_;
@@ -183,7 +183,7 @@ Blockly.FieldColour.prototype.initView = function() {
/**
* Ensure that the input value is a valid colour.
- * @param {string=} opt_newValue The input value.
+ * @param {*=} opt_newValue The input value.
* @return {?string} A valid colour, or null if invalid.
* @protected
*/
@@ -211,7 +211,7 @@ Blockly.FieldColour.prototype.doValueUpdate_ = function(newValue) {
* @return {string} Text representing the value of this field.
*/
Blockly.FieldColour.prototype.getText = function() {
- var colour = this.value_;
+ var colour = /** @type {string} */ (this.value_);
// Try to use #rgb format if possible, rather than #rrggbb.
if (/^#(.)\1(.)\2(.)\3$/.test(colour)) {
colour = '#' + colour[1] + colour[3] + colour[5];
diff --git a/core/field_date.js b/core/field_date.js
index aaf1fe72c..88b5f2548 100644
--- a/core/field_date.js
+++ b/core/field_date.js
@@ -52,12 +52,8 @@ goog.require('goog.ui.DatePicker');
* @constructor
*/
Blockly.FieldDate = function(opt_value, opt_validator) {
- opt_value = this.doClassValidation_(opt_value);
- if (!opt_value) {
- opt_value = new goog.date.Date().toIsoString(true);
- }
Blockly.FieldDate.superClass_.constructor.call(this,
- opt_value, opt_validator);
+ opt_value || new goog.date.Date().toIsoString(true), opt_validator);
};
Blockly.utils.object.inherits(Blockly.FieldDate, Blockly.Field);
@@ -103,7 +99,7 @@ Blockly.FieldDate.prototype.DROPDOWN_BACKGROUND_COLOUR = 'white';
/**
* Ensure that the input value is a valid date.
- * @param {string=} opt_newValue The input value.
+ * @param {*=} opt_newValue The input value.
* @return {?string} A valid date, or null if invalid.
* @protected
*/
diff --git a/core/field_dropdown.js b/core/field_dropdown.js
index 1271952e8..45ce9bf91 100644
--- a/core/field_dropdown.js
+++ b/core/field_dropdown.js
@@ -59,11 +59,14 @@ Blockly.FieldDropdown = function(menuGenerator, opt_validator) {
Blockly.FieldDropdown.validateOptions_(menuGenerator);
}
+ /**
+ * An array of options for a dropdown list,
+ * or a function which generates these options.
+ * @type {(!Array.|!Function)}
+ * @protected
+ */
this.menuGenerator_ = menuGenerator;
- this.trimOptions_();
- var firstTuple = this.getOptions()[0];
-
/**
* The currently selected index. A value of -1 indicates no option
* has been selected.
@@ -72,10 +75,20 @@ Blockly.FieldDropdown = function(menuGenerator, opt_validator) {
*/
this.selectedIndex_ = -1;
+ this.trimOptions_();
+ var firstTuple = this.getOptions()[0];
+
// Call parent's constructor.
Blockly.FieldDropdown.superClass_.constructor.call(this, firstTuple[1],
opt_validator);
+ /**
+ * SVG image element if currently selected option is an image, or null.
+ * @type {SVGElement}
+ * @private
+ */
+ this.imageElement_ = null;
+
/**
* A reference to the currently selected menu item.
* @type {Blockly.MenuItem}
@@ -154,13 +167,6 @@ Blockly.FieldDropdown.ARROW_CHAR =
*/
Blockly.FieldDropdown.prototype.CURSOR = 'default';
-/**
- * SVG image element if currently selected option is an image, or null.
- * @type {SVGElement}
- * @private
- */
-Blockly.FieldDropdown.prototype.imageElement_ = null;
-
/**
* Create the block UI for this dropdown.
* @package
@@ -430,7 +436,7 @@ Blockly.FieldDropdown.prototype.getOptions = function() {
/**
* Ensure that the input value is a valid language-neutral option.
- * @param {string=} opt_newValue The input value.
+ * @param {*=} opt_newValue The input value.
* @return {?string} A valid language-neutral option, or null if invalid.
* @protected
*/
@@ -452,7 +458,7 @@ Blockly.FieldDropdown.prototype.doClassValidation_ = function(opt_newValue) {
}
return null;
}
- return opt_newValue;
+ return /** @type {string} */ (opt_newValue);
};
/**
diff --git a/core/field_image.js b/core/field_image.js
index ea42ddb10..de0860748 100644
--- a/core/field_image.js
+++ b/core/field_image.js
@@ -48,7 +48,6 @@ goog.require('Blockly.utils.Size');
*/
Blockly.FieldImage = function(src, width, height,
opt_alt, opt_onClick, opt_flipRtl) {
- this.sourceBlock_ = null;
if (!src) {
throw Error('Src value of an image field is required');
@@ -66,10 +65,13 @@ Blockly.FieldImage = function(src, width, height,
throw Error('Height and width values of an image field must be greater' +
' than 0.');
}
- // Store the image height, since it is different from the field height.
+
+ /**
+ * Store the image height, since it is different from the field height.
+ * @type {number}
+ * @private
+ */
this.imageHeight_ = imageHeight;
- this.size_ = new Blockly.utils.Size(imageWidth,
- imageHeight + Blockly.FieldImage.Y_PADDING);
/**
* Whether to flip this image in RTL.
@@ -85,11 +87,21 @@ Blockly.FieldImage = function(src, width, height,
*/
this.altText_ = opt_alt || '';
- this.setValue(src || '');
-
if (typeof opt_onClick == 'function') {
this.clickHandler_ = opt_onClick;
}
+
+ Blockly.FieldImage.superClass_.constructor.call(
+ this, src || '', null);
+
+ /**
+ * The size of the area rendered by the field.
+ * @type {Blockly.utils.Size}
+ * @protected
+ * @override
+ */
+ this.size_ = new Blockly.utils.Size(imageWidth,
+ imageHeight + Blockly.FieldImage.Y_PADDING);
};
Blockly.utils.object.inherits(Blockly.FieldImage, Blockly.Field);
@@ -133,7 +145,7 @@ Blockly.FieldImage.prototype.EDITABLE = false;
* rendered. Image fields are statically sized, and only need to be
* rendered at initialization.
* @type {boolean}
- * @private
+ * @protected
*/
Blockly.FieldImage.prototype.isDirty_ = false;
@@ -151,12 +163,12 @@ Blockly.FieldImage.prototype.initView = function() {
},
this.fieldGroup_);
this.imageElement_.setAttributeNS(Blockly.utils.dom.XLINK_NS,
- 'xlink:href', this.value_);
+ 'xlink:href', /** @type {string} */ (this.value_));
};
/**
* Ensure that the input value (the source URL) is a string.
- * @param {string=} opt_newValue The input value.
+ * @param {*=} opt_newValue The input value.
* @return {?string} A string, or null if invalid.
* @protected
*/
diff --git a/core/field_label.js b/core/field_label.js
index 1e416c4d0..3b8bde5f6 100644
--- a/core/field_label.js
+++ b/core/field_label.js
@@ -44,13 +44,26 @@ goog.require('Blockly.utils.Size');
* @constructor
*/
Blockly.FieldLabel = function(opt_value, opt_class) {
- this.size_ = new Blockly.utils.Size(0, Blockly.Field.TEXT_DEFAULT_HEIGHT);
- this.class_ = opt_class;
- opt_value = this.doClassValidation_(opt_value);
- if (opt_value === null) {
+ /**
+ * The html class name to use for this field.
+ * @type {?string}
+ * @private
+ */
+ this.class_ = opt_class || null;
+
+ if (opt_value == null) {
opt_value = '';
}
- this.setValue(opt_value);
+ Blockly.FieldLabel.superClass_.constructor.call(
+ this, opt_value, null);
+
+ /**
+ * The size of the area rendered by the field.
+ * @type {Blockly.utils.Size}
+ * @protected
+ * @override
+ */
+ this.size_ = new Blockly.utils.Size(0, Blockly.Field.TEXT_DEFAULT_HEIGHT);
};
Blockly.utils.object.inherits(Blockly.FieldLabel, Blockly.Field);
@@ -90,7 +103,7 @@ Blockly.FieldLabel.prototype.initView = function() {
/**
* Ensure that the input value casts to a valid string.
- * @param {string=} opt_newValue The input value.
+ * @param {*=} opt_newValue The input value.
* @return {?string} A valid string, or null if invalid.
* @protected
*/
diff --git a/core/field_number.js b/core/field_number.js
index 65024937a..def30ed74 100644
--- a/core/field_number.js
+++ b/core/field_number.js
@@ -46,13 +46,32 @@ goog.require('Blockly.utils.object');
*/
Blockly.FieldNumber = function(opt_value, opt_min, opt_max, opt_precision,
opt_validator) {
- this.setConstraints(opt_min, opt_max, opt_precision);
- opt_value = this.doClassValidation_(opt_value);
- if (opt_value === null) {
- opt_value = 0;
- }
+
+ /**
+ * The minimum value constraint.
+ * @type {number}
+ * @protected
+ */
+ this.min_ = -Infinity;
+
+ /**
+ * The maximum value constraint.
+ * @type {number}
+ * @protected
+ */
+ this.max_ = Infinity;
+
+ /**
+ * The precision constraint for the value.
+ * @type {number}
+ * @protected
+ */
+ this.precision_ = 0;
+
Blockly.FieldNumber.superClass_.constructor.call(
- this, opt_value, opt_validator);
+ this, opt_value || 0, opt_validator);
+
+ this.setConstraints(opt_min, opt_max, opt_precision);
};
Blockly.utils.object.inherits(Blockly.FieldNumber, Blockly.FieldTextInput);
@@ -90,28 +109,34 @@ Blockly.FieldNumber.prototype.SERIALIZABLE = true;
*/
Blockly.FieldNumber.prototype.setConstraints = function(min, max, precision) {
precision = Number(precision);
- this.precision_ = isNaN(precision) ? 0 : precision;
+ if (!isNaN(precision)) {
+ this.precision_ = precision;
+ }
var precisionString = this.precision_.toString();
var decimalIndex = precisionString.indexOf('.');
this.fractionalDigits_ = (decimalIndex == -1) ? -1 :
precisionString.length - (decimalIndex + 1);
min = Number(min);
- this.min_ = isNaN(min) ? -Infinity : min;
+ if (!isNaN(min)) {
+ this.min_ = min;
+ }
max = Number(max);
- this.max_ = isNaN(max) ? Infinity : max;
+ if (!isNaN(max)) {
+ this.max_ = max;
+ }
this.setValue(this.getValue());
};
/**
* Ensure that the input value is a valid number (must fulfill the
* constraints placed on the field).
- * @param {string|number=} opt_newValue The input value.
+ * @param {*=} opt_newValue The input value.
* @return {?number} A valid number, or null if invalid.
* @protected
* @override
*/
Blockly.FieldNumber.prototype.doClassValidation_ = function(opt_newValue) {
- if (opt_newValue === null || opt_newValue === undefined) {
+ if (opt_newValue === null) {
return null;
}
// Clean up text.
@@ -142,7 +167,7 @@ Blockly.FieldNumber.prototype.doClassValidation_ = function(opt_newValue) {
/**
* Create the number input editor widget.
- * @return {!HTMLInputElement} The newly created number input editor.
+ * @return {!HTMLElement} The newly created number input editor.
* @protected
* @override
*/
diff --git a/core/field_textinput.js b/core/field_textinput.js
index 37f9d3667..3a556d262 100644
--- a/core/field_textinput.js
+++ b/core/field_textinput.js
@@ -51,12 +51,11 @@ goog.require('Blockly.utils.userAgent');
* @constructor
*/
Blockly.FieldTextInput = function(opt_value, opt_validator) {
- opt_value = this.doClassValidation_(opt_value);
- if (opt_value === null) {
+ if (opt_value == null) {
opt_value = '';
}
- Blockly.FieldTextInput.superClass_.constructor.call(this, opt_value,
- opt_validator);
+ Blockly.FieldTextInput.superClass_.constructor.call(this,
+ opt_value, opt_validator);
};
Blockly.utils.object.inherits(Blockly.FieldTextInput, Blockly.Field);
@@ -92,7 +91,8 @@ Blockly.FieldTextInput.prototype.SERIALIZABLE = true;
Blockly.FieldTextInput.FONTSIZE = 11;
/**
- * Pixel size of input border radius. Should match blocklyText's border-radius in CSS.
+ * Pixel size of input border radius.
+ * Should match blocklyText's border-radius in CSS.
*/
Blockly.FieldTextInput.BORDERRADIUS = 4;
@@ -109,8 +109,8 @@ Blockly.FieldTextInput.prototype.spellcheck_ = true;
/**
* Ensure that the input value casts to a valid string.
- * @param {string=} opt_newValue The input value.
- * @return {?string} A valid string, or null if invalid.
+ * @param {*=} opt_newValue The input value.
+ * @return {*} A valid string, or null if invalid.
* @protected
*/
Blockly.FieldTextInput.prototype.doClassValidation_ = function(opt_newValue) {
diff --git a/core/field_variable.js b/core/field_variable.js
index d03edc651..766a5c36d 100644
--- a/core/field_variable.js
+++ b/core/field_variable.js
@@ -59,12 +59,19 @@ Blockly.FieldVariable = function(varname, opt_validator, opt_variableTypes,
// The FieldDropdown constructor would call setValue, which might create a
// spurious variable. Just do the relevant parts of the constructor.
this.menuGenerator_ = Blockly.FieldVariable.dropdownCreate;
- this.size_ = new Blockly.utils.Size(0, Blockly.BlockSvg.MIN_BLOCK_Y);
opt_validator && this.setValidator(opt_validator);
this.defaultVariableName = varname || '';
this.setTypes_(opt_variableTypes, opt_defaultType);
this.value_ = null;
+
+ /**
+ * The size of the area rendered by the field.
+ * @type {Blockly.utils.Size}
+ * @protected
+ * @override
+ */
+ this.size_ = new Blockly.utils.Size(0, Blockly.BlockSvg.MIN_BLOCK_Y);
};
Blockly.utils.object.inherits(Blockly.FieldVariable, Blockly.FieldDropdown);
@@ -224,11 +231,15 @@ Blockly.FieldVariable.prototype.getValidator = function() {
/**
* Ensure that the id belongs to a valid variable of an allowed type.
- * @param {string} newId The id of the new variable to set.
+ * @param {*=} opt_newValue The id of the new variable to set.
* @return {?string} The validated id, or null if invalid.
* @protected
*/
-Blockly.FieldVariable.prototype.doClassValidation_ = function(newId) {
+Blockly.FieldVariable.prototype.doClassValidation_ = function(opt_newValue) {
+ if (opt_newValue === null) {
+ return null;
+ }
+ var newId = /** @type {string} */ (opt_newValue);
var variable = Blockly.Variables.getVariable(this.workspace_, newId);
if (!variable) {
console.warn('Variable id doesn\'t point to a real variable! ' +
diff --git a/demos/custom-fields/turtle/field_turtle.js b/demos/custom-fields/turtle/field_turtle.js
index 7e77542e1..41c93c21e 100644
--- a/demos/custom-fields/turtle/field_turtle.js
+++ b/demos/custom-fields/turtle/field_turtle.js
@@ -48,24 +48,21 @@ CustomFields.FieldTurtle = function(
// The turtle field contains an object as its value, so we need to compile
// the parameters into an object.
var value = {};
- value.pattern = opt_pattern;
- value.hat = opt_hat;
- value.turtleName = opt_turtleName;
-
- var valid = this.doClassValidation_(value);
- if (valid === null) {
- // See the doClassValidation_ function for information on the
- // cachedValidatedValue_ property.
- value = this.cachedValidatedValue_;
- value.pattern = value.pattern || CustomFields.FieldTurtle.PATTERNS[0];
- value.hat = value.hat || CustomFields.FieldTurtle.HATS[0];
- value.turtleName = value.turtleName || CustomFields.FieldTurtle.NAMES[0];
- } // Else the original value is fine.
+ value.pattern = opt_pattern || CustomFields.FieldTurtle.PATTERNS[0];
+ value.hat = opt_hat || CustomFields.FieldTurtle.HATS[0];
+ value.turtleName = opt_turtleName || CustomFields.FieldTurtle.NAMES[0];
// A field constructor should always call its parent constructor, because
// that helps keep the code organized and DRY.
CustomFields.FieldTurtle.superClass_.constructor.call(
this, value, opt_validator);
+
+ /**
+ * The size of the area rendered by the field.
+ * @type {Blockly.utils.Size}
+ * @protected
+ * @override
+ */
this.size_ = new Blockly.utils.Size(0, 0);
};
Blockly.utils.object.inherits(CustomFields.FieldTurtle, Blockly.Field);
diff --git a/tests/blocks/test_blocks.js b/tests/blocks/test_blocks.js
index d5d9097ce..f8aa6c050 100644
--- a/tests/blocks/test_blocks.js
+++ b/tests/blocks/test_blocks.js
@@ -988,55 +988,6 @@ Blockly.Blocks['test_validators_colour_red_null'] = {
}
};
-Blockly.Blocks['test_validators_date_null'] = {
- init: function() {
- this.appendDummyInput()
- .appendField("always null")
- .appendField(new Blockly.FieldDate("2020-02-20", this.validate), "INPUT");
- this.setColour(230);
- this.setCommentText('All input validates to null (invalid). This means' +
- ' the field value should not change.');
- },
-
- validate: function(newValue) {
- // We should be able to expect validators to like their initial values.
- if (newValue != '2020-02-20') {
- return null;
- }
- }
-};
-Blockly.Blocks['test_validators_date_force_20s'] = {
- init: function() {
- this.appendDummyInput()
- .appendField("force day 20s")
- .appendField(new Blockly.FieldDate("2020-02-20", this.validate), "INPUT");
- this.setColour(230);
- this.setCommentText('The input\'s date will change to always be in the' +
- ' 20s.');
- },
-
- validate: function(newValue) {
- return newValue.substr(0, 8) + '2' + newValue.substr(9, 1);
- }
-};
-Blockly.Blocks['test_validators_date_20s_null'] = {
- init: function() {
- this.appendDummyInput()
- .appendField("not 20s -> null")
- .appendField(new Blockly.FieldDate("2020-02-20", this.validate), "INPUT");
- this.setColour(230);
- this.setCommentText('If the input is not in the 20s, the input will' +
- ' validate to null (invalid). Otherwise it will return the input value.');
- },
-
- validate: function(newValue) {
- if (newValue.charAt(8) != '2') {
- return null;
- }
- return newValue;
- }
-};
-
Blockly.Blocks['test_validators_dropdown_null'] = {
init: function() {
this.appendDummyInput()
diff --git a/tests/mocha/field_angle_test.js b/tests/mocha/field_angle_test.js
index d86a6b365..86236145c 100644
--- a/tests/mocha/field_angle_test.js
+++ b/tests/mocha/field_angle_test.js
@@ -39,10 +39,6 @@ suite('Angle Fields', function() {
var angleField = new Blockly.FieldAngle(undefined);
assertValueDefault(angleField);
});
- test('Non-Parsable String', function() {
- var angleField = new Blockly.FieldAngle('bad');
- assertValueDefault(angleField);
- });
test('NaN', function() {
var angleField = new Blockly.FieldAngle(NaN);
assertValueDefault(angleField);
@@ -67,14 +63,6 @@ suite('Angle Fields', function() {
var angleField = new Blockly.FieldAngle(362);
assertValue(angleField, 2);
});
- test('Infinity', function() {
- var angleField = new Blockly.FieldAngle(Infinity);
- assertValueDefault(angleField);
- });
- test('Negative Infinity String', function() {
- var angleField = new Blockly.FieldAngle('-Infinity');
- assertValueDefault(angleField);
- });
});
suite('fromJson', function() {
test('Empty', function() {
@@ -85,10 +73,6 @@ suite('Angle Fields', function() {
var angleField = Blockly.FieldAngle.fromJson({ angle:undefined });
assertValueDefault(angleField);
});
- test('Non-Parsable String', function() {
- var angleField = Blockly.FieldAngle.fromJson({ angle:'bad' });
- assertValueDefault(angleField);
- });
test('NaN', function() {
var angleField = Blockly.FieldAngle.fromJson({ angle:NaN });
assertValueDefault(angleField);
@@ -113,14 +97,6 @@ suite('Angle Fields', function() {
var angleField = Blockly.FieldAngle.fromJson({ angle:362 });
assertValue(angleField, 2);
});
- test('Infinity', function() {
- var angleField = Blockly.FieldAngle.fromJson({ angle:Infinity });
- assertValueDefault(angleField);
- });
- test('Negative Infinity String', function() {
- var angleField = Blockly.FieldAngle.fromJson({ angle:'-Infinity' });
- assertValueDefault(angleField);
- });
});
suite('setValue', function() {
suite('Empty -> New Value', function() {
diff --git a/tests/mocha/field_checkbox_test.js b/tests/mocha/field_checkbox_test.js
index 42fb6d466..a39e7bcdd 100644
--- a/tests/mocha/field_checkbox_test.js
+++ b/tests/mocha/field_checkbox_test.js
@@ -37,10 +37,6 @@ suite('Checkbox Fields', function() {
var checkboxField = new Blockly.FieldCheckbox(undefined);
assertValueDefault(checkboxField);
});
- test('Non-Parsable String', function() {
- var checkboxField = new Blockly.FieldCheckbox('bad');
- assertValueDefault(checkboxField);
- });
test('True', function() {
var checkboxField = new Blockly.FieldCheckbox(true);
assertValue(checkboxField, 'TRUE', 'true');
@@ -67,10 +63,6 @@ suite('Checkbox Fields', function() {
var checkboxField = Blockly.FieldCheckbox.fromJson({ checked: undefined});
assertValueDefault(checkboxField);
});
- test('Non-Parsable String', function() {
- var checkboxField = Blockly.FieldCheckbox.fromJson({ checked: 'bad'});
- assertValueDefault(checkboxField);
- });
test('True', function() {
var checkboxField = Blockly.FieldCheckbox.fromJson({ checked: true});
assertValue(checkboxField, 'TRUE', 'true');
diff --git a/tests/mocha/field_colour_test.js b/tests/mocha/field_colour_test.js
index 8d48da0d3..a567746a4 100644
--- a/tests/mocha/field_colour_test.js
+++ b/tests/mocha/field_colour_test.js
@@ -53,10 +53,6 @@ suite('Colour Fields', function() {
var colourField = new Blockly.FieldColour(undefined);
assertValueDefault(colourField);
});
- test('Non-Parsable String', function() {
- var colourField = new Blockly.FieldColour('not_a_colour');
- assertValueDefault(colourField);
- });
test('#AAAAAA', function() {
var colourField = new Blockly.FieldColour('#AAAAAA');
assertValue(colourField, '#aaaaaa', '#aaa');
@@ -107,11 +103,6 @@ suite('Colour Fields', function() {
var colourField = new Blockly.FieldColour.fromJson({ colour:undefined });
assertValueDefault(colourField);
});
- test('Non-Parsable String', function() {
- var colourField = new Blockly.FieldColour.fromJson(
- { colour:'not_a_colour' });
- assertValueDefault(colourField);
- });
test('#AAAAAA', function() {
var colourField = Blockly.FieldColour.fromJson({ colour: '#AAAAAA' });
assertValue(colourField, '#aaaaaa', '#aaa');
diff --git a/tests/mocha/field_number_test.js b/tests/mocha/field_number_test.js
index 95ff1b3dd..1bce8ffcb 100644
--- a/tests/mocha/field_number_test.js
+++ b/tests/mocha/field_number_test.js
@@ -59,10 +59,6 @@ suite('Number Fields', function() {
var numberField = createNumberFieldSameValuesConstructor(undefined);
assertNumberFieldDefault(numberField);
});
- test('Non-Parsable String', function() {
- var numberField = createNumberFieldSameValuesConstructor('bad');
- assertNumberFieldDefault(numberField);
- });
test('NaN', function() {
var numberField = createNumberFieldSameValuesConstructor(NaN);
assertNumberFieldDefault(numberField);
@@ -101,10 +97,6 @@ suite('Number Fields', function() {
var numberField = createNumberFieldSameValuesJson(undefined);
assertNumberFieldDefault(numberField);
});
- test('Non-Parsable String', function() {
- var numberField = createNumberFieldSameValuesJson('bad');
- assertNumberFieldDefault(numberField);
- });
test('NaN', function() {
var numberField = createNumberFieldSameValuesJson(NaN);
assertNumberFieldDefault(numberField);
diff --git a/tests/mocha/procedures_test.js b/tests/mocha/procedures_test.js
index 1b5850f31..800521b04 100644
--- a/tests/mocha/procedures_test.js
+++ b/tests/mocha/procedures_test.js
@@ -19,7 +19,7 @@
*/
goog.require('Blockly.Blocks.procedures');
-goog.require('Blockly.Msg.en');
+goog.require('Blockly.Msg');
suite('Procedures', function() {
setup(function() {
diff --git a/tests/playground.html b/tests/playground.html
index 237c5d31b..ad8c60252 100644
--- a/tests/playground.html
+++ b/tests/playground.html
@@ -1443,13 +1443,6 @@ h1 {
-
-
-
-
-
-
-