diff --git a/core/insertion_marker_manager.ts b/core/insertion_marker_manager.ts index 7438e1cb0ff..20e27d42650 100644 --- a/core/insertion_marker_manager.ts +++ b/core/insertion_marker_manager.ts @@ -133,6 +133,11 @@ export class InsertionMarkerManager { this.firstMarker = this.createMarkerBlock(this.topBlock); this.availableConnections = this.initAvailableConnections(); + + if (this.lastOnStack) { + this.lastMarker = + this.createMarkerBlock(this.lastOnStack.getSourceBlock()); + } } /** @@ -142,18 +147,8 @@ export class InsertionMarkerManager { */ dispose() { this.availableConnections.length = 0; - - eventUtils.disable(); - try { - if (this.firstMarker) { - this.firstMarker.dispose(); - } - if (this.lastMarker) { - this.lastMarker.dispose(); - } - } finally { - eventUtils.enable(); - } + this.disposeInsertionMarker(this.firstMarker); + this.disposeInsertionMarker(this.lastMarker); } /** @@ -289,10 +284,8 @@ export class InsertionMarkerManager { } /** - * Populate the list of available connections on this block stack. This - * should only be called once, at the beginning of a drag. If the stack has - * more than one block, this function will populate lastOnStack and create - * the corresponding insertion marker. + * Populate the list of available connections on this block stack. If the + * stack has more than one block, this function will also update lastOnStack. * * @returns A list of available connections. */ @@ -303,15 +296,6 @@ export class InsertionMarkerManager { if (lastOnStack && lastOnStack !== this.topBlock.nextConnection) { available.push(lastOnStack); this.lastOnStack = lastOnStack; - if (this.lastMarker) { - eventUtils.disable(); - try { - this.lastMarker.dispose(); - } finally { - eventUtils.enable(); - } - } - this.lastMarker = this.createMarkerBlock(lastOnStack.getSourceBlock()); } return available; } @@ -561,8 +545,17 @@ export class InsertionMarkerManager { // 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); - insertionMarker = isLastInStack ? this.lastMarker : this.firstMarker; + if (isLastInStack && this.lastOnStack) { + this.disposeInsertionMarker(this.lastMarker); + this.lastMarker = + this.createMarkerBlock(this.lastOnStack.getSourceBlock()); + insertionMarker = this.lastMarker; + } else { + this.disposeInsertionMarker(this.firstMarker); + this.firstMarker = this.createMarkerBlock(this.topBlock); + insertionMarker = this.firstMarker; + } + if (!insertionMarker) { throw new Error( 'Cannot show the insertion marker because there is no insertion ' + @@ -728,6 +721,20 @@ export class InsertionMarkerManager { } return result; } + + /** + * Safely disposes of an insertion marker. + */ + private disposeInsertionMarker(marker: BlockSvg|null) { + if (marker) { + eventUtils.disable(); + try { + marker.dispose(); + } finally { + eventUtils.enable(); + } + } + } } export namespace InsertionMarkerManager {