Merge pull request #1531 from google/variables_by_id

Variables by ID
This commit is contained in:
Rachel Fenichel
2018-01-16 17:54:55 -08:00
committed by GitHub
42 changed files with 2455 additions and 1830 deletions

View File

@@ -59,6 +59,7 @@ Blockly.Blocks['procedures_defnoreturn'] = {
this.setTooltip(Blockly.Msg.PROCEDURES_DEFNORETURN_TOOLTIP);
this.setHelpUrl(Blockly.Msg.PROCEDURES_DEFNORETURN_HELPURL);
this.arguments_ = [];
this.argumentVarModels_ = [];
this.setStatements_(true);
this.statementConnection_ = null;
},
@@ -153,9 +154,14 @@ Blockly.Blocks['procedures_defnoreturn'] = {
*/
domToMutation: function(xmlElement) {
this.arguments_ = [];
this.argumentVarModels_ = [];
for (var i = 0, childNode; childNode = xmlElement.childNodes[i]; i++) {
if (childNode.nodeName.toLowerCase() == 'arg') {
this.arguments_.push(childNode.getAttribute('name'));
var varName = childNode.getAttribute('name');
this.arguments_.push(varName);
var variable = Blockly.Variables.getOrCreateVariablePackage(
this.workspace, null, varName, '');
this.argumentVarModels_.push(variable);
}
}
this.updateParams_();
@@ -206,9 +212,14 @@ Blockly.Blocks['procedures_defnoreturn'] = {
// Parameter list.
this.arguments_ = [];
this.paramIds_ = [];
this.argumentVarModels_ = [];
var paramBlock = containerBlock.getInputTargetBlock('STACK');
while (paramBlock) {
this.arguments_.push(paramBlock.getFieldValue('NAME'));
var varName = paramBlock.getFieldValue('NAME');
this.arguments_.push(varName);
var variable = Blockly.Variables.getOrCreateVariablePackage(
this.workspace, null, varName, '');
this.argumentVarModels_.push(variable);
this.paramIds_.push(paramBlock.id);
paramBlock = paramBlock.nextConnection &&
paramBlock.nextConnection.targetBlock();
@@ -260,30 +271,78 @@ Blockly.Blocks['procedures_defnoreturn'] = {
return this.arguments_;
},
/**
* Notification that a variable is renaming.
* If the name matches one of this block's variables, rename it.
* @param {string} oldName Previous name of variable.
* @param {string} newName Renamed variable.
* Return all variables referenced by this block.
* @return {!Array.<!Blockly.VariableModel>} List of variable models.
* @this Blockly.Block
*/
renameVar: function(oldName, newName) {
getVarModels: function() {
return this.argumentVarModels_;
},
/**
* Notification that a variable is renaming.
* If the ID matches one of this block's variables, rename it.
* @param {string} oldId ID of variable to rename.
* @param {string} newId ID of new variable. May be the same as oldId, but
* with an updated name. Guaranteed to be the same type as the old
* variable.
* @this Blockly.Block
*/
renameVarById: function(oldId, newId) {
var oldVariable = this.workspace.getVariableById(oldId);
if (oldVariable.type != '') {
// Procedure arguments always have the empty type.
return;
}
var oldName = oldVariable.name;
var newVar = this.workspace.getVariableById(newId);
var change = false;
for (var i = 0; i < this.arguments_.length; i++) {
if (Blockly.Names.equals(oldName, this.arguments_[i])) {
for (var i = 0; i < this.argumentVarModels_.length; i++) {
if (this.argumentVarModels_[i].getId() == oldId) {
this.arguments_[i] = newVar.name;
this.argumentVarModels_[i] = newVar;
change = true;
}
}
if (change) {
this.displayRenamedVar_(oldName, newVar.name);
}
},
/**
* Notification that a variable is renaming but keeping the same ID. If the
* variable is in use on this block, rerender to show the new name.
* @param {!Blockly.VariableModel} variable The variable being renamed.
* @package
*/
updateVarName: function(variable) {
var newName = variable.name;
var change = false;
for (var i = 0; i < this.argumentVarModels_.length; i++) {
if (this.argumentVarModels_[i].getId() == variable.getId()) {
var oldName = this.arguments_[i];
this.arguments_[i] = newName;
change = true;
}
}
if (change) {
this.updateParams_();
// Update the mutator's variables if the mutator is open.
if (this.mutator.isVisible()) {
var blocks = this.mutator.workspace_.getAllBlocks();
for (var i = 0, block; block = blocks[i]; i++) {
if (block.type == 'procedures_mutatorarg' &&
Blockly.Names.equals(oldName, block.getFieldValue('NAME'))) {
block.setFieldValue(newName, 'NAME');
}
this.displayRenamedVar_(oldName, newName);
}
},
/**
* Update the display to reflect a newly renamed argument.
* @param {string} oldName The old display name of the argument.
* @param {string} newName The new display name of the argument.
* @private
*/
displayRenamedVar_: function(oldName, newName) {
this.updateParams_();
// Update the mutator's variables if the mutator is open.
if (this.mutator.isVisible()) {
var blocks = this.mutator.workspace_.getAllBlocks();
for (var i = 0, block; block = blocks[i]; i++) {
if (block.type == 'procedures_mutatorarg' &&
Blockly.Names.equals(oldName, block.getFieldValue('NAME'))) {
block.setFieldValue(newName, 'NAME');
}
}
}
@@ -355,6 +414,7 @@ Blockly.Blocks['procedures_defreturn'] = {
this.setTooltip(Blockly.Msg.PROCEDURES_DEFRETURN_TOOLTIP);
this.setHelpUrl(Blockly.Msg.PROCEDURES_DEFRETURN_HELPURL);
this.arguments_ = [];
this.argumentVarModels_ = [];
this.setStatements_(true);
this.statementConnection_ = null;
},
@@ -376,7 +436,10 @@ Blockly.Blocks['procedures_defreturn'] = {
return [this.getFieldValue('NAME'), this.arguments_, true];
},
getVars: Blockly.Blocks['procedures_defnoreturn'].getVars,
renameVar: Blockly.Blocks['procedures_defnoreturn'].renameVar,
getVarModels: Blockly.Blocks['procedures_defnoreturn'].getVarModels,
renameVarById: Blockly.Blocks['procedures_defnoreturn'].renameVarById,
updateVarName: Blockly.Blocks['procedures_defnoreturn'].updateVarName,
displayRenamedVar_: Blockly.Blocks['procedures_defnoreturn'].displayRenamedVar_,
customContextMenu: Blockly.Blocks['procedures_defnoreturn'].customContextMenu,
callType_: 'procedures_callreturn'
};
@@ -445,12 +508,13 @@ Blockly.Blocks['procedures_mutatorarg'] = {
if (source && source.workspace && source.workspace.options &&
source.workspace.options.parentWorkspace) {
var workspace = source.workspace.options.parentWorkspace;
var variable = workspace.getVariable(newText);
var variableType = '';
var variable = workspace.getVariable(newText, variableType);
// If there is a case change, rename the variable.
if (variable && variable.name !== newText) {
workspace.renameVariableById(variable.getId(), newText);
} else {
workspace.createVariable(newText);
workspace.createVariable(newText, variableType);
}
}
}
@@ -470,6 +534,7 @@ Blockly.Blocks['procedures_callnoreturn'] = {
// Tooltip is set in renameProcedure.
this.setHelpUrl(Blockly.Msg.PROCEDURES_CALLNORETURN_HELPURL);
this.arguments_ = [];
this.argumentVarModels_ = [];
this.quarkConnections_ = {};
this.quarkIds_ = null;
},
@@ -568,6 +633,14 @@ Blockly.Blocks['procedures_callnoreturn'] = {
}
// Rebuild the block's arguments.
this.arguments_ = [].concat(paramNames);
// And rebuild the argument model list.
this.argumentVarModels_ = [];
for (var i = 0; i < this.arguments_.length; i++) {
var variable = Blockly.Variables.getOrCreateVariablePackage(
this.workspace, null, this.arguments_[i], '');
this.argumentVarModels_.push(variable);
}
this.updateShape_();
this.quarkIds_ = paramIds;
// Reconnect any child blocks.
@@ -670,19 +743,12 @@ Blockly.Blocks['procedures_callnoreturn'] = {
this.setProcedureParameters_(args, paramIds);
},
/**
* Notification that a variable is renaming.
* If the name matches one of this block's variables, rename it.
* @param {string} oldName Previous name of variable.
* @param {string} newName Renamed variable.
* Return all variables referenced by this block.
* @return {!Array.<!Blockly.VariableModel>} List of variable models.
* @this Blockly.Block
*/
renameVar: function(oldName, newName) {
for (var i = 0; i < this.arguments_.length; i++) {
if (Blockly.Names.equals(oldName, this.arguments_[i])) {
this.arguments_[i] = newName;
this.getField('ARGNAME' + i).setValue(newName);
}
}
getVarModels: function() {
return this.argumentVarModels_;
},
/**
* Procedure calls cannot exist without the corresponding procedure
@@ -793,7 +859,7 @@ Blockly.Blocks['procedures_callreturn'] = {
updateShape_: Blockly.Blocks['procedures_callnoreturn'].updateShape_,
mutationToDom: Blockly.Blocks['procedures_callnoreturn'].mutationToDom,
domToMutation: Blockly.Blocks['procedures_callnoreturn'].domToMutation,
renameVar: Blockly.Blocks['procedures_callnoreturn'].renameVar,
getVarModels: Blockly.Blocks['procedures_callnoreturn'].getVarModels,
onchange: Blockly.Blocks['procedures_callnoreturn'].onchange,
customContextMenu:
Blockly.Blocks['procedures_callnoreturn'].customContextMenu,

View File

@@ -124,8 +124,8 @@ Blockly.Constants.VariablesDynamic.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MI
options.push(option);
},
onchange: function() {
var name = this.getFieldValue('VAR');
var variableModel = this.workspace.getVariable(name);
var id = this.getFieldValue('VAR');
var variableModel = this.workspace.getVariableById(id);
if (this.type == 'variables_get_dynamic') {
this.outputConnection.setCheck(variableModel.type);
} else {