diff --git a/core/block.js b/core/block.js index 3c2268fa9..b89c402f0 100644 --- a/core/block.js +++ b/core/block.js @@ -187,10 +187,6 @@ Blockly.Block.prototype.dispose = function(healStack) { // well as corruption of the connection database. Therefore we must // methodically step through the blocks and carefully disassemble them. - if (Blockly.selected == this) { - Blockly.selected = null; - } - // First, dispose of all my children. for (var i = this.childBlocks_.length - 1; i >= 0; i--) { this.childBlocks_[i].dispose(false); diff --git a/core/block_svg.js b/core/block_svg.js index f7727980c..2c295b9c0 100644 --- a/core/block_svg.js +++ b/core/block_svg.js @@ -935,6 +935,7 @@ Blockly.BlockSvg.prototype.dispose = function(healStack, animate) { Blockly.Field.startCache(); // If this block is being dragged, unlink the mouse events. if (Blockly.selected == this) { + this.unselect(); Blockly.terminateDrag_(); } // If this block has a context menu open, close it. diff --git a/core/events.js b/core/events.js index 417d59470..f5f7a0cd0 100644 --- a/core/events.js +++ b/core/events.js @@ -224,6 +224,21 @@ Blockly.Events.setGroup = function(state) { } }; +/** + * Compute a list of the IDs of the specified block and all its descendants. + * @param {!Blockly.Block} block The root block. + * @return {!Array.} List of block IDs. + * @private + */ +Blockly.Events.getDescendantIds_ = function(block) { + var ids = []; + var descendants = block.getDescendants(); + for (var i = 0, descendant; descendant = descendants[i]; i++) { + ids[i] = descendant.id; + } + return ids; +}; + /** * Abstract class for an event. * @param {!Blockly.Block} block The block. @@ -277,6 +292,7 @@ Blockly.Events.Abstract.prototype.run = function(forward) { Blockly.Events.Create = function(block) { Blockly.Events.Create.superClass_.constructor.call(this, block); this.xml = Blockly.Xml.blockToDomWithXY(block); + this.ids = Blockly.Events.getDescendantIds_(block); }; goog.inherits(Blockly.Events.Create, Blockly.Events.Abstract); @@ -293,6 +309,7 @@ Blockly.Events.Create.prototype.type = Blockly.Events.CREATE; Blockly.Events.Create.prototype.toJson = function() { var json = Blockly.Events.Create.superClass_.toJson.call(this); json['xml'] = Blockly.Xml.domToText(this.xml); + json['ids'] = this.ids; return json; }; @@ -307,11 +324,14 @@ Blockly.Events.Create.prototype.run = function(forward) { xml.appendChild(this.xml); Blockly.Xml.domToWorkspace(workspace, xml); } else { - var block = Blockly.Block.getById(this.blockId); - if (block) { - block.dispose(false, true); - } else { - console.warn("Can't delete non-existant block: " + this.blockId); + for (var i = 0, id; id = this.ids[i]; i++) { + var block = Blockly.Block.getById(id); + if (block) { + block.dispose(false, true); + } else if (id == this.blockId) { + // Only complain about root-level block. + console.warn("Can't uncreate non-existant block: " + id); + } } } }; @@ -328,6 +348,7 @@ Blockly.Events.Delete = function(block) { } Blockly.Events.Delete.superClass_.constructor.call(this, block); this.oldXml = Blockly.Xml.blockToDomWithXY(block); + this.ids = Blockly.Events.getDescendantIds_(block); }; goog.inherits(Blockly.Events.Delete, Blockly.Events.Abstract); @@ -337,17 +358,30 @@ goog.inherits(Blockly.Events.Delete, Blockly.Events.Abstract); */ Blockly.Events.Delete.prototype.type = Blockly.Events.DELETE; +/** + * Encode the event as JSON. + * @return {!Object} JSON representation. + */ +Blockly.Events.Delete.prototype.toJson = function() { + var json = Blockly.Events.Delete.superClass_.toJson.call(this); + json['ids'] = this.ids; + return json; +}; + /** * Run a deletion event. * @param {boolean} forward True if run forward, false if run backward (undo). */ Blockly.Events.Delete.prototype.run = function(forward) { if (forward) { - var block = Blockly.Block.getById(this.blockId); - if (block) { - block.dispose(false, true); - } else { - console.warn("Can't delete non-existant block: " + this.blockId); + for (var i = 0, id; id = this.ids[i]; i++) { + var block = Blockly.Block.getById(id); + if (block) { + block.dispose(false, true); + } else if (id == this.blockId) { + // Only complain about root-level block. + console.warn("Can't delete non-existant block: " + id); + } } } else { var workspace = Blockly.Workspace.getById(this.workspaceId);