Commit 315a5fc7 authored by Neil Fraser's avatar Neil Fraser

Remove global workspace references from variable and procedure utilities.

parent 6cc26f07
This diff is collapsed.
...@@ -66,14 +66,32 @@ Blockly.FieldVariable = function(varname, opt_changeHandler) { ...@@ -66,14 +66,32 @@ Blockly.FieldVariable = function(varname, opt_changeHandler) {
Blockly.FieldVariable.superClass_.constructor.call(this, Blockly.FieldVariable.superClass_.constructor.call(this,
Blockly.FieldVariable.dropdownCreate, changeHandler); Blockly.FieldVariable.dropdownCreate, changeHandler);
if (varname) { this.setValue(varname || '');
this.setValue(varname);
} else {
this.setValue(Blockly.Variables.generateUniqueName());
}
}; };
goog.inherits(Blockly.FieldVariable, Blockly.FieldDropdown); goog.inherits(Blockly.FieldVariable, Blockly.FieldDropdown);
/**
* Install this dropdown on a block.
* @param {!Blockly.Block} block The block containing this text.
*/
Blockly.FieldVariable.prototype.init = function(block) {
if (this.sourceBlock_) {
// Dropdown has already been initialized once.
return;
}
if (!this.getValue()) {
// Variables without names get uniquely named for this workspace.
if (block.isInFlyout) {
var workspace = block.workspace.targetWorkspace;
} else {
var workspace = block.workspace;
}
this.setValue(Blockly.Variables.generateUniqueName(workspace));
}
Blockly.FieldVariable.superClass_.init.call(this, block);
};
/** /**
* Clone this FieldVariable. * Clone this FieldVariable.
* @return {!Blockly.FieldVariable} The result of calling the constructor again * @return {!Blockly.FieldVariable} The result of calling the constructor again
...@@ -147,14 +165,23 @@ Blockly.FieldVariable.dropdownChange = function(text) { ...@@ -147,14 +165,23 @@ Blockly.FieldVariable.dropdownChange = function(text) {
var newVar = window.prompt(promptText, defaultText); var newVar = window.prompt(promptText, defaultText);
// Merge runs of whitespace. Strip leading and trailing whitespace. // Merge runs of whitespace. Strip leading and trailing whitespace.
// Beyond this, all names are legal. // Beyond this, all names are legal.
return newVar && newVar.replace(/[\s\xa0]+/g, ' ').replace(/^ | $/g, ''); if (newVar) {
newVar = newVar.replace(/[\s\xa0]+/g, ' ').replace(/^ | $/g, '');
if (newVar == Blockly.Msg.RENAME_VARIABLE ||
newVar == Blockly.Msg.NEW_VARIABLE) {
// Ok, not ALL names are legal...
newVar = null;
}
}
return newVar;
} }
var workspace = this.sourceBlock_.workspace;
if (text == Blockly.Msg.RENAME_VARIABLE) { if (text == Blockly.Msg.RENAME_VARIABLE) {
var oldVar = this.getText(); var oldVar = this.getText();
text = promptName(Blockly.Msg.RENAME_VARIABLE_TITLE.replace('%1', oldVar), text = promptName(Blockly.Msg.RENAME_VARIABLE_TITLE.replace('%1', oldVar),
oldVar); oldVar);
if (text) { if (text) {
Blockly.Variables.renameVariable(oldVar, text); Blockly.Variables.renameVariable(oldVar, text, workspace);
} }
return null; return null;
} else if (text == Blockly.Msg.NEW_VARIABLE) { } else if (text == Blockly.Msg.NEW_VARIABLE) {
...@@ -162,7 +189,7 @@ Blockly.FieldVariable.dropdownChange = function(text) { ...@@ -162,7 +189,7 @@ Blockly.FieldVariable.dropdownChange = function(text) {
// Since variables are case-insensitive, ensure that if the new variable // Since variables are case-insensitive, ensure that if the new variable
// matches with an existing variable, the new case prevails throughout. // matches with an existing variable, the new case prevails throughout.
if (text) { if (text) {
Blockly.Variables.renameVariable(text, text); Blockly.Variables.renameVariable(text, text, workspace);
return text; return text;
} }
return null; return null;
......
...@@ -201,6 +201,7 @@ Blockly.Flyout.prototype.setMetrics_ = function(yRatio) { ...@@ -201,6 +201,7 @@ Blockly.Flyout.prototype.setMetrics_ = function(yRatio) {
*/ */
Blockly.Flyout.prototype.init = function(workspace) { Blockly.Flyout.prototype.init = function(workspace) {
this.targetWorkspace_ = workspace; this.targetWorkspace_ = workspace;
this.workspace_.targetWorkspace = workspace;
// Add scrollbar. // Add scrollbar.
this.scrollbar_ = new Blockly.Scrollbar(this.workspace_, false, false); this.scrollbar_ = new Blockly.Scrollbar(this.workspace_, false, false);
......
...@@ -39,14 +39,15 @@ goog.require('Blockly.Workspace'); ...@@ -39,14 +39,15 @@ goog.require('Blockly.Workspace');
Blockly.Procedures.NAME_TYPE = 'PROCEDURE'; Blockly.Procedures.NAME_TYPE = 'PROCEDURE';
/** /**
* Find all user-created procedure definitions. * Find all user-created procedure definitions in a workspace.
* @param {!Blockly.Workspace} root Root workspace.
* @return {!Array.<!Array.<!Array>>} Pair of arrays, the * @return {!Array.<!Array.<!Array>>} Pair of arrays, the
* first contains procedures without return variables, the second with. * first contains procedures without return variables, the second with.
* Each procedure is defined by a three-element list of name, parameter * Each procedure is defined by a three-element list of name, parameter
* list, and return value boolean. * list, and return value boolean.
*/ */
Blockly.Procedures.allProcedures = function() { Blockly.Procedures.allProcedures = function(root) {
var blocks = Blockly.mainWorkspace.getAllBlocks(); var blocks = root.getAllBlocks();
var proceduresReturn = []; var proceduresReturn = [];
var proceduresNoReturn = []; var proceduresNoReturn = [];
for (var x = 0; x < blocks.length; x++) { for (var x = 0; x < blocks.length; x++) {
...@@ -207,7 +208,7 @@ Blockly.Procedures.flyoutCategory = function(blocks, gaps, margin, workspace) { ...@@ -207,7 +208,7 @@ Blockly.Procedures.flyoutCategory = function(blocks, gaps, margin, workspace) {
} }
} }
var tuple = Blockly.Procedures.allProcedures(); var tuple = Blockly.Procedures.allProcedures(workspace.targetWorkspace);
populateProcedures(tuple[0], 'procedures_callnoreturn'); populateProcedures(tuple[0], 'procedures_callnoreturn');
populateProcedures(tuple[1], 'procedures_callreturn'); populateProcedures(tuple[1], 'procedures_callreturn');
}; };
......
...@@ -38,12 +38,10 @@ Blockly.Variables.NAME_TYPE = 'VARIABLE'; ...@@ -38,12 +38,10 @@ Blockly.Variables.NAME_TYPE = 'VARIABLE';
/** /**
* Find all user-created variables. * Find all user-created variables.
* @param {Blockly.Block|Blockly.Workspace|undefined} opt_root Optional root * @param {!Blockly.Block|!Blockly.Workspace} root Root block or workspace.
* block or workspace. Defaults to main workspace.
* @return {!Array.<string>} Array of variable names. * @return {!Array.<string>} Array of variable names.
*/ */
Blockly.Variables.allVariables = function(opt_root) { Blockly.Variables.allVariables = function(root) {
var root = opt_root || Blockly.mainWorkspace;
var blocks; var blocks;
if (root.getDescendants) { if (root.getDescendants) {
// Root is Block. // Root is Block.
...@@ -81,11 +79,9 @@ Blockly.Variables.allVariables = function(opt_root) { ...@@ -81,11 +79,9 @@ Blockly.Variables.allVariables = function(opt_root) {
* Find all instances of the specified variable and rename them. * Find all instances of the specified variable and rename them.
* @param {string} oldName Variable to rename. * @param {string} oldName Variable to rename.
* @param {string} newName New variable name. * @param {string} newName New variable name.
* @param {Blockly.Workspace=} opt_workspace Workspace rename variables in. * @param {!Blockly.Workspace} workspace Workspace rename variables in.
* Defaults to main workspace.
*/ */
Blockly.Variables.renameVariable = function(oldName, newName, opt_workspace) { Blockly.Variables.renameVariable = function(oldName, newName, workspace) {
var workspace = opt_workspace || Blockly.mainWorkspace;
var blocks = workspace.getAllBlocks(); var blocks = workspace.getAllBlocks();
// Iterate through every block. // Iterate through every block.
for (var x = 0; x < blocks.length; x++) { for (var x = 0; x < blocks.length; x++) {
...@@ -104,7 +100,7 @@ Blockly.Variables.renameVariable = function(oldName, newName, opt_workspace) { ...@@ -104,7 +100,7 @@ Blockly.Variables.renameVariable = function(oldName, newName, opt_workspace) {
* @param {!Blockly.Workspace} workspace The flyout's workspace. * @param {!Blockly.Workspace} workspace The flyout's workspace.
*/ */
Blockly.Variables.flyoutCategory = function(blocks, gaps, margin, workspace) { Blockly.Variables.flyoutCategory = function(blocks, gaps, margin, workspace) {
var variableList = Blockly.Variables.allVariables(); var variableList = Blockly.Variables.allVariables(workspace.targetWorkspace);
variableList.sort(goog.string.caseInsensitiveCompare); variableList.sort(goog.string.caseInsensitiveCompare);
// In addition to the user's variables, we also want to display the default // In addition to the user's variables, we also want to display the default
// variable name at the top. We also don't want this duplicated if the // variable name at the top. We also don't want this duplicated if the
...@@ -140,40 +136,39 @@ Blockly.Variables.flyoutCategory = function(blocks, gaps, margin, workspace) { ...@@ -140,40 +136,39 @@ Blockly.Variables.flyoutCategory = function(blocks, gaps, margin, workspace) {
/** /**
* Return a new variable name that is not yet being used. This will try to * Return a new variable name that is not yet being used. This will try to
* generate single letter variable names in the range 'i' to 'z' to start with. * generate single letter variable names in the range 'i' to 'z' to start with.
* If no unique name is located it will try 'i1' to 'z1', then 'i2' to 'z2' etc. * If no unique name is located it will try 'i' to 'z', 'a' to 'h',
* then 'i2' to 'z2' etc. Skip 'l'.
* @param {!Blockly.Workspace} workspace The workspace to be unique in.
* @return {string} New variable name. * @return {string} New variable name.
*/ */
Blockly.Variables.generateUniqueName = function() { Blockly.Variables.generateUniqueName = function(workspace) {
var variableList = Blockly.Variables.allVariables(); var variableList = Blockly.Variables.allVariables(workspace);
var newName = ''; var newName = '';
if (variableList.length) { if (variableList.length) {
variableList.sort(goog.string.caseInsensitiveCompare); var nameSuffix = 1;
var nameSuffix = 0, potName = 'i', i = 0, inUse = false; var letters = 'ijkmnopqrstuvwxyzabcdefgh'; // No 'l'.
var letterIndex = 0;
var potName = letters.charAt(letterIndex);
while (!newName) { while (!newName) {
i = 0; var inUse = false;
inUse = false; for (var i = 0; i < variableList.length; i++) {
while (i < variableList.length && !inUse) {
if (variableList[i].toLowerCase() == potName) { if (variableList[i].toLowerCase() == potName) {
// This potential name is already used. // This potential name is already used.
inUse = true; inUse = true;
break;
} }
i++;
} }
if (inUse) { if (inUse) {
// Try the next potential name. // Try the next potential name.
if (potName[0] === 'z') { letterIndex++;
// Reached the end of the character sequence so back to 'a' but with if (letterIndex == letters.length) {
// Reached the end of the character sequence so back to 'i'.
// a new suffix. // a new suffix.
letterIndex = 0;
nameSuffix++; nameSuffix++;
potName = 'a';
} else {
potName = String.fromCharCode(potName.charCodeAt(0) + 1);
if (potName[0] == 'l') {
// Avoid using variable 'l' because of ambiguity with '1'.
potName = String.fromCharCode(potName.charCodeAt(0) + 1);
}
} }
if (nameSuffix > 0) { potName = letters.charAt(letterIndex);
if (nameSuffix > 1) {
potName += nameSuffix; potName += nameSuffix;
} }
} else { } else {
......
...@@ -73,10 +73,9 @@ Blockly.Dart.ORDER_NONE = 99; // (...) ...@@ -73,10 +73,9 @@ Blockly.Dart.ORDER_NONE = 99; // (...)
/** /**
* Initialise the database of variable names. * Initialise the database of variable names.
* @param {Blockly.Workspace=} opt_workspace Workspace to generate code from. * @param {!Blockly.Workspace} workspace Workspace to generate code from.
* Defaults to main workspace.
*/ */
Blockly.Dart.init = function(opt_workspace) { Blockly.Dart.init = function(workspace) {
// Create a dictionary of definitions to be printed before the code. // Create a dictionary of definitions to be printed before the code.
Blockly.Dart.definitions_ = Object.create(null); Blockly.Dart.definitions_ = Object.create(null);
// Create a dictionary mapping desired function names in definitions_ // Create a dictionary mapping desired function names in definitions_
...@@ -91,7 +90,7 @@ Blockly.Dart.init = function(opt_workspace) { ...@@ -91,7 +90,7 @@ Blockly.Dart.init = function(opt_workspace) {
} }
var defvars = []; var defvars = [];
var variables = Blockly.Variables.allVariables(opt_workspace); var variables = Blockly.Variables.allVariables(workspace);
for (var x = 0; x < variables.length; x++) { for (var x = 0; x < variables.length; x++) {
defvars[x] = 'var ' + defvars[x] = 'var ' +
Blockly.Dart.variableDB_.getName(variables[x], Blockly.Dart.variableDB_.getName(variables[x],
......
...@@ -105,10 +105,9 @@ Blockly.JavaScript.ORDER_NONE = 99; // (...) ...@@ -105,10 +105,9 @@ Blockly.JavaScript.ORDER_NONE = 99; // (...)
/** /**
* Initialise the database of variable names. * Initialise the database of variable names.
* @param {Blockly.Workspace=} opt_workspace Workspace to generate code from. * @param {!Blockly.Workspace} workspace Workspace to generate code from.
* Defaults to main workspace.
*/ */
Blockly.JavaScript.init = function(opt_workspace) { Blockly.JavaScript.init = function(workspace) {
// Create a dictionary of definitions to be printed before the code. // Create a dictionary of definitions to be printed before the code.
Blockly.JavaScript.definitions_ = Object.create(null); Blockly.JavaScript.definitions_ = Object.create(null);
// Create a dictionary mapping desired function names in definitions_ // Create a dictionary mapping desired function names in definitions_
...@@ -123,7 +122,7 @@ Blockly.JavaScript.init = function(opt_workspace) { ...@@ -123,7 +122,7 @@ Blockly.JavaScript.init = function(opt_workspace) {
} }
var defvars = []; var defvars = [];
var variables = Blockly.Variables.allVariables(opt_workspace); var variables = Blockly.Variables.allVariables(workspace);
for (var x = 0; x < variables.length; x++) { for (var x = 0; x < variables.length; x++) {
defvars[x] = 'var ' + defvars[x] = 'var ' +
Blockly.JavaScript.variableDB_.getName(variables[x], Blockly.JavaScript.variableDB_.getName(variables[x],
......
...@@ -81,10 +81,9 @@ Blockly.Python.ORDER_NONE = 99; // (...) ...@@ -81,10 +81,9 @@ Blockly.Python.ORDER_NONE = 99; // (...)
/** /**
* Initialise the database of variable names. * Initialise the database of variable names.
* @param {Blockly.Workspace=} opt_workspace Workspace to generate code from. * @param {!Blockly.Workspace} workspace Workspace to generate code from.
* Defaults to main workspace.
*/ */
Blockly.Python.init = function(opt_workspace) { Blockly.Python.init = function(workspace) {
// Create a dictionary of definitions to be printed before the code. // Create a dictionary of definitions to be printed before the code.
Blockly.Python.definitions_ = Object.create(null); Blockly.Python.definitions_ = Object.create(null);
// Create a dictionary mapping desired function names in definitions_ // Create a dictionary mapping desired function names in definitions_
...@@ -99,7 +98,7 @@ Blockly.Python.init = function(opt_workspace) { ...@@ -99,7 +98,7 @@ Blockly.Python.init = function(opt_workspace) {
} }
var defvars = []; var defvars = [];
var variables = Blockly.Variables.allVariables(opt_workspace); var variables = Blockly.Variables.allVariables(workspace);
for (var x = 0; x < variables.length; x++) { for (var x = 0; x < variables.length; x++) {
defvars[x] = Blockly.Python.variableDB_.getName(variables[x], defvars[x] = Blockly.Python.variableDB_.getName(variables[x],
Blockly.Variables.NAME_TYPE) + ' = None'; Blockly.Variables.NAME_TYPE) + ' = None';
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment