@@ -27,6 +27,27 @@ goog.require('Blockly.Colours');
2727goog . require ( 'Blockly.constants' ) ;
2828goog . require ( 'Blockly.ScratchBlocks.VerticalExtensions' ) ;
2929
30+ /* Utility function for Expandable Blocks */
31+ const mutatorPopulateUtil = function ( connection , type , optValue , optValueName ) {
32+ if ( connection . sourceBlock_ . isInsertionMarker_ ) return ;
33+
34+ ScratchBlocks . Events . disable ( ) ;
35+ const block = this . workspace . newBlock ( type ) ;
36+ try {
37+ if ( optValue ) block . setFieldValue ( optValue , optValueName ) ;
38+ block . setShadow ( true ) ;
39+ if ( ! this . isInsertionMarker ( ) ) {
40+ block . initSvg ( ) ;
41+ block . render ( false ) ;
42+ }
43+ } finally {
44+ ScratchBlocks . Events . enable ( ) ;
45+ }
46+
47+ if ( ScratchBlocks . Events . isEnabled ( ) ) ScratchBlocks . Events . fire ( new ScratchBlocks . Events . BlockCreate ( block ) ) ;
48+ if ( block . outputConnection ) block . outputConnection . connect ( connection ) ;
49+ else block . previousConnection . connect ( connection ) ;
50+ }
3051
3152Blockly . Blocks [ 'operator_add' ] = {
3253 /**
@@ -147,15 +168,17 @@ Blockly.Blocks['operator_expandableMath'] = {
147168 } ) ;
148169
149170 this . inputs_ = 2 ;
171+ this . oldInputs_ = null ;
150172 if ( this . isInFlyout ) {
151173 const input1 = this . appendValueInput ( "NUM1" ) ;
152- this . fillInBlock ( input1 . connection , 0 ) ;
174+ this . fillInBlock ( input1 . connection , "math_number" ) ;
153175 const input2 = this . appendValueInput ( "NUM2" ) ;
154176 input2 . appendField ( this . menuGenerator ( ) ) ;
155- this . fillInBlock ( input2 . connection , 1 ) ;
177+ this . fillInBlock ( input2 . connection , "math_number" ) ;
156178 }
157179 } ,
158180
181+ fillInBlock : mutatorPopulateUtil ,
159182 menuGenerator : function ( ) {
160183 const dropdown = new Blockly . FieldDropdown ( function ( ) {
161184 return [
@@ -180,21 +203,11 @@ Blockly.Blocks['operator_expandableMath'] = {
180203 }
181204 return dropdown ;
182205 } ,
183- fillInBlock : function ( connection , index ) {
184- if ( connection . sourceBlock_ . isInsertionMarker_ ) return ;
185- const block = this . workspace . newBlock ( 'math_number' ) ;
186- block . setShadow ( true ) ;
187- block . initSvg ( ) ;
188- block . render ( false ) ;
189- block . outputConnection . connect ( connection ) ;
190- } ,
191206
192207 mutationToDom : function ( ) {
193208 // on save
194209 const container = document . createElement ( "mutation" ) ;
195- let number = Number ( this . inputs_ ) ;
196- if ( isNaN ( number ) ) number = 1 ;
197- container . setAttribute ( "inputcount" , String ( number ) ) ;
210+ container . setAttribute ( "inputcount" , String ( this . inputs_ ) ) ;
198211 let orderedOperations = "" ;
199212 for ( var i = 1 ; i < this . inputList . length ; i ++ ) {
200213 const input = this . inputList [ i ] ;
@@ -203,9 +216,9 @@ Blockly.Blocks['operator_expandableMath'] = {
203216 container . setAttribute ( "menuvalues" , orderedOperations ) ;
204217 return container ;
205218 } ,
206-
207219 domToMutation : function ( xmlElement ) {
208220 // on load
221+ if ( this . oldInputs_ === this . inputs_ ) return ;
209222 const inputCount = Number ( xmlElement . getAttribute ( "inputcount" ) ) ;
210223 const menuValues = String ( xmlElement . getAttribute ( "menuvalues" ) ) ;
211224 this . inputs_ = isNaN ( inputCount ) ? 0 : inputCount ;
@@ -215,19 +228,9 @@ Blockly.Blocks['operator_expandableMath'] = {
215228 const menu = input . appendField ( this . menuGenerator ( ) ) ;
216229 menu . fieldRow [ 0 ] . setValue ( menuValues [ i - 1 ] ? menuValues [ i - 1 ] : "+" , true ) ;
217230 }
218- this . fillInBlock ( input . connection , i ) ;
231+ this . fillInBlock ( input . connection , "math_number" ) ;
219232 }
220- queueMicrotask ( ( ) => {
221- const connections = this . getConnections_ ( ) ;
222- for ( let i = 1 ; i < connections . length ; i ++ ) {
223- const block = connections [ i ] . targetBlock ( ) ;
224- if ( ! block ) continue ;
225- if (
226- ! block . category_ && ! block . isShadow ( ) &&
227- ! block . type . startsWith ( "procedures_" ) && ! block . type . startsWith ( "argument_" )
228- ) block . dispose ( ) ;
229- }
230- } ) ;
233+ this . oldInputs_ = this . inputs_ ;
231234 } ,
232235
233236 onExpandableButtonClicked_ : function ( isAdding ) {
@@ -240,7 +243,7 @@ Blockly.Blocks['operator_expandableMath'] = {
240243 const number = this . inputs_ ;
241244 const newInput = this . appendValueInput ( `NUM${ number } ` ) ;
242245 newInput . appendField ( this . menuGenerator ( ) ) ;
243- this . fillInBlock ( newInput . connection , number - 1 ) ;
246+ this . fillInBlock ( newInput . connection , "math_number" ) ;
244247 } else if ( this . inputs_ > 1 ) {
245248 const number = this . inputs_ ;
246249 this . removeInput ( `NUM${ number } ` ) ;
@@ -675,66 +678,33 @@ Blockly.Blocks['operators_expandablejoininputs'] = {
675678
676679 this . messageList = [ "apple" , "banana" , "pear" , "orange" , "mango" , "strawberry" , "pineapple" , "grape" , "kiwi" ] ;
677680 this . inputs_ = 2 ;
678- if ( this . isInFlyout ) {
681+ this . oldInputs_ = null ;
682+ if ( this . isInFlyout ) queueMicrotask ( ( ) => {
679683 for ( let i = 0 ; i < this . inputs_ ; i ++ ) {
680684 const input = this . appendValueInput ( `INPUT${ i + 1 } ` ) ;
681- this . fillInBlock ( input . connection , i ) ;
685+ this . fillInBlock ( input . connection , "text" , this . messageList [ i ] , "TEXT" ) ;
682686 }
683- }
687+ } )
684688 } ,
685689
686- fillInBlock : function ( connection , index ) {
687- if ( connection . sourceBlock_ . isInsertionMarker_ ) return ;
688- const block = this . workspace . newBlock ( 'text' ) ;
689-
690- let textValue = this . messageList [ index ] ;
691- const editingTarget = window . vm . editingTarget ;
692- if ( editingTarget ) {
693- const vmBlock = editingTarget . blocks . getBlock ( this . id ) ;
694- if ( vmBlock ) {
695- const input = vmBlock . inputs [ `INPUT${ index + 1 } ` ] ;
696- if ( input ) {
697- const inpuBlock = editingTarget . blocks . getBlock ( input . block ) ;
698- if ( inpuBlock ) textValue = inpuBlock . fields . TEXT . value ;
699- }
700- }
701- }
702-
703- block . setFieldValue ( textValue !== undefined ? textValue : "..." , "TEXT" ) ;
704- block . setShadow ( true ) ;
705- block . initSvg ( ) ;
706- block . render ( false ) ;
707- block . outputConnection . connect ( connection ) ;
708- } ,
690+ fillInBlock : mutatorPopulateUtil ,
709691
710692 mutationToDom : function ( ) {
711693 // on save
712694 const container = document . createElement ( "mutation" ) ;
713- let number = Number ( this . inputs_ ) ;
714- if ( isNaN ( number ) ) number = 1 ;
715- container . setAttribute ( "inputcount" , String ( number ) ) ;
695+ container . setAttribute ( "inputcount" , String ( this . inputs_ ) ) ;
716696 return container ;
717697 } ,
718-
719698 domToMutation : function ( xmlElement ) {
720699 // on load
700+ if ( this . oldInputs_ === this . inputs_ ) return ;
721701 const inputCount = Number ( xmlElement . getAttribute ( "inputcount" ) ) ;
722702 this . inputs_ = isNaN ( inputCount ) ? 0 : inputCount ;
723703 for ( let i = 0 ; i < this . inputs_ ; i ++ ) {
724704 const input = this . appendValueInput ( `INPUT${ i + 1 } ` ) ;
725- this . fillInBlock ( input . connection , i ) ;
705+ this . fillInBlock ( input . connection , "text" , this . messageList [ i ] , "TEXT" ) ;
726706 }
727- queueMicrotask ( ( ) => {
728- const connections = this . getConnections_ ( ) ;
729- for ( let i = 1 ; i < connections . length ; i ++ ) {
730- const block = connections [ i ] . targetBlock ( ) ;
731- if ( ! block ) continue ;
732- if (
733- ! block . category_ && ! block . isShadow ( ) &&
734- ! block . type . startsWith ( "procedures_" ) && ! block . type . startsWith ( "argument_" )
735- ) block . dispose ( ) ;
736- }
737- } ) ;
707+ this . oldInputs_ = this . inputs_ ;
738708 } ,
739709
740710 onExpandableButtonClicked_ : function ( isAdding ) {
@@ -746,10 +716,9 @@ Blockly.Blocks['operators_expandablejoininputs'] = {
746716 this . inputs_ ++ ;
747717 const number = this . inputs_ ;
748718 const newInput = this . appendValueInput ( `INPUT${ number } ` ) ;
749- this . fillInBlock ( newInput . connection , number - 1 ) ;
719+ this . fillInBlock ( newInput . connection , "text" , this . messageList [ number - 1 ] , "TEXT" ) ;
750720 } else if ( this . inputs_ > 1 ) {
751- const number = this . inputs_ ;
752- this . removeInput ( `INPUT${ number } ` ) ;
721+ this . removeInput ( `INPUT${ this . inputs_ } ` ) ;
753722 this . inputs_ -- ;
754723 }
755724 this . initSvg ( ) ;
0 commit comments