diff --git a/snap.html b/snap.html
index eae589b8..fc3f3e4a 100755
--- a/snap.html
+++ b/snap.html
@@ -7,7 +7,7 @@
-
+
diff --git a/src/blocks.js b/src/blocks.js
index 39bcb487..a2d60cc1 100644
--- a/src/blocks.js
+++ b/src/blocks.js
@@ -148,7 +148,7 @@ CustomCommandBlockMorph, SymbolMorph, ToggleButtonMorph, DialMorph*/
// Global stuff ////////////////////////////////////////////////////////
-modules.blocks = '2020-June-15';
+modules.blocks = '2020-June-19';
var SyntaxElementMorph;
var BlockMorph;
@@ -3173,6 +3173,10 @@ BlockMorph.prototype.unringify = function () {
};
BlockMorph.prototype.relabel = function (alternativeSelectors) {
+ // morph one block into another trying to keep the inputs in place
+ // alternative Selector can either be a string representing
+ // a block selector or a 2-item array containing a string and
+ // an integer offset for restoring inputs
var menu, oldInputs,
target = this.selectForEdit(); // copy-on-edit
if (target !== this) {
@@ -3180,14 +3184,22 @@ BlockMorph.prototype.relabel = function (alternativeSelectors) {
}
menu = new MenuMorph(this);
oldInputs = this.inputs();
- alternativeSelectors.forEach(sel => {
- var block = SpriteMorph.prototype.blockForSelector(sel);
- block.restoreInputs(oldInputs);
+ alternativeSelectors.forEach(alternative => {
+ var block, selector, offset;
+ if (alternative instanceof Array) {
+ selector = alternative[0];
+ offset = -alternative[1];
+ } else {
+ selector = alternative;
+ offset = 0;
+ }
+ block = SpriteMorph.prototype.blockForSelector(selector);
+ block.restoreInputs(oldInputs, offset);
block.fixBlockColor(null, true);
block.addShadow(new Point(3, 3));
menu.addItem(
block.fullImage(),
- () => this.setSelector(sel)
+ () => this.setSelector(selector, -offset)
);
});
menu.popup(this.world(), this.bottomLeft().subtract(new Point(
@@ -3196,8 +3208,11 @@ BlockMorph.prototype.relabel = function (alternativeSelectors) {
)));
};
-BlockMorph.prototype.setSelector = function (aSelector) {
+
+BlockMorph.prototype.setSelector = function (aSelector, inputOffset = 0) {
// private - used only for relabel()
+ // input offset is optional and can be used to shift the inputs
+ // to be restored
var oldInputs = this.inputs(),
scripts = this.parentThatIsA(ScriptsMorph),
surplus,
@@ -3206,7 +3221,7 @@ BlockMorph.prototype.setSelector = function (aSelector) {
this.setCategory(info.category);
this.selector = aSelector;
this.setSpec(localize(info.spec));
- surplus = this.restoreInputs(oldInputs);
+ surplus = this.restoreInputs(oldInputs, -inputOffset);
this.fixLabelColor();
// place surplus blocks on scipts
@@ -3218,17 +3233,31 @@ BlockMorph.prototype.setSelector = function (aSelector) {
}
};
-BlockMorph.prototype.restoreInputs = function (oldInputs) {
+BlockMorph.prototype.restoreInputs = function (oldInputs, offset = 0) {
// private - used only for relabel()
// try to restore my previous inputs when my spec has been changed
// return an Array of left-over blocks, if any
- var i = 0,
- old,
- nb,
+ // optional offset parameter allows for shifting the range
+ // of inputs to be restored
+ var old, nb, i,
leftOver = [];
- this.inputs().forEach(inp => {
+ // gather leading surplus blocks
+ for (i = 0; i < offset; i += 1) {
old = oldInputs[i];
+ if (old instanceof ReporterBlockMorph) {
+ leftOver.push(old);
+ } else if (old instanceof CommandSlotMorph) {
+ nb = old.nestedBlock();
+ if (nb) {
+ leftOver.push(nb);
+ }
+ }
+ }
+
+ // restore matching inputs in their original order
+ this.inputs().forEach(inp => {
+ old = oldInputs[offset];
if (old instanceof ReporterBlockMorph) {
this.replaceInput(inp, old.fullCopy());
} else if (old && inp instanceof InputSlotMorph) {
@@ -3247,12 +3276,12 @@ BlockMorph.prototype.restoreInputs = function (oldInputs) {
inp.nestedBlock(nb.fullCopy());
}
}
- i += 1;
+ offset += 1;
});
- // gather surplus blocks
- for (i; i < oldInputs.length; i += 1) {
- old = oldInputs[i];
+ // gather trailing surplus blocks
+ for (offset; offset < oldInputs.length; offset += 1) {
+ old = oldInputs[offset];
if (old instanceof ReporterBlockMorph) {
leftOver.push(old);
} else if (old instanceof CommandSlotMorph) {