Commit 4ccbeea4 authored by Evan W. Patton's avatar Evan W. Patton

Implement menu option to make component blocks generic

Change-Id: I62ae3fed73342a5f6cb7652903a09e4dd9c6d620
parent 4ddd02db
...@@ -144,3 +144,35 @@ Blockly.Block.prototype.isolate = function(healStack) { ...@@ -144,3 +144,35 @@ Blockly.Block.prototype.isolate = function(healStack) {
Blockly.Block.prototype.interpolateMsg.SPLIT_REGEX_ = /(%\d+|\n)/; Blockly.Block.prototype.interpolateMsg.SPLIT_REGEX_ = /(%\d+|\n)/;
Blockly.Block.prototype.interpolateMsg.INLINE_REGEX_ = /%1\s*$/; Blockly.Block.prototype.interpolateMsg.INLINE_REGEX_ = /%1\s*$/;
/**
* Walk the tree of blocks starting with this block.
*
* @param {function(Blockly.Block, number)} callback the callback function to evaluate for each
* block. The function receives the block and the logical depth of the block in the tree.
*/
Blockly.Block.prototype.walk = function(callback) {
function doWalk(block, depth) {
callback(block, depth);
block.inputList.forEach(function(input) {
if ((input.type === Blockly.INPUT_VALUE || input.type === Blockly.NEXT_STATEMENT) &&
input.connection && input.connection.targetBlock()) {
doWalk(input.connection.targetBlock(), depth + 1);
}
if (block.nextConnection && block.nextConnection.targetBlock()) {
doWalk(block.nextConnection.targetBlock(), depth);
}
})
}
doWalk(this, 0);
};
/**
* @type {?function(this: Blockly.BlockSvg, !Element)}
*/
Blockly.Block.prototype.domToMutation = null;
/**
* @type {?function(this: Blockly.BlockSvg):!Element}
*/
Blockly.Block.prototype.mutationToDom = null;
...@@ -39,7 +39,160 @@ Blockly.ComponentBlock.COLOUR_COMPONENT = '#439970'; // [67, 153, 112] ...@@ -39,7 +39,160 @@ Blockly.ComponentBlock.COLOUR_COMPONENT = '#439970'; // [67, 153, 112]
Blockly.ComponentBlock.COMPONENT_SELECTOR = "COMPONENT_SELECTOR"; Blockly.ComponentBlock.COMPONENT_SELECTOR = "COMPONENT_SELECTOR";
//TODO(): add I18N /**
* Add a menu option to the context menu for {@code block} to swap between
* the generic and specific versions of the block.
*
* @param {Blockly.BlockSvg} block the block to manipulate
* @param {Array.<{enabled,text,callback}>} options the menu options
*/
Blockly.ComponentBlock.addGenericOption = function(block, options) {
if (block.type === 'component_event' && block.isGeneric) {
return; // Cannot make a generic component_event specific for now...
}
/**
* Helper function used to make component blocks generic.
*
* @param {Blockly.BlockSvg} block the block to be made generic
* @param {(!Element|boolean)=} opt_replacementDom DOM tree for a replacement block to use in the
* substitution, false if no substitution should be made, or undefined if the substitution should
* be inferred.
*/
function makeGeneric(block, opt_replacementDom) {
var instanceName = block.instanceName;
var mutation = block.mutationToDom();
var oldMutation = Blockly.Xml.domToText(mutation);
mutation.setAttribute('is_generic', 'true');
mutation.removeAttribute('instance_name');
var newMutation = Blockly.Xml.domToText(mutation);
block.domToMutation(mutation);
block.initSvg(); // block shape may have changed
block.render();
Blockly.Events.fire(new Blockly.Events.Change(
block, 'mutation', null, oldMutation, newMutation));
if (block.type === 'component_event') opt_replacementDom = false;
if (opt_replacementDom !== false) {
if (opt_replacementDom === undefined) {
var compBlockXml = '<xml><block type="component_component_block">' +
'<mutation component_type="' + block.typeName + '" instance_name="' + instanceName + '"></mutation>' +
'<field name="COMPONENT_SELECTOR">' + instanceName + '</field>' +
'</block></xml>';
opt_replacementDom = Blockly.Xml.textToDom(compBlockXml).firstElementChild;
}
var replacement = Blockly.Xml.domToBlock(opt_replacementDom, block.workspace);
replacement.initSvg();
block.getInput('COMPONENT').connection.connect(replacement.outputConnection);
}
var group = Blockly.Events.getGroup();
setTimeout(function() {
Blockly.Events.setGroup(group);
// noinspection JSAccessibilityCheck
block.bumpNeighbours_();
Blockly.Events.setGroup(false);
}, Blockly.BUMP_DELAY);
}
var item = { enabled: false };
if (block.isGeneric) {
var compBlock = block.getInputTargetBlock('COMPONENT');
item.enabled = compBlock && compBlock.type === 'component_component_block';
item.text = Blockly.Msg.UNGENERICIZE_BLOCK;
item.callback = function () {
try {
Blockly.Events.setGroup(true);
var instanceName = compBlock.instanceName;
compBlock.dispose(true);
var mutation = block.mutationToDom();
var oldMutation = Blockly.Xml.domToText(mutation);
mutation.setAttribute('instance_name', instanceName);
mutation.setAttribute('is_generic', 'false');
var newMutation = Blockly.Xml.domToText(mutation);
block.domToMutation(mutation);
block.initSvg(); // block shape may have changed
block.render();
Blockly.Events.fire(new Blockly.Events.Change(
block, 'mutation', null, oldMutation, newMutation));
var group = Blockly.Events.getGroup();
setTimeout(function () {
Blockly.Events.setGroup(group);
// noinspection JSAccessibilityCheck
block.bumpNeighbours_();
Blockly.Events.setGroup(false);
}, Blockly.BUMP_DELAY);
} finally {
Blockly.Events.setGroup(false);
}
};
} else if (block.type === 'component_event') {
item.enabled = true;
item.text = Blockly.Msg.GENERICIZE_BLOCK;
item.callback = function() {
try {
Blockly.Events.setGroup(true);
var instanceName = block.instanceName;
var intlName = block.workspace.getComponentDatabase()
.getInternationalizedParameterName('component');
// Aggregate variables in scope
var namesInScope = {}, maxNum = 0;
var regex = new RegExp('^' + intlName + '([0-9]+)$');
var varDeclsWithIntlName = [];
block.walk(function(block) {
if (block.type === 'local_declaration_statement' ||
block.type === 'local_declaration_expression') {
var localNames = block.getVars();
localNames.forEach(function(varname) {
namesInScope[varname] = true;
var match = varname.match(regex);
if (match) {
maxNum = Math.max(maxNum, parseInt(match[1]));
}
if (varname === intlName) {
varDeclsWithIntlName.push(block);
}
});
}
});
// Rename local variable definition of i18n(component) to prevent
// variable capture
if (intlName in namesInScope) {
varDeclsWithIntlName.forEach(function(block) {
Blockly.LexicalVariable.renameParamFromTo(block, intlName, intlName + (maxNum + 1).toString(), true);
});
}
// Make generic the block and any descendants of the same component instance
var varBlockXml = '<xml><block type="lexical_variable_get">' +
'<mutation><eventparam name="component"></eventparam></mutation>' +
'<field name="VAR">' + intlName + '</field></block></xml>';
var varBlockDom = Blockly.Xml.textToDom(varBlockXml).firstElementChild;
makeGeneric(block); // Do this first so 'component' is defined.
block.walk(function(block) {
if ((block.type === 'component_method' || block.type === 'component_set_get') &&
block.instanceName === instanceName) {
makeGeneric(/** @type Blockly.BlockSvg */ block, varBlockDom);
}
});
} finally {
Blockly.Events.setGroup(false);
}
};
} else {
item.enabled = true;
item.text = Blockly.Msg.GENERICIZE_BLOCK;
item.callback = function() {
try {
Blockly.Events.setGroup(true);
makeGeneric(block);
} finally {
Blockly.Events.setGroup(false);
}
};
}
options.splice(options.length - 1, 0, item);
};
/** /**
* Create an event block of the given type for a component with the given * Create an event block of the given type for a component with the given
...@@ -52,6 +205,10 @@ Blockly.Blocks.component_event = { ...@@ -52,6 +205,10 @@ Blockly.Blocks.component_event = {
category : 'Component', category : 'Component',
blockType : 'event', blockType : 'event',
init: function() {
this.componentDropDown = Blockly.ComponentBlock.createComponentDropDown(this);
},
mutationToDom : function() { mutationToDom : function() {
var container = document.createElement('mutation'); var container = document.createElement('mutation');
...@@ -70,21 +227,37 @@ Blockly.Blocks.component_event = { ...@@ -70,21 +227,37 @@ Blockly.Blocks.component_event = {
}, },
domToMutation : function(xmlElement) { domToMutation : function(xmlElement) {
var oldRendered = this.rendered;
this.rendered = false;
var oldDo = null;
for (var i = 0, input; input = this.inputList[i]; i++) {
if (input.connection) {
if (input.name === 'DO') {
oldDo = input.connection.targetBlock();
}
var block = input.connection.targetBlock();
if (block) {
block.unplug();
}
}
input.dispose();
}
this.inputList.length = 0;
this.typeName = xmlElement.getAttribute('component_type'); this.typeName = xmlElement.getAttribute('component_type');
this.eventName = xmlElement.getAttribute('event_name');
this.isGeneric = xmlElement.getAttribute('is_generic') == 'true'; this.isGeneric = xmlElement.getAttribute('is_generic') == 'true';
if (!this.isGeneric) { if (!this.isGeneric) {
this.instanceName = xmlElement.getAttribute('instance_name');//instance name not needed this.instanceName = xmlElement.getAttribute('instance_name');//instance name not needed
} else {
delete this.instanceName;
} }
this.eventName = xmlElement.getAttribute('event_name'); // Orient parameters horizontally by default
var horizParams = xmlElement.getAttribute('vertical_parameters') !== "true"; var horizParams = xmlElement.getAttribute('vertical_parameters') !== "true";
// Orient parameters horizontally by default
this.setColour(Blockly.ComponentBlock.COLOUR_EVENT); this.setColour(Blockly.ComponentBlock.COLOUR_EVENT);
this.componentDropDown = Blockly.ComponentBlock.createComponentDropDown(this);
var localizedEventName; var localizedEventName;
var eventType = this.getEventTypeObject(); var eventType = this.getEventTypeObject();
var componentDb = this.getTopWorkspace().getComponentDatabase(); var componentDb = this.getTopWorkspace().getComponentDatabase();
...@@ -116,6 +289,14 @@ Blockly.Blocks.component_event = { ...@@ -116,6 +289,14 @@ Blockly.Blocks.component_event = {
this.setPreviousStatement(false, null); this.setPreviousStatement(false, null);
this.setNextStatement(false, null); this.setNextStatement(false, null);
if (oldDo) {
this.getInput('DO').connection.connect(oldDo.previousConnection);
}
for (var i = 0, input; input = this.inputList[i]; i++) {
input.init();
}
if (eventType && eventType.deprecated === "true" && this.workspace === Blockly.mainWorkspace) { if (eventType && eventType.deprecated === "true" && this.workspace === Blockly.mainWorkspace) {
this.badBlock(); this.badBlock();
this.setDisabled(true); this.setDisabled(true);
...@@ -123,6 +304,7 @@ Blockly.Blocks.component_event = { ...@@ -123,6 +304,7 @@ Blockly.Blocks.component_event = {
this.verify(); // verify the block and mark it accordingly this.verify(); // verify the block and mark it accordingly
this.rendered = oldRendered;
}, },
// [lyn, 10/24/13] Allow switching between horizontal and vertical display of arguments // [lyn, 10/24/13] Allow switching between horizontal and vertical display of arguments
// Also must create flydown params and DO input if they don't exist. // Also must create flydown params and DO input if they don't exist.
...@@ -316,6 +498,7 @@ Blockly.Blocks.component_event = { ...@@ -316,6 +498,7 @@ Blockly.Blocks.component_event = {
}, },
customContextMenu: function (options) { customContextMenu: function (options) {
Blockly.FieldParameterFlydown.addHorizontalVerticalOption(this, options); Blockly.FieldParameterFlydown.addHorizontalVerticalOption(this, options);
Blockly.ComponentBlock.addGenericOption(this, options);
}, },
// check if the block corresponds to an event inside componentTypes[typeName].eventDictionary // check if the block corresponds to an event inside componentTypes[typeName].eventDictionary
...@@ -418,6 +601,22 @@ Blockly.Blocks.component_method = { ...@@ -418,6 +601,22 @@ Blockly.Blocks.component_method = {
}, },
domToMutation : function(xmlElement) { domToMutation : function(xmlElement) {
var oldRendered = this.rendered;
this.rendered = false;
var oldInputValues = [];
for (var i = 0, input; input = this.inputList[i]; i++) {
if (input.connection) {
var block = input.connection.targetBlock();
if (block) {
block.unplug();
}
oldInputValues.push(block);
} else {
oldInputValues.push(null);
}
input.dispose();
}
this.inputList.length = 0;
this.typeName = xmlElement.getAttribute('component_type'); this.typeName = xmlElement.getAttribute('component_type');
this.methodName = xmlElement.getAttribute('method_name'); this.methodName = xmlElement.getAttribute('method_name');
...@@ -425,6 +624,8 @@ Blockly.Blocks.component_method = { ...@@ -425,6 +624,8 @@ Blockly.Blocks.component_method = {
this.isGeneric = isGenericString == 'true'; this.isGeneric = isGenericString == 'true';
if(!this.isGeneric) { if(!this.isGeneric) {
this.instanceName = xmlElement.getAttribute('instance_name');//instance name not needed this.instanceName = xmlElement.getAttribute('instance_name');//instance name not needed
} else {
delete this.instanceName;
} }
this.setColour(Blockly.ComponentBlock.COLOUR_METHOD); this.setColour(Blockly.ComponentBlock.COLOUR_METHOD);
...@@ -504,11 +705,19 @@ Blockly.Blocks.component_method = { ...@@ -504,11 +705,19 @@ Blockly.Blocks.component_method = {
if (methodTypeObject) { if (methodTypeObject) {
params = methodTypeObject.parameters; params = methodTypeObject.parameters;
} }
oldInputValues.splice(0, oldInputValues.length - params.length);
for (var i = 0, param; param = params[i]; i++) { for (var i = 0, param; param = params[i]; i++) {
var newInput = this.appendValueInput("ARG" + i).appendField(componentDb.getInternationalizedParameterName(param.name)); var newInput = this.appendValueInput("ARG" + i).appendField(componentDb.getInternationalizedParameterName(param.name));
newInput.setAlign(Blockly.ALIGN_RIGHT); newInput.setAlign(Blockly.ALIGN_RIGHT);
var blockyType = Blockly.Blocks.Utilities.YailTypeToBlocklyType(param.type,Blockly.Blocks.Utilities.INPUT); var blockyType = Blockly.Blocks.Utilities.YailTypeToBlocklyType(param.type,Blockly.Blocks.Utilities.INPUT);
newInput.connection.setCheck(blockyType); newInput.connection.setCheck(blockyType);
if (oldInputValues[i] && newInput.connection) {
Blockly.Mutator.reconnect(oldInputValues[i].outputConnection, this, 'ARG' + i);
}
}
for (var i = 0, input; input = this.inputList[i]; i++) {
input.init();
} }
if (!methodTypeObject) { if (!methodTypeObject) {
...@@ -534,6 +743,8 @@ Blockly.Blocks.component_method = { ...@@ -534,6 +743,8 @@ Blockly.Blocks.component_method = {
} }
this.verify(); // verify the block and mark it accordingly this.verify(); // verify the block and mark it accordingly
this.rendered = oldRendered;
}, },
// Rename the block's instanceName, type, and reset its title // Rename the block's instanceName, type, and reset its title
rename : function(oldname, newname) { rename : function(oldname, newname) {
...@@ -691,6 +902,11 @@ Blockly.Blocks.component_method = { ...@@ -691,6 +902,11 @@ Blockly.Blocks.component_method = {
} else { } else {
this.badBlock(); this.badBlock();
} }
},
customContextMenu: function(options) {
Blockly.ComponentBlock.addGenericOption(this, options);
Blockly.Block.prototype.customContextMenu.call(this, options);
} }
}; };
...@@ -711,6 +927,10 @@ Blockly.Blocks.component_set_get = { ...@@ -711,6 +927,10 @@ Blockly.Blocks.component_set_get = {
return Blockly.ComponentBlock.PROPERTIES_HELPURLS[mode]; return Blockly.ComponentBlock.PROPERTIES_HELPURLS[mode];
}, },
init: function() {
this.componentDropDown = Blockly.ComponentBlock.createComponentDropDown(this);
},
mutationToDom : function() { mutationToDom : function() {
var container = document.createElement('mutation'); var container = document.createElement('mutation');
...@@ -729,6 +949,23 @@ Blockly.Blocks.component_set_get = { ...@@ -729,6 +949,23 @@ Blockly.Blocks.component_set_get = {
}, },
domToMutation : function(xmlElement) { domToMutation : function(xmlElement) {
var oldRendered = this.rendered;
this.rendered = false;
var oldInput = this.setOrGet == "set" && this.getInputTargetBlock('VALUE');
for (var i = 0, input; input = this.inputList[i]; i++) {
if (input.connection) {
var block = input.connection.targetBlock();
if (block) {
if (block.isShadow()) {
block.dispose();
} else {
block.unplug();
}
}
}
input.dispose();
}
this.inputList.length = 0;
var componentDb = this.getTopWorkspace().getComponentDatabase(); var componentDb = this.getTopWorkspace().getComponentDatabase();
this.typeName = xmlElement.getAttribute('component_type'); this.typeName = xmlElement.getAttribute('component_type');
this.setOrGet = xmlElement.getAttribute('set_or_get'); this.setOrGet = xmlElement.getAttribute('set_or_get');
...@@ -738,6 +975,8 @@ Blockly.Blocks.component_set_get = { ...@@ -738,6 +975,8 @@ Blockly.Blocks.component_set_get = {
this.isGeneric = isGenericString == "true"; this.isGeneric = isGenericString == "true";
if(!this.isGeneric) { if(!this.isGeneric) {
this.instanceName = xmlElement.getAttribute('instance_name');//instance name not needed this.instanceName = xmlElement.getAttribute('instance_name');//instance name not needed
} else {
delete this.instanceName;
} }
if(this.setOrGet == "set"){ if(this.setOrGet == "set"){
this.setColour(Blockly.ComponentBlock.COLOUR_SET); this.setColour(Blockly.ComponentBlock.COLOUR_SET);
...@@ -769,8 +1008,6 @@ Blockly.Blocks.component_set_get = { ...@@ -769,8 +1008,6 @@ Blockly.Blocks.component_set_get = {
} }
); );
this.componentDropDown = Blockly.ComponentBlock.createComponentDropDown(this);
if(this.setOrGet == "get") { if(this.setOrGet == "get") {
//add output plug for get blocks //add output plug for get blocks
this.setOutput(true); this.setOutput(true);
...@@ -821,6 +1058,11 @@ Blockly.Blocks.component_set_get = { ...@@ -821,6 +1058,11 @@ Blockly.Blocks.component_set_get = {
} }
} }
if (oldInput) {
this.getInput('VALUE').init();
Blockly.Mutator.reconnect(oldInput.outputConnection, this, 'VALUE');
}
//for non-generic blocks, set the value of the component drop down //for non-generic blocks, set the value of the component drop down
if(!this.isGeneric) { if(!this.isGeneric) {
this.componentDropDown.setValue(this.instanceName); this.componentDropDown.setValue(this.instanceName);
...@@ -843,6 +1085,11 @@ Blockly.Blocks.component_set_get = { ...@@ -843,6 +1085,11 @@ Blockly.Blocks.component_set_get = {
this.verify(); this.verify();
for (var i = 0, input; input = this.inputList[i]; i++) {
input.init();
}
this.rendered = oldRendered;
}, },
setTypeCheck : function() { setTypeCheck : function() {
...@@ -995,7 +1242,13 @@ Blockly.Blocks.component_set_get = { ...@@ -995,7 +1242,13 @@ Blockly.Blocks.component_set_get = {
this.badBlock(true); this.badBlock(true);
} }
},
customContextMenu: function(options) {
Blockly.ComponentBlock.addGenericOption(this, options);
Blockly.Block.prototype.customContextMenu.call(this, options);
} }
}; };
/** /**
......
...@@ -340,6 +340,7 @@ Blockly.Blocks['local_declaration_statement'] = { ...@@ -340,6 +340,7 @@ Blockly.Blocks['local_declaration_statement'] = {
this.rendered = savedRendered; this.rendered = savedRendered;
if (this.rendered) { if (this.rendered) {
this.initSvg();
this.render(); this.render();
} }
}, },
...@@ -487,7 +488,7 @@ Blockly.Blocks['local_declaration_statement'] = { ...@@ -487,7 +488,7 @@ Blockly.Blocks['local_declaration_statement'] = {
for (var x = 0, block; block = blocks[x]; x++) { for (var x = 0, block; block = blocks[x]; x++) {
if (block.type == 'procedures_mutatorarg') { if (block.type == 'procedures_mutatorarg') {
var oldName = block.getFieldValue('NAME'); var oldName = block.getFieldValue('NAME');
var newName = substitution.appy(oldName); var newName = substitution.apply(oldName);
if (newName !== oldName) { if (newName !== oldName) {
block.setFieldValue(newName, 'NAME'); block.setFieldValue(newName, 'NAME');
} }
...@@ -497,6 +498,7 @@ Blockly.Blocks['local_declaration_statement'] = { ...@@ -497,6 +498,7 @@ Blockly.Blocks['local_declaration_statement'] = {
} }
}, },
renameBound: function (boundSubstitution, freeSubstitution) { renameBound: function (boundSubstitution, freeSubstitution) {
var oldMutation = Blockly.Xml.domToText(this.mutationToDom());
var localNames = this.declaredNames(); var localNames = this.declaredNames();
for (var i = 0; i < localNames.length; i++) { for (var i = 0; i < localNames.length; i++) {
// This is LET semantics, not LET* semantics, and needs to change! // This is LET semantics, not LET* semantics, and needs to change!
...@@ -506,6 +508,10 @@ Blockly.Blocks['local_declaration_statement'] = { ...@@ -506,6 +508,10 @@ Blockly.Blocks['local_declaration_statement'] = {
this.renameVars(paramSubstitution); this.renameVars(paramSubstitution);
var newFreeSubstitution = freeSubstitution.remove(localNames).extend(paramSubstitution); var newFreeSubstitution = freeSubstitution.remove(localNames).extend(paramSubstitution);
Blockly.LexicalVariable.renameFree(this.getInputTargetBlock(this.bodyInputName), newFreeSubstitution); Blockly.LexicalVariable.renameFree(this.getInputTargetBlock(this.bodyInputName), newFreeSubstitution);
var newMutation = Blockly.Xml.domToText(this.mutationToDom());
if (Blockly.Events.isEnabled()) {
Blockly.Events.fire(new Blockly.Events.Change(this, 'mutation', null, oldMutation, newMutation));
}
if (this.nextConnection) { if (this.nextConnection) {
var nextBlock = this.nextConnection.targetBlock(); var nextBlock = this.nextConnection.targetBlock();
Blockly.LexicalVariable.renameFree(nextBlock, freeSubstitution); Blockly.LexicalVariable.renameFree(nextBlock, freeSubstitution);
...@@ -549,7 +555,6 @@ Blockly.Blocks['local_declaration_statement'] = { ...@@ -549,7 +555,6 @@ Blockly.Blocks['local_declaration_statement'] = {
} }
return result; return result;
}, },
//TODO (user) this has not been internationalized yet
typeblock: [{ translatedName: Blockly.Msg.LANG_VARIABLES_LOCAL_DECLARATION_TRANSLATED_NAME }] typeblock: [{ translatedName: Blockly.Msg.LANG_VARIABLES_LOCAL_DECLARATION_TRANSLATED_NAME }]
}; };
...@@ -583,12 +588,11 @@ Blockly.Blocks['local_declaration_expression'] = { ...@@ -583,12 +588,11 @@ Blockly.Blocks['local_declaration_expression'] = {
saveConnections: Blockly.Blocks.local_declaration_statement.saveConnections, saveConnections: Blockly.Blocks.local_declaration_statement.saveConnections,
getVars: Blockly.Blocks.local_declaration_statement.getVars, getVars: Blockly.Blocks.local_declaration_statement.getVars,
declaredNames: Blockly.Blocks.local_declaration_statement.declaredNames, declaredNames: Blockly.Blocks.local_declaration_statement.declaredNames,
renameVar: Blockly.Blocks.local_declaration_statement.renameVars, renameVar: Blockly.Blocks.local_declaration_statement.renameVar,
renameVars: Blockly.Blocks.local_declaration_statement.renameVar, renameVars: Blockly.Blocks.local_declaration_statement.renameVars,
renameBound: Blockly.Blocks.local_declaration_statement.renameBound, renameBound: Blockly.Blocks.local_declaration_statement.renameBound,
renameFree: Blockly.Blocks.local_declaration_statement.renameFree, renameFree: Blockly.Blocks.local_declaration_statement.renameFree,
freeVariables: Blockly.Blocks.local_declaration_statement.freeVariables, freeVariables: Blockly.Blocks.local_declaration_statement.freeVariables,
//TODO (user) this has not been internationalized yet
typeblock: [{ translatedName: Blockly.Msg.LANG_VARIABLES_LOCAL_DECLARATION_EXPRESSION_TRANSLATED_NAME }] typeblock: [{ translatedName: Blockly.Msg.LANG_VARIABLES_LOCAL_DECLARATION_EXPRESSION_TRANSLATED_NAME }]
}; };
......
...@@ -92,6 +92,8 @@ Blockly.Msg.en.switch_language_to_english = { ...@@ -92,6 +92,8 @@ Blockly.Msg.en.switch_language_to_english = {
Blockly.Msg.ENABLE_ALL_BLOCKS = 'Enable All Blocks'; Blockly.Msg.ENABLE_ALL_BLOCKS = 'Enable All Blocks';
Blockly.Msg.HIDE_ALL_COMMENTS = 'Hide All Comments'; Blockly.Msg.HIDE_ALL_COMMENTS = 'Hide All Comments';
Blockly.Msg.SHOW_ALL_COMMENTS = 'Show All Comments'; Blockly.Msg.SHOW_ALL_COMMENTS = 'Show All Comments';
Blockly.Msg.GENERICIZE_BLOCK = 'Make Generic';
Blockly.Msg.UNGENERICIZE_BLOCK = 'Make Specific';
// Variable renaming. // Variable renaming.
Blockly.Msg.CHANGE_VALUE_TITLE = 'Change value:'; Blockly.Msg.CHANGE_VALUE_TITLE = 'Change value:';
......
Subproject commit c5ead64c2b930e0794031ea999df9dca62bcf0e1 Subproject commit 174cda1495a5302037029c6ca79bf1d86b4936fe
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