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]]; }