Add list of ids to create/delete events for robustness.

This commit is contained in:
Neil Fraser
2016-03-28 18:10:54 -07:00
parent f549744bf0
commit 741491347b
3 changed files with 45 additions and 14 deletions

View File

@@ -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);

View File

@@ -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.

View File

@@ -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.<string>} 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);