@@ -629,30 +629,49 @@ type ArgumentBlock = Block & ArgumentMixin;
629629interface ArgumentMixin extends ArgumentMixinType { }
630630type ArgumentMixinType = typeof PROCEDURES_MUTATORARGUMENT ;
631631
632- // TODO(#6920): This is kludgy.
633- type FieldTextInputForArgument = FieldTextInput & {
634- oldShowEditorFn_ ( _e ?: Event , quietInput ?: boolean ) : void ;
635- createdVariables_ : IVariableModel < IVariableState > [ ] ;
636- } ;
632+ /**
633+ * Field responsible for editing procedure argument names.
634+ */
635+ class ProcedureArgumentField extends FieldTextInput {
636+ /**
637+ * Whether or not this field is currently being edited interactively.
638+ */
639+ editingInteractively = false ;
640+
641+ /**
642+ * The procedure argument variable whose name is being interactively edited.
643+ */
644+ editingVariable ?: IVariableModel < IVariableState > ;
645+
646+ /**
647+ * Displays the field editor.
648+ *
649+ * @param e The event that triggered display of the field editor.
650+ */
651+ protected override showEditor_ ( e ?: Event ) {
652+ super . showEditor_ ( e ) ;
653+ this . editingInteractively = true ;
654+ this . editingVariable = undefined ;
655+ }
656+
657+ /**
658+ * Handles cleanup when the field editor is dismissed.
659+ */
660+ override onFinishEditing_ ( value : string ) {
661+ super . onFinishEditing_ ( value ) ;
662+ this . editingInteractively = false ;
663+ }
664+ }
637665
638666const PROCEDURES_MUTATORARGUMENT = {
639667 /**
640668 * Mutator block for procedure argument.
641669 */
642670 init : function ( this : ArgumentBlock ) {
643- const field = fieldRegistry . fromJson ( {
644- type : 'field_input' ,
645- text : Procedures . DEFAULT_ARG ,
646- } ) as FieldTextInputForArgument ;
647- field . setValidator ( this . validator_ ) ;
648- // Hack: override showEditor to do just a little bit more work.
649- // We don't have a good place to hook into the start of a text edit.
650- field . oldShowEditorFn_ = ( field as AnyDuringMigration ) . showEditor_ ;
651- const newShowEditorFn = function ( this : typeof field ) {
652- this . createdVariables_ = [ ] ;
653- this . oldShowEditorFn_ ( ) ;
654- } ;
655- ( field as AnyDuringMigration ) . showEditor_ = newShowEditorFn ;
671+ const field = new ProcedureArgumentField (
672+ Procedures . DEFAULT_ARG ,
673+ this . validator_ ,
674+ ) ;
656675
657676 this . appendDummyInput ( )
658677 . appendField ( Msg [ 'PROCEDURES_MUTATORARG_TITLE' ] )
@@ -662,14 +681,6 @@ const PROCEDURES_MUTATORARGUMENT = {
662681 this . setStyle ( 'procedure_blocks' ) ;
663682 this . setTooltip ( Msg [ 'PROCEDURES_MUTATORARG_TOOLTIP' ] ) ;
664683 this . contextMenu = false ;
665-
666- // Create the default variable when we drag the block in from the flyout.
667- // Have to do this after installing the field on the block.
668- field . onFinishEditing_ = this . deleteIntermediateVars_ ;
669- // Create an empty list so onFinishEditing_ has something to look at, even
670- // though the editor was never opened.
671- field . createdVariables_ = [ ] ;
672- field . onFinishEditing_ ( 'x' ) ;
673684 } ,
674685
675686 /**
@@ -683,11 +694,11 @@ const PROCEDURES_MUTATORARGUMENT = {
683694 * @returns Valid name, or null if a name was not specified.
684695 */
685696 validator_ : function (
686- this : FieldTextInputForArgument ,
697+ this : ProcedureArgumentField ,
687698 varName : string ,
688699 ) : string | null {
689700 const sourceBlock = this . getSourceBlock ( ) ! ;
690- const outerWs = sourceBlock ! . workspace . getRootWorkspace ( ) ! ;
701+ const outerWs = sourceBlock . workspace . getRootWorkspace ( ) ! ;
691702 varName = varName . replace ( / [ \s \xa0 ] + / g, ' ' ) . replace ( / ^ | $ / g, '' ) ;
692703 if ( ! varName ) {
693704 return null ;
@@ -716,43 +727,24 @@ const PROCEDURES_MUTATORARGUMENT = {
716727 return varName ;
717728 }
718729
719- let model = outerWs . getVariable ( varName , '' ) ;
730+ const model = outerWs . getVariable ( varName , '' ) ;
720731 if ( model && model . getName ( ) !== varName ) {
721732 // Rename the variable (case change)
722733 outerWs . renameVariableById ( model . getId ( ) , varName ) ;
723734 }
724735 if ( ! model ) {
725- model = outerWs . createVariable ( varName , '' ) ;
726- if ( model && this . createdVariables_ ) {
727- this . createdVariables_ . push ( model ) ;
736+ if ( this . editingInteractively ) {
737+ if ( ! this . editingVariable ) {
738+ this . editingVariable = outerWs . createVariable ( varName , '' ) ;
739+ } else {
740+ outerWs . renameVariableById ( this . editingVariable . getId ( ) , varName ) ;
741+ }
742+ } else {
743+ outerWs . createVariable ( varName , '' ) ;
728744 }
729745 }
730746 return varName ;
731747 } ,
732-
733- /**
734- * Called when focusing away from the text field.
735- * Deletes all variables that were created as the user typed their intended
736- * variable name.
737- *
738- * @internal
739- * @param newText The new variable name.
740- */
741- deleteIntermediateVars_ : function (
742- this : FieldTextInputForArgument ,
743- newText : string ,
744- ) {
745- const outerWs = this . getSourceBlock ( ) ! . workspace . getRootWorkspace ( ) ;
746- if ( ! outerWs ) {
747- return ;
748- }
749- for ( let i = 0 ; i < this . createdVariables_ . length ; i ++ ) {
750- const model = this . createdVariables_ [ i ] ;
751- if ( model . getName ( ) !== newText ) {
752- outerWs . deleteVariableById ( model . getId ( ) ) ;
753- }
754- }
755- } ,
756748} ;
757749blocks [ 'procedures_mutatorarg' ] = PROCEDURES_MUTATORARGUMENT ;
758750
0 commit comments