mirror of
https://github.com/google/blockly.git
synced 2026-01-04 15:40:08 +01:00
fix: Don't create intermediate variables when renaming a procedure argument. (#8723)
This commit is contained in:
@@ -629,30 +629,49 @@ type ArgumentBlock = Block & ArgumentMixin;
|
|||||||
interface ArgumentMixin extends ArgumentMixinType {}
|
interface ArgumentMixin extends ArgumentMixinType {}
|
||||||
type ArgumentMixinType = typeof PROCEDURES_MUTATORARGUMENT;
|
type ArgumentMixinType = typeof PROCEDURES_MUTATORARGUMENT;
|
||||||
|
|
||||||
// TODO(#6920): This is kludgy.
|
/**
|
||||||
type FieldTextInputForArgument = FieldTextInput & {
|
* Field responsible for editing procedure argument names.
|
||||||
oldShowEditorFn_(_e?: Event, quietInput?: boolean): void;
|
*/
|
||||||
createdVariables_: IVariableModel<IVariableState>[];
|
class ProcedureArgumentField extends FieldTextInput {
|
||||||
};
|
/**
|
||||||
|
* Whether or not this field is currently being edited interactively.
|
||||||
|
*/
|
||||||
|
editingInteractively = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The procedure argument variable whose name is being interactively edited.
|
||||||
|
*/
|
||||||
|
editingVariable?: IVariableModel<IVariableState>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays the field editor.
|
||||||
|
*
|
||||||
|
* @param e The event that triggered display of the field editor.
|
||||||
|
*/
|
||||||
|
protected override showEditor_(e?: Event) {
|
||||||
|
super.showEditor_(e);
|
||||||
|
this.editingInteractively = true;
|
||||||
|
this.editingVariable = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles cleanup when the field editor is dismissed.
|
||||||
|
*/
|
||||||
|
override onFinishEditing_(value: string) {
|
||||||
|
super.onFinishEditing_(value);
|
||||||
|
this.editingInteractively = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const PROCEDURES_MUTATORARGUMENT = {
|
const PROCEDURES_MUTATORARGUMENT = {
|
||||||
/**
|
/**
|
||||||
* Mutator block for procedure argument.
|
* Mutator block for procedure argument.
|
||||||
*/
|
*/
|
||||||
init: function (this: ArgumentBlock) {
|
init: function (this: ArgumentBlock) {
|
||||||
const field = fieldRegistry.fromJson({
|
const field = new ProcedureArgumentField(
|
||||||
type: 'field_input',
|
Procedures.DEFAULT_ARG,
|
||||||
text: Procedures.DEFAULT_ARG,
|
this.validator_,
|
||||||
}) as FieldTextInputForArgument;
|
);
|
||||||
field.setValidator(this.validator_);
|
|
||||||
// Hack: override showEditor to do just a little bit more work.
|
|
||||||
// We don't have a good place to hook into the start of a text edit.
|
|
||||||
field.oldShowEditorFn_ = (field as AnyDuringMigration).showEditor_;
|
|
||||||
const newShowEditorFn = function (this: typeof field) {
|
|
||||||
this.createdVariables_ = [];
|
|
||||||
this.oldShowEditorFn_();
|
|
||||||
};
|
|
||||||
(field as AnyDuringMigration).showEditor_ = newShowEditorFn;
|
|
||||||
|
|
||||||
this.appendDummyInput()
|
this.appendDummyInput()
|
||||||
.appendField(Msg['PROCEDURES_MUTATORARG_TITLE'])
|
.appendField(Msg['PROCEDURES_MUTATORARG_TITLE'])
|
||||||
@@ -662,14 +681,6 @@ const PROCEDURES_MUTATORARGUMENT = {
|
|||||||
this.setStyle('procedure_blocks');
|
this.setStyle('procedure_blocks');
|
||||||
this.setTooltip(Msg['PROCEDURES_MUTATORARG_TOOLTIP']);
|
this.setTooltip(Msg['PROCEDURES_MUTATORARG_TOOLTIP']);
|
||||||
this.contextMenu = false;
|
this.contextMenu = false;
|
||||||
|
|
||||||
// Create the default variable when we drag the block in from the flyout.
|
|
||||||
// Have to do this after installing the field on the block.
|
|
||||||
field.onFinishEditing_ = this.deleteIntermediateVars_;
|
|
||||||
// Create an empty list so onFinishEditing_ has something to look at, even
|
|
||||||
// though the editor was never opened.
|
|
||||||
field.createdVariables_ = [];
|
|
||||||
field.onFinishEditing_('x');
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -683,11 +694,11 @@ const PROCEDURES_MUTATORARGUMENT = {
|
|||||||
* @returns Valid name, or null if a name was not specified.
|
* @returns Valid name, or null if a name was not specified.
|
||||||
*/
|
*/
|
||||||
validator_: function (
|
validator_: function (
|
||||||
this: FieldTextInputForArgument,
|
this: ProcedureArgumentField,
|
||||||
varName: string,
|
varName: string,
|
||||||
): string | null {
|
): string | null {
|
||||||
const sourceBlock = this.getSourceBlock()!;
|
const sourceBlock = this.getSourceBlock()!;
|
||||||
const outerWs = sourceBlock!.workspace.getRootWorkspace()!;
|
const outerWs = sourceBlock.workspace.getRootWorkspace()!;
|
||||||
varName = varName.replace(/[\s\xa0]+/g, ' ').replace(/^ | $/g, '');
|
varName = varName.replace(/[\s\xa0]+/g, ' ').replace(/^ | $/g, '');
|
||||||
if (!varName) {
|
if (!varName) {
|
||||||
return null;
|
return null;
|
||||||
@@ -716,43 +727,24 @@ const PROCEDURES_MUTATORARGUMENT = {
|
|||||||
return varName;
|
return varName;
|
||||||
}
|
}
|
||||||
|
|
||||||
let model = outerWs.getVariable(varName, '');
|
const model = outerWs.getVariable(varName, '');
|
||||||
if (model && model.getName() !== varName) {
|
if (model && model.getName() !== varName) {
|
||||||
// Rename the variable (case change)
|
// Rename the variable (case change)
|
||||||
outerWs.renameVariableById(model.getId(), varName);
|
outerWs.renameVariableById(model.getId(), varName);
|
||||||
}
|
}
|
||||||
if (!model) {
|
if (!model) {
|
||||||
model = outerWs.createVariable(varName, '');
|
if (this.editingInteractively) {
|
||||||
if (model && this.createdVariables_) {
|
if (!this.editingVariable) {
|
||||||
this.createdVariables_.push(model);
|
this.editingVariable = outerWs.createVariable(varName, '');
|
||||||
|
} else {
|
||||||
|
outerWs.renameVariableById(this.editingVariable.getId(), varName);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
outerWs.createVariable(varName, '');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return varName;
|
return varName;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when focusing away from the text field.
|
|
||||||
* Deletes all variables that were created as the user typed their intended
|
|
||||||
* variable name.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
* @param newText The new variable name.
|
|
||||||
*/
|
|
||||||
deleteIntermediateVars_: function (
|
|
||||||
this: FieldTextInputForArgument,
|
|
||||||
newText: string,
|
|
||||||
) {
|
|
||||||
const outerWs = this.getSourceBlock()!.workspace.getRootWorkspace();
|
|
||||||
if (!outerWs) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (let i = 0; i < this.createdVariables_.length; i++) {
|
|
||||||
const model = this.createdVariables_[i];
|
|
||||||
if (model.getName() !== newText) {
|
|
||||||
outerWs.deleteVariableById(model.getId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
blocks['procedures_mutatorarg'] = PROCEDURES_MUTATORARGUMENT;
|
blocks['procedures_mutatorarg'] = PROCEDURES_MUTATORARGUMENT;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user