in core/connection_checker.js [194:273]
Blockly.ConnectionChecker.prototype.doDragChecks = function(a, b, distance) {
if (a.distanceFrom(b) > distance) {
return false;
}
// Don't consider insertion markers.
if (b.getSourceBlock().isInsertionMarker()) {
return false;
}
switch (b.type) {
case Blockly.connectionTypes.PREVIOUS_STATEMENT:
return this.canConnectToPrevious_(a, b);
case Blockly.connectionTypes.OUTPUT_VALUE: {
// Don't offer to connect an already connected left (male) value plug to
// an available right (female) value plug.
if ((b.isConnected() &&
!b.targetBlock().isInsertionMarker()) ||
a.isConnected()) {
return false;
}
break;
}
case Blockly.connectionTypes.INPUT_VALUE: {
// Offering to connect the left (male) of a value block to an already
// connected value pair is ok, we'll splice it in.
// However, don't offer to splice into an immovable block.
if (b.isConnected() &&
!b.targetBlock().isMovable() &&
!b.targetBlock().isShadow()) {
return false;
}
// pxt-blockly: don't allow connecting a block to an argument reporter
// shadow.
if (b && b.targetBlock()) {
var targetBlock = b.targetBlock();
if (targetBlock.isShadow() && Blockly.pxtBlocklyUtils.isFunctionArgumentReporter(targetBlock)) {
return false;
}
}
// pxt-blockly: don't allow putting argument reporters outside their
// respective function or event handler.
if (Blockly.pxtBlocklyUtils.isFunctionArgumentReporter(a.getSourceBlock())) {
// Ensure the root block of this stack has an argument reporter
// matching the name and the type of this reporter.
var rootBlock = b.getSourceBlock().getRootBlock();
if (rootBlock.isEnabled() && !Blockly.pxtBlocklyUtils.hasMatchingArgumentReporter(rootBlock, a.getSourceBlock())) {
return false;
}
}
break;
}
case Blockly.connectionTypes.NEXT_STATEMENT: {
// Don't let a block with no next connection bump other blocks out of the
// stack. But covering up a shadow block or stack of shadow blocks is
// fine. Similarly, replacing a terminal statement with another terminal
// statement is allowed.
if (b.isConnected() &&
!a.getSourceBlock().nextConnection &&
!b.targetBlock().isShadow() &&
b.targetBlock().nextConnection) {
return false;
}
break;
}
default:
// Unexpected connection type.
return false;
}
// Don't let blocks try to connect to themselves or ones they nest.
if (Blockly.draggingConnections.indexOf(b) != -1) {
return false;
}
return true;
};