diff --git a/core/block_svg.js b/core/block_svg.js index dcab41b85..6c44f2bf2 100644 --- a/core/block_svg.js +++ b/core/block_svg.js @@ -165,12 +165,11 @@ Blockly.BlockSvg.prototype.warningTextDb_ = null; /** * Should the block tell its connections to start tracking inside the render - * method? Or it should it wait for startTrackingConnections to be called - * separately? + * method? * @type {boolean} * @private */ -Blockly.BlockSvg.prototype.waitToTrackConnections_ = false; +Blockly.BlockSvg.prototype.doNotCallTrackConnections_ = false; /** * Constant for identifying rows that are to be rendered inline. @@ -1447,14 +1446,31 @@ Blockly.BlockSvg.prototype.appendInput_ = function(type, name) { return input; }; +/** + * Tell the block to wait for an outside source to call + * startTrackingConnections, rather than starting connection + * tracking automatically. + * + * Also tells children of this block to wait. + * @package + */ Blockly.BlockSvg.prototype.waitToTrackConnections = function() { - this.waitToTrackConnections_ = true; + this.doNotCallTrackConnections_ = true; var children = this.getChildren(); for (var i = 0, child; child = children[i]; i++) { child.waitToTrackConnections(); } }; +/** + * Tell this block's connections to add themselves to the connection + * database (i.e. start tracking). + * + * All following/next blocks will be told to start tracking. Inner blocks + * (i.e. blocks attached to value/statement inputs) will be told to start + * tracking if this block is not collapsed. + * @package + */ Blockly.BlockSvg.prototype.startTrackingConnections = function() { if (this.previousConnection) { this.previousConnection.setTracking(true); @@ -1470,19 +1486,19 @@ Blockly.BlockSvg.prototype.startTrackingConnections = function() { } } - // If we're collapsed we want the invisible inputs' connections - // to remain untracked. - if (!this.collapsed_) { - for (var i = 0; i < this.inputList.length; i++) { - var conn = this.inputList[i].connection; - if (conn) { - conn.setTracking(true); + if (this.collapsed_) { + return; + } - // Pass tracking on down the chain. - var block = conn.targetBlock(); - if (block) { - block.startTrackingConnections(); - } + for (var i = 0; i < this.inputList.length; i++) { + var conn = this.inputList[i].connection; + if (conn) { + conn.setTracking(true); + + // Pass tracking on down the chain. + var block = conn.targetBlock(); + if (block) { + block.startTrackingConnections(); } } } @@ -1632,8 +1648,12 @@ Blockly.BlockSvg.prototype.render = function(opt_bubble) { (/** @type {!Blockly.WorkspaceSvg} */ (this.workspace)).getRenderer().render(this); // No matter how we rendered, connection locations should now be correct. this.updateConnectionLocations_(); - if (!this.waitToTrackConnections_) { + // TODO: This should be handled inside a robust init method, because it would + // make it a lot cleaner, but for now it's handled here for backwards + // compatibility. + if (!this.doNotCallTrackConnections_) { this.startTrackingConnections(); + this.doNotCallTrackConnections_ = true; } if (opt_bubble !== false) { // Render all blocks above this one (propagate a reflow). diff --git a/core/connection.js b/core/connection.js index 082eb9b8c..f788d82cf 100644 --- a/core/connection.js +++ b/core/connection.js @@ -204,8 +204,7 @@ Blockly.Connection.prototype.connect_ = function(childConnection) { }; /** - * Dispose of this connection. Deal with connected blocks and remove this - * connection from the database. + * Dispose of this connection and deal with connected blocks. * @package */ Blockly.Connection.prototype.dispose = function() { diff --git a/core/connection_db.js b/core/connection_db.js index d18e85264..102060210 100644 --- a/core/connection_db.js +++ b/core/connection_db.js @@ -19,14 +19,16 @@ */ /** - * @fileoverview Components for managing connections between blocks. + * @fileoverview A database of all the rendered connections that could + * possibly be connected to (i.e. not collapsed, etc). + * Sorted by y coordinate. * @author fraser@google.com (Neil Fraser) */ 'use strict'; goog.provide('Blockly.ConnectionDB'); -goog.require('Blockly.Connection'); +goog.require('Blockly.RenderedConnection'); /** @@ -38,7 +40,7 @@ goog.require('Blockly.Connection'); Blockly.ConnectionDB = function() { /** * Array of connections sorted by y position in workspace units. - * @type {!Array.} + * @type {!Array.} * @private */ this.connections_ = []; @@ -46,16 +48,12 @@ Blockly.ConnectionDB = function() { /** * Add a connection to the database. Should not already exist in the database. - * @param {!Blockly.Connection} connection The connection to be added. + * @param {!Blockly.RenderedConnection} connection The connection to be added. * @param {number} yPos The y position used to decide where to insert the * connection. * @package */ Blockly.ConnectionDB.prototype.addConnection = function(connection, yPos) { - if (connection.getSourceBlock().isInFlyout) { - // Don't bother maintaining a database of connections in a flyout. - return; - } var index = this.calculateIndexForYPos_(yPos); this.connections_.splice(index, 0, connection); }; @@ -65,7 +63,7 @@ Blockly.ConnectionDB.prototype.addConnection = function(connection, yPos) { * * Starts by doing a binary search to find the approximate location, then * linearly searches nearby for the exact connection. - * @param {!Blockly.Connection} conn The connection to find. + * @param {!Blockly.RenderedConnection} conn The connection to find. * @param {number} yPos The y position used to find the index of the connection. * @return {number} The index of the connection, or -1 if the connection was * not found. @@ -132,7 +130,7 @@ Blockly.ConnectionDB.prototype.calculateIndexForYPos_ = function(yPos) { /** * Remove a connection from the database. Must already exist in DB. - * @param {!Blockly.Connection} connection The connection to be removed. + * @param {!Blockly.RenderedConnection} connection The connection to be removed. * @param {number} yPos The y position used to find the index of the connection. * @throws {Error} If the connection cannot be found in the database. */ @@ -147,10 +145,10 @@ Blockly.ConnectionDB.prototype.removeConnection = function(connection, yPos) { /** * Find all nearby connections to the given connection. * Type checking does not apply, since this function is used for bumping. - * @param {!Blockly.Connection} connection The connection whose neighbours - * should be returned. + * @param {!Blockly.RenderedConnection} connection The connection whose + * neighbours should be returned. * @param {number} maxRadius The maximum radius to another connection. - * @return {!Array.} List of connections. + * @return {!Array.} List of connections. */ Blockly.ConnectionDB.prototype.getNeighbours = function(connection, maxRadius) { var db = this.connections_; @@ -219,15 +217,15 @@ Blockly.ConnectionDB.prototype.isInYRange_ = function(index, baseY, maxRadius) { /** * Find the closest compatible connection to this connection. - * @param {!Blockly.Connection} conn The connection searching for a compatible + * @param {!Blockly.RenderedConnection} conn The connection searching for a compatible * mate. * @param {number} maxRadius The maximum radius to another connection. * @param {!Blockly.utils.Coordinate} dxy Offset between this connection's * location in the database and the current location (as a result of * dragging). - * @return {!{connection: ?Blockly.Connection, radius: number}} Contains two - * properties:' connection' which is either another connection or null, - * and 'radius' which is the distance. + * @return {!{connection: Blockly.RenderedConnection, radius: number}} + * Contains two properties: 'connection' which is either another + * connection or null, and 'radius' which is the distance. */ Blockly.ConnectionDB.prototype.searchForClosest = function(conn, maxRadius, dxy) { @@ -243,10 +241,10 @@ Blockly.ConnectionDB.prototype.searchForClosest = function(conn, maxRadius, conn.x_ = baseX + dxy.x; conn.y_ = baseY + dxy.y; - // findPositionForConnection finds an index for insertion, which is always + // calculateIndexForYPos_ finds an index for insertion, which is always // after any block with the same y index. We want to search both forward // and back, so search on both sides of the index. - var closestIndex = this.findPositionForConnection_(conn); + var closestIndex = this.calculateIndexForYPos_(conn.y_); var bestConnection = null; var bestRadius = maxRadius; diff --git a/core/rendered_connection.js b/core/rendered_connection.js index 2018849d8..ecf156e59 100644 --- a/core/rendered_connection.js +++ b/core/rendered_connection.js @@ -77,7 +77,10 @@ Blockly.RenderedConnection = function(source, type) { Blockly.utils.object.inherits(Blockly.RenderedConnection, Blockly.Connection); /** + * Dispose of this connection. Remove it from the database (if it is + * tracked) and call the super-function to deal with connected blocks. * @override + * @package */ Blockly.RenderedConnection.prototype.dispose = function() { if (this.tracked_) { @@ -284,11 +287,16 @@ Blockly.RenderedConnection.prototype.unhighlight = function() { /** * Set whether this connections is tracked in the database or not. * @param {boolean} doTracking If true, start tracking. If false, stop tracking. + * @package */ Blockly.RenderedConnection.prototype.setTracking = function(doTracking) { if (doTracking == this.tracked_) { return; } + if (this.sourceBlock_.isInFlyout) { + // Don't bother maintaining a database of connections in a flyout. + return; + } if (doTracking) { this.db_.addConnection(this, this.y_); } else { diff --git a/core/xml.js b/core/xml.js index 6f6478267..fde92fccd 100644 --- a/core/xml.js +++ b/core/xml.js @@ -562,7 +562,7 @@ Blockly.Xml.domToBlock = function(xmlBlock, workspace) { // Populating the connection database may be deferred until after the // blocks have rendered. setTimeout(function() { - if (!topBlock.disposed) { // Check that the block hasn't been deleted. + if (!topBlock.disposed) { topBlock.startTrackingConnections(); } }, 1);