From 68d81132b851d20884ee9da41719fa62cdfce0ee Mon Sep 17 00:00:00 2001 From: Mark Friedman Date: Wed, 15 Dec 2021 15:46:17 -0800 Subject: [PATCH] fix: change getCandidate_ and showInsertionMarker_ to be more dynamic (#5722) * Change getCandidate_ and showInsertionMarker_ to be more dynamic * Ran clang formatter * Fix typos * Fix issue with dragging stacks * From PR comment --- core/insertion_marker_manager.js | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/core/insertion_marker_manager.js b/core/insertion_marker_manager.js index df86ecc8c89..b2592d491de 100644 --- a/core/insertion_marker_manager.js +++ b/core/insertion_marker_manager.js @@ -431,6 +431,16 @@ InsertionMarkerManager.prototype.getCandidate_ = function(dxy) { let candidateClosest = null; let candidateLocal = null; + // It's possible that a block has added or removed connections during a drag, + // (e.g. in a drag/move event handler), so let's update the available + // connections. Note that this will be called on every move while dragging, so + // it might cause slowness, especially if the block stack is large. If so, + // maybe it could be made more efficient. Also note that we won't update the + // connections if we've already connected the insertion marker to a block. + if (!this.markerConnection_ || !this.markerConnection_.isConnected()) { + this.updateAvailableConnections(); + } + for (let i = 0; i < this.availableConnections_.length; i++) { const myConnection = this.availableConnections_[i]; const neighbour = myConnection.closest(radius, dxy); @@ -617,8 +627,21 @@ InsertionMarkerManager.prototype.showInsertionMarker_ = function() { const closest = this.closestConnection_; const isLastInStack = this.lastOnStack_ && local === this.lastOnStack_; - const imBlock = isLastInStack ? this.lastMarker_ : this.firstMarker_; - const imConn = imBlock.getMatchingConnection(local.getSourceBlock(), local); + let imBlock = isLastInStack ? this.lastMarker_ : this.firstMarker_; + let imConn; + try { + imConn = imBlock.getMatchingConnection(local.getSourceBlock(), local); + } catch (e) { + // It's possible that the number of connections on the local block has + // changed since the insertion marker was originally created. Let's + // recreate the insertion marker and try again. In theory we could probably + // recreate the marker block (e.g. in getCandidate_), which is called more + // often during the drag, but creating a block that often might be too slow, + // so we only do it if necessary. + this.firstMarker_ = this.createMarkerBlock_(this.topBlock_); + imBlock = isLastInStack ? this.lastMarker_ : this.firstMarker_; + imConn = imBlock.getMatchingConnection(local.getSourceBlock(), local); + } if (imConn === this.markerConnection_) { throw Error(