Blockly.ConnectionChecker.prototype.doDragChecks = function()

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;
};