diff --git a/core/field_label.js b/core/field_label.js index 3b8bde5f6..ae1508c02 100644 --- a/core/field_label.js +++ b/core/field_label.js @@ -40,22 +40,29 @@ goog.require('Blockly.utils.Size'); * @param {string=} opt_value The initial value of the field. Should cast to a * string. Defaults to an empty string if null or undefined. * @param {string=} opt_class Optional CSS class for the field's text. + * @param {Object=} opt_config A map of options used to configure the field. + * See the [field creation documentation]{@link https://developers.google.com/blockly/guides/create-custom-blocks/fields/built-in-fields/label#creation} + * for a list of properties this parameter supports. * @extends {Blockly.Field} * @constructor */ -Blockly.FieldLabel = function(opt_value, opt_class) { +Blockly.FieldLabel = function(opt_value, opt_class, opt_config) { /** * The html class name to use for this field. * @type {?string} * @private */ - this.class_ = opt_class || null; + this.class_ = null; if (opt_value == null) { opt_value = ''; } Blockly.FieldLabel.superClass_.constructor.call( - this, opt_value, null); + this, opt_value, null, opt_config); + + if (!opt_config) { // If the config was not passed use old configuration. + this.class_ = opt_class; + } /** * The size of the area rendered by the field. @@ -77,7 +84,7 @@ Blockly.utils.object.inherits(Blockly.FieldLabel, Blockly.Field); */ Blockly.FieldLabel.fromJson = function(options) { var text = Blockly.utils.replaceMessageReferences(options['text']); - return new Blockly.FieldLabel(text, options['class']); + return new Blockly.FieldLabel(text, null, options); }; /** @@ -88,6 +95,14 @@ Blockly.FieldLabel.fromJson = function(options) { */ Blockly.FieldLabel.prototype.EDITABLE = false; +/** + * @override + */ +Blockly.FieldLabel.prototype.configure_ = function(config) { + Blockly.FieldLabel.superClass_.configure_.call(this, config); + this.class_ = config['class']; +}; + /** * Create block UI for this label. * @package @@ -114,4 +129,22 @@ Blockly.FieldLabel.prototype.doClassValidation_ = function(opt_newValue) { return String(opt_newValue); }; +/** + * Set the css class applied to the field's textElement_. + * @param {?string} cssClass The new css class name, or null to remove. + */ +Blockly.FieldLabel.prototype.setClass = function(cssClass) { + if (this.textElement_) { + // This check isn't necessary, but it's faster than letting removeClass + // figure it out. + if (this.class_) { + Blockly.utils.dom.removeClass(this.textElement_, this.class_); + } + if (cssClass) { + Blockly.utils.dom.addClass(this.textElement_, cssClass); + } + } + this.class_ = cssClass; +}; + Blockly.fieldRegistry.register('field_label', Blockly.FieldLabel); diff --git a/core/field_label_serializable.js b/core/field_label_serializable.js index 68712402b..2c020519b 100644 --- a/core/field_label_serializable.js +++ b/core/field_label_serializable.js @@ -38,13 +38,16 @@ goog.require('Blockly.utils.object'); * @param {*} opt_value The initial value of the field. Should cast to a * string. Defaults to an empty string if null or undefined. * @param {string=} opt_class Optional CSS class for the field's text. + * @param {Object=} opt_config A map of options used to configure the field. + * See the [field creation documentation]{@link https://developers.google.com/blockly/guides/create-custom-blocks/fields/built-in-fields/label-serializable#creation} + * for a list of properties this parameter supports. * @extends {Blockly.FieldLabel} * @constructor * */ -Blockly.FieldLabelSerializable = function(opt_value, opt_class) { - Blockly.FieldLabelSerializable.superClass_.constructor.call(this, opt_value, - opt_class); +Blockly.FieldLabelSerializable = function(opt_value, opt_class, opt_config) { + Blockly.FieldLabelSerializable.superClass_.constructor.call( + this, opt_value, opt_class, opt_config); }; Blockly.utils.object.inherits(Blockly.FieldLabelSerializable, Blockly.FieldLabel); @@ -59,7 +62,7 @@ Blockly.utils.object.inherits(Blockly.FieldLabelSerializable, */ Blockly.FieldLabelSerializable.fromJson = function(options) { var text = Blockly.utils.replaceMessageReferences(options['text']); - return new Blockly.FieldLabelSerializable(text, options['class']); + return new Blockly.FieldLabelSerializable(text, null, options); }; /** diff --git a/tests/mocha/field_label_serializable_test.js b/tests/mocha/field_label_serializable_test.js index 09659af1a..07b8544be 100644 --- a/tests/mocha/field_label_serializable_test.js +++ b/tests/mocha/field_label_serializable_test.js @@ -28,6 +28,18 @@ suite('Label Serializable Fields', function() { function assertValueDefault(labelField) { assertValue(labelField, ''); } + function assertHasClass(labelField, cssClass) { + labelField.fieldGroup_ = Blockly.utils.dom.createSvgElement('g', {}, null); + labelField.initView(); + chai.assert.isTrue(Blockly.utils.dom.hasClass( + labelField.textElement_, cssClass)); + } + function assertDoesNotHaveClass(labelField, cssClass) { + labelField.fieldGroup_ = Blockly.utils.dom.createSvgElement('g', {}, null); + labelField.initView(); + chai.assert.isFalse(Blockly.utils.dom.hasClass( + labelField.textElement_, cssClass)); + } suite('Constructor', function() { test('Empty', function() { var labelField = new Blockly.FieldLabelSerializable(); @@ -167,4 +179,66 @@ suite('Label Serializable Fields', function() { }); }); }); + suite('Customizations', function() { + test('JS Constructor', function() { + var field = new Blockly.FieldLabelSerializable('text', 'testClass'); + assertHasClass(field, 'testClass'); + }); + test('JSON Definition', function() { + var field = Blockly.FieldLabelSerializable.fromJson({ + class: 'testClass' + }); + assertHasClass(field, 'testClass'); + }); + test('JS Configuration - Simple', function() { + var field = new Blockly.FieldLabelSerializable('text', null, { + class: 'testClass' + }); + assertHasClass(field, 'testClass'); + }); + test('JS Configuration - Ignore', function() { + var field = new Blockly.FieldLabelSerializable('text', 'paramClass', { + class: 'configClass' + }); + assertDoesNotHaveClass(field, 'paramClass'); + assertHasClass(field, 'configClass'); + }); + test('JS Configuration - Ignore - \'\'', function() { + var field = new Blockly.FieldLabelSerializable('text', '', { + class: 'configClass' + }); + assertHasClass(field, 'configClass'); + }); + test('JS Configuration - Ignore - Config \'\'', function() { + var field = new Blockly.FieldLabelSerializable('text', 'paramClass', { + class: '' + }); + assertDoesNotHaveClass(field, 'paramClass'); + }); + suite('setClass', function() { + test('setClass', function() { + var field = new Blockly.FieldLabelSerializable(); + field.fieldGroup_ = Blockly.utils.dom.createSvgElement('g', {}, null); + field.initView(); + field.setClass('testClass'); + // Don't call assertHasClass b/c we don't want to re-initialize. + chai.assert.isTrue(Blockly.utils.dom.hasClass( + field.textElement_, 'testClass')); + }); + test('setClass Before Initialization', function() { + var field = new Blockly.FieldLabelSerializable(); + field.setClass('testClass'); + assertHasClass(field, 'testClass'); + }); + test('Remove Class', function() { + var field = new Blockly.FieldLabelSerializable('text', null, { + class: 'testClass' + }); + assertHasClass(field, 'testClass'); + field.setClass(null); + chai.assert.isFalse(Blockly.utils.dom.hasClass( + field.textElement_, 'testClass')); + }); + }); + }); }); diff --git a/tests/mocha/field_label_test.js b/tests/mocha/field_label_test.js index 8e6e53358..1ed552345 100644 --- a/tests/mocha/field_label_test.js +++ b/tests/mocha/field_label_test.js @@ -28,6 +28,18 @@ suite('Label Fields', function() { function assertValueDefault(labelField) { assertValue(labelField, ''); } + function assertHasClass(labelField, cssClass) { + labelField.fieldGroup_ = Blockly.utils.dom.createSvgElement('g', {}, null); + labelField.initView(); + chai.assert.isTrue(Blockly.utils.dom.hasClass( + labelField.textElement_, cssClass)); + } + function assertDoesNotHaveClass(labelField, cssClass) { + labelField.fieldGroup_ = Blockly.utils.dom.createSvgElement('g', {}, null); + labelField.initView(); + chai.assert.isFalse(Blockly.utils.dom.hasClass( + labelField.textElement_, cssClass)); + } suite('Constructor', function() { test('Empty', function() { var labelField = new Blockly.FieldLabel(); @@ -156,4 +168,66 @@ suite('Label Fields', function() { }); }); }); + suite('Customizations', function() { + test('JS Constructor', function() { + var field = new Blockly.FieldLabel('text', 'testClass'); + assertHasClass(field, 'testClass'); + }); + test('JSON Definition', function() { + var field = Blockly.FieldLabel.fromJson({ + class: 'testClass' + }); + assertHasClass(field, 'testClass'); + }); + test('JS Configuration - Simple', function() { + var field = new Blockly.FieldLabel('text', null, { + class: 'testClass' + }); + assertHasClass(field, 'testClass'); + }); + test('JS Configuration - Ignore', function() { + var field = new Blockly.FieldLabel('text', 'paramClass', { + class: 'configClass' + }); + assertDoesNotHaveClass(field, 'paramClass'); + assertHasClass(field, 'configClass'); + }); + test('JS Configuration - Ignore - \'\'', function() { + var field = new Blockly.FieldLabel('text', '', { + class: 'configClass' + }); + assertHasClass(field, 'configClass'); + }); + test('JS Configuration - Ignore - Config \'\'', function() { + var field = new Blockly.FieldLabel('text', 'paramClass', { + class: '' + }); + assertDoesNotHaveClass(field, 'paramClass'); + }); + suite('setClass', function() { + test('setClass', function() { + var field = new Blockly.FieldLabel(); + field.fieldGroup_ = Blockly.utils.dom.createSvgElement('g', {}, null); + field.initView(); + field.setClass('testClass'); + // Don't call assertHasClass b/c we don't want to re-initialize. + chai.assert.isTrue(Blockly.utils.dom.hasClass( + field.textElement_, 'testClass')); + }); + test('setClass Before Initialization', function() { + var field = new Blockly.FieldLabel(); + field.setClass('testClass'); + assertHasClass(field, 'testClass'); + }); + test('Remove Class', function() { + var field = new Blockly.FieldLabel('text', null, { + class: 'testClass' + }); + assertHasClass(field, 'testClass'); + field.setClass(null); + chai.assert.isFalse(Blockly.utils.dom.hasClass( + field.textElement_, 'testClass')); + }); + }); + }); });