Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions core/blockly.js
Original file line number Diff line number Diff line change
Expand Up @@ -545,15 +545,37 @@ exports.DRAG_STICKY = internalConstants.DRAG_STICKY;
exports.DRAG_BEGIN = internalConstants.DRAG_BEGIN;
exports.DRAG_FREE = internalConstants.DRAG_FREE;
exports.OPPOSITE_TYPE = internalConstants.OPPOSITE_TYPE;
exports.VARIABLE_CATEGORY_NAME = internalConstants.VARIABLE_CATEGORY_NAME;
exports.VARIABLE_DYNAMIC_CATEGORY_NAME =
internalConstants.VARIABLE_DYNAMIC_CATEGORY_NAME;
exports.PROCEDURE_CATEGORY_NAME = internalConstants.PROCEDURE_CATEGORY_NAME;
exports.RENAME_VARIABLE_ID = internalConstants.RENAME_VARIABLE_ID;
exports.DELETE_VARIABLE_ID = internalConstants.DELETE_VARIABLE_ID;
exports.COLLAPSED_INPUT_NAME = constants.COLLAPSED_INPUT_NAME;
exports.COLLAPSED_FIELD_NAME = constants.COLLAPSED_FIELD_NAME;

/**
* String for use in the "custom" attribute of a category in toolbox XML.
* This string indicates that the category should be dynamically populated with
* variable blocks.
* @const {string}
* @alias Blockly.VARIABLE_CATEGORY_NAME
*/
exports.VARIABLE_CATEGORY_NAME = Variables.CATEGORY_NAME;

/**
* String for use in the "custom" attribute of a category in toolbox XML.
* This string indicates that the category should be dynamically populated with
* variable blocks.
* @const {string}
* @alias Blockly.VARIABLE_DYNAMIC_CATEGORY_NAME
*/
exports.VARIABLE_DYNAMIC_CATEGORY_NAME = VariablesDynamic.CATEGORY_NAME;
/**
* String for use in the "custom" attribute of a category in toolbox XML.
* This string indicates that the category should be dynamically populated with
* procedure blocks.
* @const {string}
* @alias Blockly.PROCEDURE_CATEGORY_NAME
*/
exports.PROCEDURE_CATEGORY_NAME = Procedures.CATEGORY_NAME;

// Re-export submodules that no longer declareLegacyNamespace.
exports.ASTNode = ASTNode;
exports.BasicCursor = BasicCursor;
Expand Down
7 changes: 3 additions & 4 deletions core/generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,10 @@ goog.module('Blockly.Generator');

const common = goog.require('Blockly.common');
const deprecation = goog.require('Blockly.utils.deprecation');
const internalConstants = goog.require('Blockly.internalConstants');
/* eslint-disable-next-line no-unused-vars */
const {Block} = goog.requireType('Blockly.Block');
/* eslint-disable-next-line no-unused-vars */
const {Names} = goog.requireType('Blockly.Names');
const {Names, NameType} = goog.require('Blockly.Names');
/* eslint-disable-next-line no-unused-vars */
const {Workspace} = goog.requireType('Blockly.Workspace');

Expand Down Expand Up @@ -467,8 +466,8 @@ Object.defineProperties(Generator.prototype, {
*/
Generator.prototype.provideFunction_ = function(desiredName, code) {
if (!this.definitions_[desiredName]) {
const functionName = this.nameDB_.getDistinctName(
desiredName, internalConstants.PROCEDURE_CATEGORY_NAME);
const functionName =
this.nameDB_.getDistinctName(desiredName, NameType.PROCEDURE);
this.functionNames_[desiredName] = functionName;
let codeText = code.join('\n').replace(
this.FUNCTION_NAME_PLACEHOLDER_REGEXP_, functionName);
Expand Down
30 changes: 0 additions & 30 deletions core/internal_constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,36 +196,6 @@ OPPOSITE_TYPE[ConnectionType.PREVIOUS_STATEMENT] =

exports.OPPOSITE_TYPE = OPPOSITE_TYPE;

/**
* String for use in the "custom" attribute of a category in toolbox XML.
* This string indicates that the category should be dynamically populated with
* variable blocks.
* @const {string}
* @alias Blockly.internalConstants.VARIABLE_CATEGORY_NAME
*/
const VARIABLE_CATEGORY_NAME = 'VARIABLE';
exports.VARIABLE_CATEGORY_NAME = VARIABLE_CATEGORY_NAME;

/**
* String for use in the "custom" attribute of a category in toolbox XML.
* This string indicates that the category should be dynamically populated with
* variable blocks.
* @const {string}
* @alias Blockly.internalConstants.VARIABLE_DYNAMIC_CATEGORY_NAME
*/
const VARIABLE_DYNAMIC_CATEGORY_NAME = 'VARIABLE_DYNAMIC';
exports.VARIABLE_DYNAMIC_CATEGORY_NAME = VARIABLE_DYNAMIC_CATEGORY_NAME;

/**
* String for use in the "custom" attribute of a category in toolbox XML.
* This string indicates that the category should be dynamically populated with
* procedure blocks.
* @const {string}
* @alias Blockly.internalConstants.PROCEDURE_CATEGORY_NAME
*/
const PROCEDURE_CATEGORY_NAME = 'PROCEDURE';
exports.PROCEDURE_CATEGORY_NAME = PROCEDURE_CATEGORY_NAME;

/**
* String for use in the dropdown created in field_variable.
* This string indicates that this option in the dropdown is 'Rename
Expand Down
81 changes: 44 additions & 37 deletions core/names.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ goog.module('Blockly.Names');

const Msg = goog.require('Blockly.Msg');
const Variables = goog.require('Blockly.Variables');
const internalConstants = goog.require('Blockly.internalConstants');
/* eslint-disable-next-line no-unused-vars */
const {VariableMap} = goog.requireType('Blockly.VariableMap');
/* eslint-disable-next-line no-unused-vars */
Expand Down Expand Up @@ -48,22 +47,32 @@ const Names = function(reservedWords, opt_variablePrefix) {
};

/**
* Constant to separate developer variable names from user-defined variable
* names when running generators.
* A developer variable will be declared as a global in the generated code, but
* will never be shown to the user in the workspace or stored in the variable
* map.
*/
Names.DEVELOPER_VARIABLE_TYPE = 'DEVELOPER_VARIABLE';

/**
* Enum for the type of a name. Different name types may have different rules
* about collisions.
* When JavaScript (or most other languages) is generated, variable 'foo' and
* procedure 'foo' would collide. However, Blockly has no such problems since
* variable get 'foo' and procedure call 'foo' are unambiguous.
* Therefore, Blockly keeps a separate realm name to disambiguate.
* Therefore, Blockly keeps a separate name type to disambiguate.
* getName('foo', 'VARIABLE') -> 'foo'
* getName('foo', 'PROCEDURE') -> 'foo2'
* @enum { string }
* @alias Blockly.Names.NameType
*/
const NameType = {
DEVELOPER_VARIABLE: 'DEVELOPER_VARIABLE',
VARIABLE: 'VARIABLE',
PROCEDURE: 'PROCEDURE',
};
exports.NameType = NameType;

/**
* Constant to separate developer variable names from user-defined variable
* names when running generators.
* A developer variable will be declared as a global in the generated code, but
* will never be shown to the user in the workspace or stored in the variable
* map.
*/
Names.DEVELOPER_VARIABLE_TYPE = NameType.DEVELOPER_VARIABLE;

/**
* Empty the database and start from scratch. The reserved words are kept.
Expand All @@ -84,8 +93,7 @@ Names.prototype.setVariableMap = function(map) {

/**
* Get the name for a user-defined variable, based on its ID.
* This should only be used for variables of realm
* internalConstants.VARIABLE_CATEGORY_NAME.
* This should only be used for variables of NameType VARIABLE.
* @param {string} id The ID to look up in the variable map.
* @return {?string} The name of the referenced variable, or null if there was
* no variable map or the variable was not found in the map.
Expand Down Expand Up @@ -115,8 +123,7 @@ Names.prototype.getNameForUserVariable_ = function(id) {
Names.prototype.populateVariables = function(workspace) {
const variables = Variables.allUsedVarModels(workspace);
for (let i = 0; i < variables.length; i++) {
this.getName(
variables[i].getId(), internalConstants.VARIABLE_CATEGORY_NAME);
this.getName(variables[i].getId(), NameType.VARIABLE);
}
};

Expand All @@ -130,21 +137,21 @@ Names.prototype.populateProcedures = function(workspace) {
// Flatten the return vs no-return procedure lists.
procedures = procedures[0].concat(procedures[1]);
for (let i = 0; i < procedures.length; i++) {
this.getName(procedures[i][0], internalConstants.PROCEDURE_CATEGORY_NAME);
this.getName(procedures[i][0], NameType.PROCEDURE);
}
};

/**
* Convert a Blockly entity name to a legal exportable entity name.
* @param {string} nameOrId The Blockly entity name (no constraints) or
* variable ID.
* @param {string} realm The realm of entity in Blockly
* @param {NameType|string} type The type of the name in Blockly
* ('VARIABLE', 'PROCEDURE', 'DEVELOPER_VARIABLE', etc...).
* @return {string} An entity name that is legal in the exported language.
*/
Names.prototype.getName = function(nameOrId, realm) {
Names.prototype.getName = function(nameOrId, type) {
let name = nameOrId;
if (realm === internalConstants.VARIABLE_CATEGORY_NAME) {
if (type === NameType.VARIABLE) {
const varName = this.getNameForUserVariable_(nameOrId);
if (varName) {
// Successful ID lookup.
Expand All @@ -153,31 +160,31 @@ Names.prototype.getName = function(nameOrId, realm) {
}
const normalizedName = name.toLowerCase();

const isVar = realm === internalConstants.VARIABLE_CATEGORY_NAME ||
realm === Names.DEVELOPER_VARIABLE_TYPE;
const isVar =
type === NameType.VARIABLE || type === NameType.DEVELOPER_VARIABLE;

const prefix = isVar ? this.variablePrefix_ : '';
if (!(realm in this.db_)) {
this.db_[realm] = Object.create(null);
if (!(type in this.db_)) {
this.db_[type] = Object.create(null);
}
const realmDb = this.db_[realm];
if (normalizedName in realmDb) {
return prefix + realmDb[normalizedName];
const typeDb = this.db_[type];
if (normalizedName in typeDb) {
return prefix + typeDb[normalizedName];
}
const safeName = this.getDistinctName(name, realm);
realmDb[normalizedName] = safeName.substr(prefix.length);
const safeName = this.getDistinctName(name, type);
typeDb[normalizedName] = safeName.substr(prefix.length);
return safeName;
};

/**
* Return a list of all known user-created names in a specified realm.
* @param {string} realm The realm of entity in Blockly
* Return a list of all known user-created names of a specified name type.
* @param {NameType|string} type The type of entity in Blockly
* ('VARIABLE', 'PROCEDURE', 'DEVELOPER_VARIABLE', etc...).
* @return {!Array<string>} A list of Blockly entity names (no constraints).
*/
Names.prototype.getUserNames = function(realm) {
const realmDb = this.db_[realm] || {};
return Object.keys(realmDb);
Names.prototype.getUserNames = function(type) {
const typeDb = this.db_[type] || {};
return Object.keys(typeDb);
};

/**
Expand All @@ -186,11 +193,11 @@ Names.prototype.getUserNames = function(realm) {
* Also check against list of reserved words for the current language and
* ensure name doesn't collide.
* @param {string} name The Blockly entity name (no constraints).
* @param {string} realm The realm of entity in Blockly
* @param {NameType|string} type The type of entity in Blockly
* ('VARIABLE', 'PROCEDURE', 'DEVELOPER_VARIABLE', etc...).
* @return {string} An entity name that is legal in the exported language.
*/
Names.prototype.getDistinctName = function(name, realm) {
Names.prototype.getDistinctName = function(name, type) {
let safeName = this.safeName_(name);
let i = '';
while (this.dbReverse_[safeName + i] ||
Expand All @@ -200,8 +207,8 @@ Names.prototype.getDistinctName = function(name, realm) {
}
safeName += i;
this.dbReverse_[safeName] = true;
const isVar = realm === internalConstants.VARIABLE_CATEGORY_NAME ||
realm === Names.DEVELOPER_VARIABLE_TYPE;
const isVar =
type === NameType.VARIABLE || type === NameType.DEVELOPER_VARIABLE;
const prefix = isVar ? this.variablePrefix_ : '';
return prefix + safeName;
};
Expand Down
12 changes: 12 additions & 0 deletions core/procedures.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,18 @@ const {Workspace} = goog.require('Blockly.Workspace');
goog.require('Blockly.Events.BlockChange');


/**
* String for use in the "custom" attribute of a category in toolbox XML.
* This string indicates that the category should be dynamically populated with
* procedure blocks.
* See also Blockly.Variables.CATEGORY_NAME and
* Blockly.VariablesDynamic.CATEGORY_NAME.
* @const {string}
* @alias Blockly.Procedures.CATEGORY_NAME
*/
const CATEGORY_NAME = 'PROCEDURE';
exports.CATEGORY_NAME = CATEGORY_NAME;

/**
* The default argument for a procedures_mutatorarg block.
* @type {string}
Expand Down
11 changes: 11 additions & 0 deletions core/variables.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ const {VariableModel} = goog.require('Blockly.VariableModel');
/* eslint-disable-next-line no-unused-vars */
const {Workspace} = goog.requireType('Blockly.Workspace');

/**
* String for use in the "custom" attribute of a category in toolbox XML.
* This string indicates that the category should be dynamically populated with
* variable blocks.
* See also Blockly.Procedures.CATEGORY_NAME and
* Blockly.VariablesDynamic.CATEGORY_NAME.
* @const {string}
* @alias Blockly.Variables.CATEGORY_NAME
*/
const CATEGORY_NAME = 'VARIABLE';
exports.CATEGORY_NAME = CATEGORY_NAME;

/**
* Find all user-created variables that are in use in the workspace.
Expand Down
12 changes: 12 additions & 0 deletions core/variables_dynamic.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ const {VariableModel} = goog.require('Blockly.VariableModel');
const {Workspace} = goog.requireType('Blockly.Workspace');


/**
* String for use in the "custom" attribute of a category in toolbox XML.
* This string indicates that the category should be dynamically populated with
* variable blocks.
* See also Blockly.Variables.CATEGORY_NAME and
* Blockly.Procedures.CATEGORY_NAME.
* @const {string}
* @alias Blockly.VariablesDynamic.CATEGORY_NAME
*/
const CATEGORY_NAME = 'VARIABLE_DYNAMIC';
exports.CATEGORY_NAME = CATEGORY_NAME;

const stringButtonClickHandler = function(button) {
Variables.createVariableButtonHandler(
button.getTargetWorkspace(), undefined, 'String');
Expand Down
7 changes: 3 additions & 4 deletions core/workspace_svg.js
Original file line number Diff line number Diff line change
Expand Up @@ -226,20 +226,19 @@ const WorkspaceSvg = function(
const Variables = goog.module.get('Blockly.Variables');
if (Variables && Variables.flyoutCategory) {
this.registerToolboxCategoryCallback(
internalConstants.VARIABLE_CATEGORY_NAME, Variables.flyoutCategory);
Variables.CATEGORY_NAME, Variables.flyoutCategory);
}

const VariablesDynamic = goog.module.get('Blockly.VariablesDynamic');
if (VariablesDynamic && VariablesDynamic.flyoutCategory) {
this.registerToolboxCategoryCallback(
internalConstants.VARIABLE_DYNAMIC_CATEGORY_NAME,
VariablesDynamic.flyoutCategory);
VariablesDynamic.CATEGORY_NAME, VariablesDynamic.flyoutCategory);
}

const Procedures = goog.module.get('Blockly.Procedures');
if (Procedures && Procedures.flyoutCategory) {
this.registerToolboxCategoryCallback(
internalConstants.PROCEDURE_CATEGORY_NAME, Procedures.flyoutCategory);
Procedures.CATEGORY_NAME, Procedures.flyoutCategory);
this.addChangeListener(Procedures.mutatorOpenListener);
}

Expand Down
4 changes: 2 additions & 2 deletions tests/deps.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.