diff --git a/core/field_variable.js b/core/field_variable.js index e5e379c13..f700d4a99 100644 --- a/core/field_variable.js +++ b/core/field_variable.js @@ -10,24 +10,24 @@ */ 'use strict'; -goog.provide('Blockly.FieldVariable'); +goog.module('Blockly.FieldVariable'); +goog.module.declareLegacyNamespace(); +const Block = goog.requireType('Blockly.Block'); +const FieldDropdown = goog.require('Blockly.FieldDropdown'); +const Menu = goog.requireType('Blockly.Menu'); +const MenuItem = goog.requireType('Blockly.MenuItem'); +const Msg = goog.require('Blockly.Msg'); +const Size = goog.require('Blockly.utils.Size'); +const VariableModel = goog.require('Blockly.VariableModel'); +const Variables = goog.require('Blockly.Variables'); +const Xml = goog.require('Blockly.Xml'); +const fieldRegistry = goog.require('Blockly.fieldRegistry'); +const internalConstants = goog.require('Blockly.internalConstants'); +const {inherits} = goog.require('Blockly.utils.object'); +const {replaceMessageReferences} = goog.require('Blockly.utils'); /** @suppress {extraRequire} */ goog.require('Blockly.Events.BlockChange'); -goog.require('Blockly.FieldDropdown'); -goog.require('Blockly.fieldRegistry'); -goog.require('Blockly.internalConstants'); -goog.require('Blockly.Msg'); -goog.require('Blockly.utils'); -goog.require('Blockly.utils.object'); -goog.require('Blockly.utils.Size'); -goog.require('Blockly.VariableModel'); -goog.require('Blockly.Variables'); -goog.require('Blockly.Xml'); - -goog.requireType('Blockly.Block'); -goog.requireType('Blockly.Menu'); -goog.requireType('Blockly.MenuItem'); /** @@ -42,13 +42,14 @@ goog.requireType('Blockly.MenuItem'); * @param {string=} opt_defaultType The type of variable to create if this * field's value is not explicitly set. Defaults to ''. * @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/variable#creation} + * See the [field creation documentation]{@link + * https://developers.google.com/blockly/guides/create-custom-blocks/fields/built-in-fields/variable#creation} * for a list of properties this parameter supports. - * @extends {Blockly.FieldDropdown} + * @extends {FieldDropdown} * @constructor */ -Blockly.FieldVariable = function(varName, opt_validator, opt_variableTypes, - opt_defaultType, opt_config) { +const FieldVariable = function( + varName, opt_validator, opt_variableTypes, opt_defaultType, opt_config) { // The FieldDropdown constructor expects the field's initial value to be // the first entry in the menu generator, which it may or may not be. // Just do the relevant parts of the constructor. @@ -57,10 +58,10 @@ Blockly.FieldVariable = function(varName, opt_validator, opt_variableTypes, * An array of options for a dropdown list, * or a function which generates these options. * @type {(!Array| - * !function(this:Blockly.FieldDropdown): !Array)} + * !function(this:FieldDropdown): !Array)} * @protected */ - this.menuGenerator_ = Blockly.FieldVariable.dropdownCreate; + this.menuGenerator_ = FieldVariable.dropdownCreate; /** * The initial variable name passed to this field's constructor, or an @@ -72,11 +73,11 @@ Blockly.FieldVariable = function(varName, opt_validator, opt_variableTypes, /** * The size of the area rendered by the field. - * @type {Blockly.utils.Size} + * @type {Size} * @protected * @override */ - this.size_ = new Blockly.utils.Size(0, 0); + this.size_ = new Size(0, 0); opt_config && this.configure_(opt_config); opt_validator && this.setValidator(opt_validator); @@ -85,19 +86,19 @@ Blockly.FieldVariable = function(varName, opt_validator, opt_variableTypes, this.setTypes_(opt_variableTypes, opt_defaultType); } }; -Blockly.utils.object.inherits(Blockly.FieldVariable, Blockly.FieldDropdown); +inherits(FieldVariable, FieldDropdown); /** * Construct a FieldVariable from a JSON arg object, * dereferencing any string table references. * @param {!Object} options A JSON object with options (variable, * variableTypes, and defaultType). - * @return {!Blockly.FieldVariable} The new field instance. + * @return {!FieldVariable} The new field instance. * @package * @nocollapse */ -Blockly.FieldVariable.fromJson = function(options) { - var varName = Blockly.utils.replaceMessageReferences(options['variable']); +FieldVariable.fromJson = function(options) { + const varName = replaceMessageReferences(options['variable']); // `this` might be a subclass of FieldVariable if that class doesn't override // the static fromJson method. return new this(varName, undefined, undefined, undefined, options); @@ -108,15 +109,15 @@ Blockly.FieldVariable.fromJson = function(options) { * are not. Editable fields should also be serializable. * @type {boolean} */ -Blockly.FieldVariable.prototype.SERIALIZABLE = true; +FieldVariable.prototype.SERIALIZABLE = true; /** * Configure the field based on the given map of options. * @param {!Object} config A map of options to configure the field based on. * @protected */ -Blockly.FieldVariable.prototype.configure_ = function(config) { - Blockly.FieldVariable.superClass_.configure_.call(this, config); +FieldVariable.prototype.configure_ = function(config) { + FieldVariable.superClass_.configure_.call(this, config); this.setTypes_(config['variableTypes'], config['defaultType']); }; @@ -126,13 +127,13 @@ Blockly.FieldVariable.prototype.configure_ = function(config) { * variable rather than let the value be invalid. * @package */ -Blockly.FieldVariable.prototype.initModel = function() { +FieldVariable.prototype.initModel = function() { if (this.variable_) { return; // Initialization already happened. } - var variable = Blockly.Variables.getOrCreateVariablePackage( - this.sourceBlock_.workspace, null, - this.defaultVariableName, this.defaultType_); + const variable = Variables.getOrCreateVariablePackage( + this.sourceBlock_.workspace, null, this.defaultVariableName, + this.defaultType_); // Don't call setValue because we don't want to cause a rerender. this.doValueUpdate_(variable.getId()); @@ -141,10 +142,10 @@ Blockly.FieldVariable.prototype.initModel = function() { /** * @override */ -Blockly.FieldVariable.prototype.shouldAddBorderRect_ = function() { - return Blockly.FieldVariable.superClass_.shouldAddBorderRect_.call(this) && - (!this.getConstants().FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW || - this.sourceBlock_.type != 'variables_get'); +FieldVariable.prototype.shouldAddBorderRect_ = function() { + return FieldVariable.superClass_.shouldAddBorderRect_.call(this) && + (!this.getConstants().FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW || + this.sourceBlock_.type != 'variables_get'); }; /** @@ -152,23 +153,24 @@ Blockly.FieldVariable.prototype.shouldAddBorderRect_ = function() { * @param {!Element} fieldElement The element containing information about the * variable field's state. */ -Blockly.FieldVariable.prototype.fromXml = function(fieldElement) { - var id = fieldElement.getAttribute('id'); - var variableName = fieldElement.textContent; +FieldVariable.prototype.fromXml = function(fieldElement) { + const id = fieldElement.getAttribute('id'); + const variableName = fieldElement.textContent; // 'variabletype' should be lowercase, but until July 2019 it was sometimes // recorded as 'variableType'. Thus we need to check for both. - var variableType = fieldElement.getAttribute('variabletype') || + const variableType = fieldElement.getAttribute('variabletype') || fieldElement.getAttribute('variableType') || ''; - var variable = Blockly.Variables.getOrCreateVariablePackage( + const variable = Variables.getOrCreateVariablePackage( this.sourceBlock_.workspace, id, variableName, variableType); // This should never happen :) if (variableType != null && variableType !== variable.type) { - throw Error('Serialized variable type with id \'' + - variable.getId() + '\' had type ' + variable.type + ', and ' + - 'does not match variable field that references it: ' + - Blockly.Xml.domToText(fieldElement) + '.'); + throw Error( + 'Serialized variable type with id \'' + variable.getId() + + '\' had type ' + variable.type + ', and ' + + 'does not match variable field that references it: ' + + Xml.domToText(fieldElement) + '.'); } this.setValue(variable.getId()); @@ -180,7 +182,7 @@ Blockly.FieldVariable.prototype.fromXml = function(fieldElement) { * field's state. * @return {!Element} The element containing info about the field's state. */ -Blockly.FieldVariable.prototype.toXml = function(fieldElement) { +FieldVariable.prototype.toXml = function(fieldElement) { // Make sure the variable is initialized. this.initModel(); @@ -194,20 +196,20 @@ Blockly.FieldVariable.prototype.toXml = function(fieldElement) { /** * Attach this field to a block. - * @param {!Blockly.Block} block The block containing this field. + * @param {!Block} block The block containing this field. */ -Blockly.FieldVariable.prototype.setSourceBlock = function(block) { +FieldVariable.prototype.setSourceBlock = function(block) { if (block.isShadow()) { throw Error('Variable fields are not allowed to exist on shadow blocks.'); } - Blockly.FieldVariable.superClass_.setSourceBlock.call(this, block); + FieldVariable.superClass_.setSourceBlock.call(this, block); }; /** * Get the variable's ID. * @return {string} Current variable's ID. */ -Blockly.FieldVariable.prototype.getValue = function() { +FieldVariable.prototype.getValue = function() { return this.variable_ ? this.variable_.getId() : null; }; @@ -216,7 +218,7 @@ Blockly.FieldVariable.prototype.getValue = function() { * @return {string} The selected variable's name, or the empty string if no * variable is selected. */ -Blockly.FieldVariable.prototype.getText = function() { +FieldVariable.prototype.getText = function() { return this.variable_ ? this.variable_.name : ''; }; @@ -224,11 +226,11 @@ Blockly.FieldVariable.prototype.getText = function() { * Get the variable model for the selected variable. * Not guaranteed to be in the variable map on the workspace (e.g. if accessed * after the variable has been deleted). - * @return {?Blockly.VariableModel} The selected variable, or null if none was + * @return {?VariableModel} The selected variable, or null if none was * selected. * @package */ -Blockly.FieldVariable.prototype.getVariable = function() { +FieldVariable.prototype.getVariable = function() { return this.variable_; }; @@ -239,7 +241,7 @@ Blockly.FieldVariable.prototype.getVariable = function() { * a block and workspace at that point. * @return {?Function} Validation function, or null. */ -Blockly.FieldVariable.prototype.getValidator = function() { +FieldVariable.prototype.getValidator = function() { // Validators shouldn't operate on the initial setValue call. // Normally this is achieved by calling setValidator after setValue, but // this is not a possibility with variable fields. @@ -255,20 +257,20 @@ Blockly.FieldVariable.prototype.getValidator = function() { * @return {?string} The validated ID, or null if invalid. * @protected */ -Blockly.FieldVariable.prototype.doClassValidation_ = function(opt_newValue) { +FieldVariable.prototype.doClassValidation_ = function(opt_newValue) { if (opt_newValue === null) { return null; } - var newId = /** @type {string} */ (opt_newValue); - var variable = Blockly.Variables.getVariable( - this.sourceBlock_.workspace, newId); + const newId = /** @type {string} */ (opt_newValue); + const variable = Variables.getVariable(this.sourceBlock_.workspace, newId); if (!variable) { - console.warn('Variable id doesn\'t point to a real variable! ' + + console.warn( + 'Variable id doesn\'t point to a real variable! ' + 'ID was ' + newId); return null; } // Type Checks. - var type = variable.type; + const type = variable.type; if (!this.typeIsAllowed_(type)) { console.warn('Variable type doesn\'t match this field! Type was ' + type); return null; @@ -284,10 +286,10 @@ Blockly.FieldVariable.prototype.doClassValidation_ = function(opt_newValue) { * @param {*} newId The value to be saved. * @protected */ -Blockly.FieldVariable.prototype.doValueUpdate_ = function(newId) { - this.variable_ = Blockly.Variables.getVariable( +FieldVariable.prototype.doValueUpdate_ = function(newId) { + this.variable_ = Variables.getVariable( this.sourceBlock_.workspace, /** @type {string} */ (newId)); - Blockly.FieldVariable.superClass_.doValueUpdate_.call(this, newId); + FieldVariable.superClass_.doValueUpdate_.call(this, newId); }; /** @@ -296,12 +298,12 @@ Blockly.FieldVariable.prototype.doValueUpdate_ = function(newId) { * @return {boolean} True if the type is in the list of allowed types. * @private */ -Blockly.FieldVariable.prototype.typeIsAllowed_ = function(type) { - var typeList = this.getVariableTypes_(); +FieldVariable.prototype.typeIsAllowed_ = function(type) { + const typeList = this.getVariableTypes_(); if (!typeList) { return true; // If it's null, all types are valid. } - for (var i = 0; i < typeList.length; i++) { + for (let i = 0; i < typeList.length; i++) { if (type == typeList[i]) { return true; } @@ -315,9 +317,9 @@ Blockly.FieldVariable.prototype.typeIsAllowed_ = function(type) { * @throws {Error} if variableTypes is an empty array. * @private */ -Blockly.FieldVariable.prototype.getVariableTypes_ = function() { +FieldVariable.prototype.getVariableTypes_ = function() { // TODO (#1513): Try to avoid calling this every time the field is edited. - var variableTypes = this.variableTypes; + let variableTypes = this.variableTypes; if (variableTypes === null) { // If variableTypes is null, return all variable types. if (this.sourceBlock_ && this.sourceBlock_.workspace) { @@ -327,9 +329,9 @@ Blockly.FieldVariable.prototype.getVariableTypes_ = function() { variableTypes = variableTypes || ['']; if (variableTypes.length == 0) { // Throw an error if variableTypes is an empty list. - var name = this.getText(); - throw Error('\'variableTypes\' of field variable ' + - name + ' was an empty list'); + const name = this.getText(); + throw Error( + '\'variableTypes\' of field variable ' + name + ' was an empty list'); } return variableTypes; }; @@ -344,29 +346,32 @@ Blockly.FieldVariable.prototype.getVariableTypes_ = function() { * field's value is not explicitly set. Defaults to ''. * @private */ -Blockly.FieldVariable.prototype.setTypes_ = function(opt_variableTypes, - opt_defaultType) { +FieldVariable.prototype.setTypes_ = function( + opt_variableTypes, opt_defaultType) { // If you expected that the default type would be the same as the only entry // in the variable types array, tell the Blockly team by commenting on #1499. - var defaultType = opt_defaultType || ''; + const defaultType = opt_defaultType || ''; + let variableTypes; // Set the allowable variable types. Null means all types on the workspace. if (opt_variableTypes == null || opt_variableTypes == undefined) { - var variableTypes = null; + variableTypes = null; } else if (Array.isArray(opt_variableTypes)) { - var variableTypes = opt_variableTypes; + variableTypes = opt_variableTypes; // Make sure the default type is valid. - var isInArray = false; - for (var i = 0; i < variableTypes.length; i++) { + let isInArray = false; + for (let i = 0; i < variableTypes.length; i++) { if (variableTypes[i] == defaultType) { isInArray = true; } } if (!isInArray) { - throw Error('Invalid default type \'' + defaultType + '\' in ' + + throw Error( + 'Invalid default type \'' + defaultType + '\' in ' + 'the definition of a FieldVariable'); } } else { - throw Error('\'variableTypes\' was not an array in the definition of ' + + throw Error( + '\'variableTypes\' was not an array in the definition of ' + 'a FieldVariable'); } // Only update the field once all checks pass. @@ -380,7 +385,7 @@ Blockly.FieldVariable.prototype.setTypes_ = function(opt_variableTypes, * be called by the block. * @package */ -Blockly.FieldVariable.prototype.refreshVariableName = function() { +FieldVariable.prototype.refreshVariableName = function() { this.forceRerender(); }; @@ -388,40 +393,39 @@ Blockly.FieldVariable.prototype.refreshVariableName = function() { * Return a sorted list of variable names for variable dropdown menus. * Include a special option at the end for creating a new variable name. * @return {!Array} Array of variable names/id tuples. - * @this {Blockly.FieldVariable} + * @this {FieldVariable} */ -Blockly.FieldVariable.dropdownCreate = function() { +FieldVariable.dropdownCreate = function() { if (!this.variable_) { - throw Error('Tried to call dropdownCreate on a variable field with no' + + throw Error( + 'Tried to call dropdownCreate on a variable field with no' + ' variable selected.'); } - var name = this.getText(); - var variableModelList = []; + const name = this.getText(); + let variableModelList = []; if (this.sourceBlock_ && this.sourceBlock_.workspace) { - var variableTypes = this.getVariableTypes_(); + const variableTypes = this.getVariableTypes_(); // Get a copy of the list, so that adding rename and new variable options // doesn't modify the workspace's list. - for (var i = 0; i < variableTypes.length; i++) { - var variableType = variableTypes[i]; - var variables = - this.sourceBlock_.workspace.getVariablesOfType(variableType); + for (let i = 0; i < variableTypes.length; i++) { + const variableType = variableTypes[i]; + const variables = + this.sourceBlock_.workspace.getVariablesOfType(variableType); variableModelList = variableModelList.concat(variables); } } - variableModelList.sort(Blockly.VariableModel.compareByName); + variableModelList.sort(VariableModel.compareByName); - var options = []; - for (var i = 0; i < variableModelList.length; i++) { + const options = []; + for (let i = 0; i < variableModelList.length; i++) { // Set the UUID as the internal representation of the variable. options[i] = [variableModelList[i].name, variableModelList[i].getId()]; } - options.push([ - Blockly.Msg['RENAME_VARIABLE'], Blockly.internalConstants.RENAME_VARIABLE_ID - ]); - if (Blockly.Msg['DELETE_VARIABLE']) { + options.push([Msg['RENAME_VARIABLE'], internalConstants.RENAME_VARIABLE_ID]); + if (Msg['DELETE_VARIABLE']) { options.push([ - Blockly.Msg['DELETE_VARIABLE'].replace('%1', name), - Blockly.internalConstants.DELETE_VARIABLE_ID + Msg['DELETE_VARIABLE'].replace('%1', name), + internalConstants.DELETE_VARIABLE_ID ]); } @@ -432,20 +436,19 @@ Blockly.FieldVariable.dropdownCreate = function() { * Handle the selection of an item in the variable dropdown menu. * Special case the 'Rename variable...' and 'Delete variable...' options. * In the rename case, prompt the user for a new name. - * @param {!Blockly.Menu} menu The Menu component clicked. - * @param {!Blockly.MenuItem} menuItem The MenuItem selected within menu. + * @param {!Menu} menu The Menu component clicked. + * @param {!MenuItem} menuItem The MenuItem selected within menu. * @protected */ -Blockly.FieldVariable.prototype.onItemSelected_ = function(menu, menuItem) { - var id = menuItem.getValue(); +FieldVariable.prototype.onItemSelected_ = function(menu, menuItem) { + const id = menuItem.getValue(); // Handle special cases. if (this.sourceBlock_ && this.sourceBlock_.workspace) { - if (id == Blockly.internalConstants.RENAME_VARIABLE_ID) { + if (id == internalConstants.RENAME_VARIABLE_ID) { // Rename variable. - Blockly.Variables.renameVariable( - this.sourceBlock_.workspace, this.variable_); + Variables.renameVariable(this.sourceBlock_.workspace, this.variable_); return; - } else if (id == Blockly.internalConstants.DELETE_VARIABLE_ID) { + } else if (id == internalConstants.DELETE_VARIABLE_ID) { // Delete variable. this.sourceBlock_.workspace.deleteVariableById(this.variable_.getId()); return; @@ -461,8 +464,10 @@ Blockly.FieldVariable.prototype.onItemSelected_ = function(menu, menuItem) { * @package * @override */ -Blockly.FieldVariable.prototype.referencesVariables = function() { +FieldVariable.prototype.referencesVariables = function() { return true; }; -Blockly.fieldRegistry.register('field_variable', Blockly.FieldVariable); +fieldRegistry.register('field_variable', FieldVariable); + +exports = FieldVariable; diff --git a/tests/deps.js b/tests/deps.js index 234771c13..05c15c9e7 100644 --- a/tests/deps.js +++ b/tests/deps.js @@ -60,7 +60,7 @@ goog.addDependency('../../core/field_multilineinput.js', ['Blockly.FieldMultilin goog.addDependency('../../core/field_number.js', ['Blockly.FieldNumber'], ['Blockly.FieldTextInput', 'Blockly.fieldRegistry', 'Blockly.utils.aria', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/field_registry.js', ['Blockly.fieldRegistry'], ['Blockly.registry']); goog.addDependency('../../core/field_textinput.js', ['Blockly.FieldTextInput'], ['Blockly.DropDownDiv', 'Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Field', 'Blockly.Msg', 'Blockly.WidgetDiv', 'Blockly.browserEvents', 'Blockly.fieldRegistry', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.KeyCodes', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.userAgent']); -goog.addDependency('../../core/field_variable.js', ['Blockly.FieldVariable'], ['Blockly.Events.BlockChange', 'Blockly.FieldDropdown', 'Blockly.Msg', 'Blockly.VariableModel', 'Blockly.Variables', 'Blockly.Xml', 'Blockly.fieldRegistry', 'Blockly.internalConstants', 'Blockly.utils', 'Blockly.utils.Size', 'Blockly.utils.object']); +goog.addDependency('../../core/field_variable.js', ['Blockly.FieldVariable'], ['Blockly.Events.BlockChange', 'Blockly.FieldDropdown', 'Blockly.Msg', 'Blockly.VariableModel', 'Blockly.Variables', 'Blockly.Xml', 'Blockly.fieldRegistry', 'Blockly.internalConstants', 'Blockly.utils', 'Blockly.utils.Size', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/flyout_base.js', ['Blockly.Flyout'], ['Blockly.Block', 'Blockly.ComponentManager', 'Blockly.DeleteArea', 'Blockly.Events', 'Blockly.Events.BlockCreate', 'Blockly.Events.VarCreate', 'Blockly.FlyoutMetricsManager', 'Blockly.Gesture', 'Blockly.IFlyout', 'Blockly.ScrollbarPair', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.WorkspaceSvg', 'Blockly.Xml', 'Blockly.blockRendering', 'Blockly.browserEvents', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.toolbox', 'Blockly.utils.xml']); goog.addDependency('../../core/flyout_button.js', ['Blockly.FlyoutButton'], ['Blockly.Css', 'Blockly.browserEvents', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.style'], {'lang': 'es5'}); goog.addDependency('../../core/flyout_horizontal.js', ['Blockly.HorizontalFlyout'], ['Blockly.Block', 'Blockly.DropDownDiv', 'Blockly.Flyout', 'Blockly.Scrollbar', 'Blockly.WidgetDiv', 'Blockly.registry', 'Blockly.utils', 'Blockly.utils.Rect', 'Blockly.utils.object', 'Blockly.utils.toolbox']);