Facing an issue while deleting connected blocks.

108 views
Skip to first unread message

Rupak Choudhury

unread,
May 17, 2021, 8:15:24 AM5/17/21
to blo...@googlegroups.com
Hi Team,

I am facing an issue while deleting connected blocks.

If you observe the 1st attachment , When I right click on the second block it shows me the option Delete 2 Blocks.

When I clicked on the option it actually delete the first block only as shown in the attachment 2.

Is this the default behaviour of blockly?


Can anyone suggest, If I want to delete all the connected blocks how can I achieve that?

Thanks,
Rupak

IMG-20210517-WA0004.jpg
IMG-20210517-WA0003.jpg

Jason Schanker

unread,
May 17, 2021, 3:56:31 PM5/17/21
to Blockly
Hi Rupak,

Not on the Blockly team so I don't know if this was intended, but it seems strange to me that it would count the child blocks for the delete message but not remove them.  In fact, if you attach another text block to the create text block, all blocks are deleted so I'm fairly certain this is a bug.

The relevant code can be found in the callback here: https://github.com/google/blockly/blob/master/core/contextmenu_items.js#L458.  When it calls  scope.block.dispose(true, true), it's passing true for healStack (https://github.com/google/blockly/blob/master/core/block.js#L357); the other true seems accidental as the method only takes one argument.  In the current implementation, if healStack is true, it attempts to connect the stack of blocks below it to the deleted block's parent (if it's a statement block, which is not relevant here).  However, if the deleted block has an output connection as is the case with the create text block, and that block only has one block connected to its value input, the text block in this case (https://github.com/google/blockly/blob/master/core/block.js#L495), it will attempt to connect the deleted block's child to the deleted block's parent (the variable set block).  This is why if you have one text block connected, it succeeds in reconnecting it to the variable set block, but if you have multiple ones, getOnlyValueConnection_ returns with null so it deletes the child text blocks as intended (obviously can't connect two text blocks to a single variable set block).

A simple monkey-patch solution that you could use for now would be to redefine Blockly.Block.prototype.unplug so that this.unplugFromRow_ is called with false instead of opt_healStack.  This way it will never try to reconnect value input blocks of deleted blocks even if there's only one.  Not a recommended solution in general, but this could be a quick fix for now until this likely bug is corrected.

Blockly.Block.prototype.unplug = function(opt_healStack) {
  if (this.outputConnection) {
    this.unplugFromRow_(false);
  } else if (this.previousConnection) {
    this.unplugFromStack_(opt_healStack);
  }
};

Best,
Jason

Beka Westberg

unread,
May 17, 2021, 7:07:53 PM5/17/21
to blo...@googlegroups.com
Hi peoples! Thanks for reporting this. I think you're right that this behavior is buggy, so I've filed an issue for it.

To temporarily fix the problem, you can definitely go with what Jason suggested, and/or you can also try out the new context menus API to remove and replace that context menu option.

Also, this is a side tangent, but about the 2 params vs 1, that's a side effect of how Blockly actually has 2 "block" classes. One (Block) handles all of the "headless" behavior - which doesn't rely on the UI, and the other (BlockSvg) adds all of the UI behavior. So while the Block dispose function only has one param, the BlockSvg.dispose function adds another param which controls whether an animation is played.

Thank you again for reporting this :D Best wishes,
--Beka

--
You received this message because you are subscribed to the Google Groups "Blockly" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blockly+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/blockly/8e073ee7-fcd9-4f0d-bea7-fffcda16e221n%40googlegroups.com.

Jason Schanker

unread,
May 17, 2021, 9:15:11 PM5/17/21
to Blockly
Thanks, Beka for the clarification!  I forgot to check the subclass method.

Rupak Choudhury

unread,
May 18, 2021, 1:38:35 PM5/18/21
to blo...@googlegroups.com
Thank you Jason and Beka, thanks for the timely response. It really helps.

Jason Schanker

unread,
Jun 4, 2021, 2:30:23 AM6/4/21
to Blockly
Hi Rupak,

As I returned to this bug, I noticed an unfortunate side effect of my suggestion.  Specifically, when a block with a single input can fit in between two other ones with a single input horizontally, then dragging it in and out can result in the deletion of blocks (see below GIF animation):

disappearing-block-unplug.gif
Fortunately, it seems you can still work around the earlier bug you found by removing and replacing the context menu option to delete blocks (`Blockly.ContextMenuRegistry.registry.unregister('blockDelete')`) as Beka had suggested.  You can modify the callback to heal vertical stacks but not rows by replacing `scope.block.dispose(true, true)` with:

if(scope.block.outputConnection) {
  scope.block.dispose(false, true);
} else {
  scope.block.dispose(true, true);
}

Sorry for the earlier mistake and hope I'm not missing something again!

Best,
Jason
Reply all
Reply to author
Forward
0 new messages