diff --git a/blockly_uncompressed.js b/blockly_uncompressed.js index 8c7996a6e..ccd5115ac 100644 --- a/blockly_uncompressed.js +++ b/blockly_uncompressed.js @@ -37,7 +37,7 @@ this.BLOCKLY_BOOT = function(root) { goog.addDependency("../../../" + dir + "/core/block.js", ['Blockly.Block'], ['Blockly.Blocks', 'Blockly.Comment', 'Blockly.Connection', 'Blockly.Events.BlockChange', 'Blockly.Events.BlockCreate', 'Blockly.Events.BlockDelete', 'Blockly.Events.BlockMove', 'Blockly.Extensions', 'Blockly.Input', 'Blockly.Mutator', 'Blockly.utils', 'Blockly.Warning', 'Blockly.Workspace', 'goog.math.Coordinate']); goog.addDependency("../../../" + dir + "/core/block_animations.js", ['Blockly.BlockAnimations'], ['Blockly.utils']); goog.addDependency("../../../" + dir + "/core/block_drag_surface.js", ['Blockly.BlockDragSurfaceSvg'], ['Blockly.utils', 'goog.math.Coordinate']); -goog.addDependency("../../../" + dir + "/core/block_dragger.js", ['Blockly.BlockDragger'], ['Blockly.BlockAnimations', 'Blockly.DraggedConnectionManager', 'Blockly.Events.BlockMove', 'goog.math.Coordinate']); +goog.addDependency("../../../" + dir + "/core/block_dragger.js", ['Blockly.BlockDragger'], ['Blockly.BlockAnimations', 'Blockly.InsertionMarkerManager', 'Blockly.Events.BlockMove', 'goog.math.Coordinate']); goog.addDependency("../../../" + dir + "/core/block_events.js", ['Blockly.Events.BlockBase', 'Blockly.Events.BlockChange', 'Blockly.Events.BlockCreate', 'Blockly.Events.BlockDelete', 'Blockly.Events.BlockMove', 'Blockly.Events.Change', 'Blockly.Events.Create', 'Blockly.Events.Delete', 'Blockly.Events.Move'], ['Blockly.Events', 'Blockly.Events.Abstract', 'Blockly.Xml.utils', 'goog.math.Coordinate']); goog.addDependency("../../../" + dir + "/core/block_render_svg.js", ['Blockly.BlockSvg.render'], ['Blockly.BlockSvg']); goog.addDependency("../../../" + dir + "/core/block_svg.js", ['Blockly.BlockSvg'], ['Blockly.Block', 'Blockly.BlockAnimations', 'Blockly.ContextMenu', 'Blockly.Events.Ui', 'Blockly.Events.BlockMove', 'Blockly.Grid', 'Blockly.RenderedConnection', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.utils', 'goog.color', 'goog.math.Coordinate']); @@ -77,6 +77,7 @@ goog.addDependency("../../../" + dir + "/core/grid.js", ['Blockly.Grid'], ['Bloc goog.addDependency("../../../" + dir + "/core/icon.js", ['Blockly.Icon'], ['Blockly.utils', 'goog.math.Coordinate']); goog.addDependency("../../../" + dir + "/core/inject.js", ['Blockly.inject'], ['Blockly.BlockDragSurfaceSvg', 'Blockly.Css', 'Blockly.Grid', 'Blockly.Options', 'Blockly.utils', 'Blockly.WorkspaceSvg', 'Blockly.WorkspaceDragSurfaceSvg', 'goog.ui.Component', 'goog.userAgent']); goog.addDependency("../../../" + dir + "/core/input.js", ['Blockly.Input'], ['Blockly.Connection', 'Blockly.FieldLabel']); +goog.addDependency("../../../" + dir + "/core/insertion_marker_manager.js", ['Blockly.InsertionMarkerManager'], ['Blockly.BlockAnimations', 'Blockly.Events.BlockMove', 'Blockly.RenderedConnection', 'goog.math.Coordinate']); goog.addDependency("../../../" + dir + "/core/msg.js", ['Blockly.Msg'], []); goog.addDependency("../../../" + dir + "/core/mutator.js", ['Blockly.Mutator'], ['Blockly.Bubble', 'Blockly.Events.BlockChange', 'Blockly.Events.Ui', 'Blockly.Icon', 'Blockly.utils', 'Blockly.WorkspaceSvg', 'Blockly.Xml', 'Blockly.Xml.utils']); goog.addDependency("../../../" + dir + "/core/names.js", ['Blockly.Names'], []); @@ -1786,6 +1787,7 @@ goog.require('Blockly.Grid'); goog.require('Blockly.HorizontalFlyout'); goog.require('Blockly.Icon'); goog.require('Blockly.Input'); +goog.require('Blockly.InsertionMarkerManager'); goog.require('Blockly.Msg'); goog.require('Blockly.Mutator'); goog.require('Blockly.Names'); diff --git a/core/connection.js b/core/connection.js index 197b4c468..bff427814 100644 --- a/core/connection.js +++ b/core/connection.js @@ -357,48 +357,39 @@ Blockly.Connection.prototype.canConnectToPrevious_ = function(candidate) { return false; } - switch (candidate.type) { - case Blockly.PREVIOUS_STATEMENT: - // Don't offer to connect the bottom of a statement block to one that's - // already connected. - if (candidate.isConnected() || this.isConnected()) { - return false; - } - break; - case Blockly.OUTPUT_VALUE: - // Don't offer to connect an already connected left (male) value plug to - // an available right (female) value plug. - if (candidate.isConnected() || this.isConnected()) { - return false; - } - break; - case Blockly.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 unmovable block. - if (candidate.targetConnection && - !candidate.targetBlock().isMovable() && - !candidate.targetBlock().isShadow()) { - return false; - } - break; - case Blockly.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 (candidate.isConnected() && - !this.sourceBlock_.nextConnection && - !candidate.targetBlock().isShadow() && - candidate.targetBlock().nextConnection) { - return false; - } - break; - default: - throw Error('Unknown connection type in isConnectionAllowed'); + // Don't let blocks try to connect to themselves or ones they nest. + if (Blockly.draggingConnections_.indexOf(candidate) != -1) { + return false; } - return true; + var firstStatementConnection = + this.sourceBlock_.getFirstStatementConnection(); + var isFirstStatementConnection = this == firstStatementConnection; + var isNextConnection = this == this.sourceBlock_.nextConnection; + + // Complex blocks with no previous connection will not be allowed to connect + // mid-stack. + var sourceHasPreviousConn = this.sourceBlock_.previousConnection != null; + + if (isNextConnection || + (isFirstStatementConnection && !sourceHasPreviousConn)) { + // If the candidate is the first connection in a stack, we can connect. + if (!candidate.targetConnection) { + return true; + } + + var targetBlock = candidate.targetBlock(); + // If it is connected a real block, game over. + if (!targetBlock.isInsertionMarker()) { + return false; + } + // If it's connected to an insertion marker but that insertion marker + // is the first block in a stack, it's still fine. If that insertion + // marker is in the middle of a stack, it won't work. + return !targetBlock.getPreviousBlock(); + } + // ??? + return false; }; /** diff --git a/core/insertion_marker_manager.js b/core/insertion_marker_manager.js index b53f2adf4..10dbb6d0f 100644 --- a/core/insertion_marker_manager.js +++ b/core/insertion_marker_manager.js @@ -703,9 +703,7 @@ Blockly.InsertionMarkerManager.prototype.connectMarker_ = function() { imBlock.positionNewBlock(imBlock, imConn, closest); // Connect() also renders the insertion marker. - console.log("connecting the insertion marker"); imConn.connect(closest); - console.log("done connecting the insertion marker"); this.markerConnection_ = imConn; }; diff --git a/tests/jsunit/connection_db_test.js b/tests/jsunit/connection_db_test.js index 1ef07c6b8..f488d5a96 100644 --- a/tests/jsunit/connection_db_test.js +++ b/tests/jsunit/connection_db_test.js @@ -279,6 +279,7 @@ function helper_searchDB(db, x, y, radius, shared_workspace) { var tempConn = helper_createConnection(x, y, Blockly.NEXT_STATEMENT, shared_workspace, true); tempConn.sourceBlock_ = helper_makeSourceBlock(shared_workspace); + tempConn.sourceBlock_.nextConnection = tempConn; var closest = db.searchForClosest(tempConn, radius, {x: 0, y: 0}); return closest.connection; }