mirror of
https://github.com/google/blockly.git
synced 2026-01-11 10:57:07 +01:00
Reduce duplication in Connection.connect. Support shadow statement blocks. Fix race condition.
This commit is contained in:
@@ -156,54 +156,41 @@ Blockly.Connection.prototype.connect = function(otherConnection) {
|
||||
if (Blockly.OPPOSITE_TYPE[this.type] != otherConnection.type) {
|
||||
throw 'Attempt to connect incompatible types.';
|
||||
}
|
||||
if (this.type == Blockly.INPUT_VALUE || this.type == Blockly.OUTPUT_VALUE) {
|
||||
// Value connections.
|
||||
if (this.targetConnection) {
|
||||
// Can't make a value connection if male block is already connected.
|
||||
throw 'Source connection already connected (value).';
|
||||
} else if (otherConnection.targetConnection) {
|
||||
if (this.targetConnection) {
|
||||
throw 'Source connection already connected.';
|
||||
}
|
||||
if (otherConnection.targetConnection) {
|
||||
// Other connection is already connected to something.
|
||||
var orphanBlock = otherConnection.targetBlock();
|
||||
if (orphanBlock.isShadow()) {
|
||||
orphanBlock.dispose();
|
||||
orphanBlock = null;
|
||||
} else if (this.type == Blockly.INPUT_VALUE ||
|
||||
this.type == Blockly.OUTPUT_VALUE) {
|
||||
// Value connections.
|
||||
// If female block is already connected, disconnect and bump the male.
|
||||
var orphanBlock = otherConnection.targetBlock();
|
||||
orphanBlock.setParent(null);
|
||||
if (orphanBlock.isShadow()) {
|
||||
orphanBlock.dispose();
|
||||
} else {
|
||||
if (!orphanBlock.outputConnection) {
|
||||
throw 'Orphan block does not have an output connection.';
|
||||
}
|
||||
// Attempt to reattach the orphan at the end of the newly inserted
|
||||
// block. Since this block may be a row, walk down to the end.
|
||||
var newBlock = this.sourceBlock_;
|
||||
var connection;
|
||||
while (connection = Blockly.Connection.singleConnection_(
|
||||
/** @type {!Blockly.Block} */ (newBlock), orphanBlock)) {
|
||||
// '=' is intentional in line above.
|
||||
newBlock = connection.targetBlock();
|
||||
if (!newBlock || newBlock.isShadow()) {
|
||||
orphanBlock.outputConnection.connect(connection);
|
||||
orphanBlock = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (orphanBlock) {
|
||||
// Unable to reattach orphan. Bump it off to the side.
|
||||
setTimeout(function() {
|
||||
orphanBlock.outputConnection.bumpAwayFrom_(otherConnection);
|
||||
}, Blockly.BUMP_DELAY);
|
||||
if (!orphanBlock.outputConnection) {
|
||||
throw 'Orphan block does not have an output connection.';
|
||||
}
|
||||
// Attempt to reattach the orphan at the end of the newly inserted
|
||||
// block. Since this block may be a row, walk down to the end.
|
||||
var newBlock = this.sourceBlock_;
|
||||
var connection;
|
||||
while (connection = Blockly.Connection.singleConnection_(
|
||||
/** @type {!Blockly.Block} */ (newBlock), orphanBlock)) {
|
||||
// '=' is intentional in line above.
|
||||
newBlock = connection.targetBlock();
|
||||
if (!newBlock || newBlock.isShadow()) {
|
||||
orphanBlock.outputConnection.connect(connection);
|
||||
orphanBlock = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Statement connections.
|
||||
if (this.targetConnection) {
|
||||
throw 'Source connection already connected (block).';
|
||||
} else if (otherConnection.targetConnection) {
|
||||
} else if (this.type == Blockly.PREVIOUS_STATEMENT) {
|
||||
// Statement connections.
|
||||
// Statement blocks may be inserted into the middle of a stack.
|
||||
if (this.type != Blockly.PREVIOUS_STATEMENT) {
|
||||
throw 'Can only do a mid-stack connection with the top of a block.';
|
||||
}
|
||||
// Split the stack.
|
||||
var orphanBlock = otherConnection.targetBlock();
|
||||
orphanBlock.setParent(null);
|
||||
if (!orphanBlock.previousConnection) {
|
||||
throw 'Orphan block does not have a previous connection.';
|
||||
@@ -223,12 +210,18 @@ Blockly.Connection.prototype.connect = function(otherConnection) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (orphanBlock) {
|
||||
// Unable to reattach orphan. Bump it off to the side.
|
||||
setTimeout(function() {
|
||||
orphanBlock.previousConnection.bumpAwayFrom_(otherConnection);
|
||||
}, Blockly.BUMP_DELAY);
|
||||
}
|
||||
} else {
|
||||
// Type is Blockly.NEXT_STATEMENT.
|
||||
throw 'Can only do a mid-stack connection with the top of a block.';
|
||||
}
|
||||
if (orphanBlock) {
|
||||
// Unable to reattach orphan. Bump it off to the side after a moment.
|
||||
setTimeout(function() {
|
||||
// Verify orphan hasn't been deleted or reconnected (user on meth).
|
||||
if (orphanBlock.workspace && !orphanBlock.getParent()) {
|
||||
orphanBlock.outputConnection.bumpAwayFrom_(otherConnection);
|
||||
}
|
||||
}, Blockly.BUMP_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user