diff --git a/blocks.js b/blocks.js
index b817db4c..49132c42 100644
--- a/blocks.js
+++ b/blocks.js
@@ -148,7 +148,7 @@ CustomCommandBlockMorph, SymbolMorph, ToggleButtonMorph, DialMorph*/
// Global stuff ////////////////////////////////////////////////////////
-modules.blocks = '2018-June-04';
+modules.blocks = '2018-June-06';
var SyntaxElementMorph;
var BlockMorph;
@@ -659,7 +659,7 @@ SyntaxElementMorph.prototype.refactorVarInStack = function (
if (this instanceof CustomCommandBlockMorph
&& this.definition.body
- && isNil(this.definition.declarations[oldName])
+ && isNil(this.definition.declarations.get(oldName))
&& !contains(this.definition.variableNames, oldName)) {
this.definition.body.expression.refactorVarInStack(oldName, newName);
}
diff --git a/byob.js b/byob.js
index 1675b5f3..f629f73b 100644
--- a/byob.js
+++ b/byob.js
@@ -95,7 +95,7 @@
*/
-/*global modules, CommandBlockMorph, SpriteMorph, TemplateSlotMorph,
+/*global modules, CommandBlockMorph, SpriteMorph, TemplateSlotMorph, Map,
StringMorph, Color, DialogBoxMorph, ScriptsMorph, ScrollFrameMorph,
Point, HandleMorph, HatBlockMorph, BlockMorph, detect, List, Process,
AlignmentMorph, ToggleMorph, InputFieldMorph, ReporterBlockMorph,
@@ -108,7 +108,7 @@ BooleanSlotMorph, XML_Serializer, SnapTranslator*/
// Global stuff ////////////////////////////////////////////////////////
-modules.byob = '2018-January-18';
+modules.byob = '2018-June-06';
// Declarations
@@ -140,8 +140,9 @@ function CustomBlockDefinition(spec, receiver) {
this.isGlobal = false;
this.type = 'command';
this.spec = spec || '';
- // format: {'inputName' : [type, default, options, readonly]}
- this.declarations = {};
+ this.declarations = new Map();
+ // key: inputName
+ // value: [type, default, options, isReadOnly]
this.variableNames = [];
this.comment = null;
this.codeMapping = null; // experimental, generate text code
@@ -203,7 +204,7 @@ CustomBlockDefinition.prototype.prototypeInstance = function () {
// assign slot declarations to prototype inputs
block.parts().forEach(function (part) {
if (part instanceof BlockInputFragmentMorph) {
- slot = myself.declarations[part.fragment.labelString];
+ slot = myself.declarations.get(part.fragment.labelString);
if (slot) {
part.fragment.type = slot[0];
part.fragment.defaultValue = slot[1];
@@ -223,7 +224,13 @@ CustomBlockDefinition.prototype.copyAndBindTo = function (sprite, headerOnly) {
delete c[XML_Serializer.prototype.idProperty];
c.receiver = sprite; // only for (kludgy) serialization
- c.declarations = copy(this.declarations); // might have to go deeper
+
+ // copy declarations
+ c.declarations = new Map();
+ for (var [key, val] of this.declarations) {
+ c.declarations.set(key, val);
+ }
+
if (headerOnly) { // for serializing inherited method signatures
c.body = null;
return c;
@@ -276,15 +283,15 @@ CustomBlockDefinition.prototype.helpSpec = function () {
};
CustomBlockDefinition.prototype.typeOf = function (inputName) {
- if (this.declarations[inputName]) {
- return this.declarations[inputName][0];
+ if (this.declarations.has(inputName)) {
+ return this.declarations.get(inputName)[0];
}
return '%s';
};
CustomBlockDefinition.prototype.defaultValueOf = function (inputName) {
- if (this.declarations[inputName]) {
- return this.declarations[inputName][1];
+ if (this.declarations.has(inputName)) {
+ return this.declarations.get(inputName)[1];
}
return '';
};
@@ -310,8 +317,9 @@ CustomBlockDefinition.prototype.inputOptionsOfIdx = function (idx) {
};
CustomBlockDefinition.prototype.dropDownMenuOf = function (inputName) {
- if (this.declarations[inputName] && this.declarations[inputName][2]) {
- return this.parseChoices(this.declarations[inputName][2]);
+ if (this.declarations.has(inputName) &&
+ this.declarations.get(inputName)[2]) {
+ return this.parseChoices(this.declarations.get(inputName)[2]);
}
return null;
};
@@ -336,8 +344,8 @@ CustomBlockDefinition.prototype.parseChoices = function (string) {
};
CustomBlockDefinition.prototype.isReadOnlyInput = function (inputName) {
- return this.declarations[inputName] &&
- this.declarations[inputName][3] === true;
+ return this.declarations.has(inputName) &&
+ this.declarations.get(inputName)[3] === true;
};
CustomBlockDefinition.prototype.inputOptionsOf = function (inputName) {
@@ -830,17 +838,22 @@ CustomCommandBlockMorph.prototype.blockSpecFromFragments = function () {
};
CustomCommandBlockMorph.prototype.declarationsFromFragments = function () {
- // format for type declarations: {inputName : [type, default]}
- var ans = {};
+ // returns a Map object for type declarations:
+ // key: inputName
+ // value: [type, default, options, isReadOnly]
+ var ans = new Map();
this.parts().forEach(function (part) {
if (part instanceof BlockInputFragmentMorph) {
- ans[part.fragment.labelString] = [
- part.fragment.type,
- part.fragment.defaultValue,
- part.fragment.options,
- part.fragment.isReadOnly
- ];
+ ans.set(
+ part.fragment.labelString,
+ [
+ part.fragment.type,
+ part.fragment.defaultValue,
+ part.fragment.options,
+ part.fragment.isReadOnly
+ ]
+ );
}
});
return ans;
diff --git a/history.txt b/history.txt
index 9398dc24..0b39df60 100755
--- a/history.txt
+++ b/history.txt
@@ -4131,3 +4131,4 @@ in development:
* updated German translation, thanks, Jadga!
* updated Portuguese translation, thanks, Manuel!
* new Project Cloud Backups feature, thanks, Bernat!
+* BYOB, Blocks, Threads, Store: fixed support for numerical custom block input names
diff --git a/store.js b/store.js
index 396f66ee..11111890 100644
--- a/store.js
+++ b/store.js
@@ -61,7 +61,7 @@ normalizeCanvas, contains*/
// Global stuff ////////////////////////////////////////////////////////
-modules.store = '2018-March-05';
+modules.store = '2018-June-06';
// XML_Serializer ///////////////////////////////////////////////////////
@@ -914,14 +914,17 @@ SnapSerializer.prototype.loadCustomBlocks = function (
return;
}
i += 1;
- definition.declarations[names[i]] = [
- child.attributes.type,
- contains(['%b', '%boolUE'], child.attributes.type) ?
- (child.contents ? child.contents === 'true' : null)
- : child.contents,
- options ? options.contents : undefined,
- child.attributes.readonly === 'true'
- ];
+ definition.declarations.set(
+ names[i],
+ [
+ child.attributes.type,
+ contains(['%b', '%boolUE'], child.attributes.type) ?
+ (child.contents ? child.contents === 'true' : null)
+ : child.contents,
+ options ? options.contents : undefined,
+ child.attributes.readonly === 'true'
+ ]
+ );
});
}
@@ -2010,15 +2013,16 @@ CustomBlockDefinition.prototype.toXML = function (serializer) {
this.codeHeader || '',
this.codeMapping || '',
this.translationsAsText(),
- Object.keys(this.declarations).reduce(function (xml, decl) {
+ Array.from(this.declarations.keys()).reduce(function (xml, decl) {
+ // to be refactored now that we've moved to ES6 Map:
return xml + serializer.format(
'$%',
- myself.declarations[decl][0],
- myself.declarations[decl][3] ?
+ myself.declarations.get(decl)[0],
+ myself.declarations.get(decl)[3] ?
' readonly="true"' : '',
- myself.declarations[decl][1],
- myself.declarations[decl][2] ?
- '' + myself.declarations[decl][2] +
+ myself.declarations.get(decl)[1],
+ myself.declarations.get(decl)[2] ?
+ '' + myself.declarations.get(decl)[2] +
''
: ''
);
diff --git a/threads.js b/threads.js
index a0c7d57d..02f88616 100644
--- a/threads.js
+++ b/threads.js
@@ -1397,7 +1397,7 @@ Process.prototype.evaluateCustomBlock = function () {
// if the parameter is an upvar,
// create a reference to the variable it points to
- if (declarations[context.inputs[i]][0] === '%upvar') {
+ if (declarations.get(context.inputs[i])[0] === '%upvar') {
this.context.outerContext.variables.vars[value] =
outer.variables.vars[context.inputs[i]];
}