fixed support for numerical custom block input names

upd4.2
jmoenig 2018-06-06 18:13:36 +02:00
rodzic 05fed02018
commit 0731192941
5 zmienionych plików z 58 dodań i 40 usunięć

Wyświetl plik

@ -148,7 +148,7 @@ CustomCommandBlockMorph, SymbolMorph, ToggleButtonMorph, DialMorph*/
// Global stuff //////////////////////////////////////////////////////// // Global stuff ////////////////////////////////////////////////////////
modules.blocks = '2018-June-04'; modules.blocks = '2018-June-06';
var SyntaxElementMorph; var SyntaxElementMorph;
var BlockMorph; var BlockMorph;
@ -659,7 +659,7 @@ SyntaxElementMorph.prototype.refactorVarInStack = function (
if (this instanceof CustomCommandBlockMorph if (this instanceof CustomCommandBlockMorph
&& this.definition.body && this.definition.body
&& isNil(this.definition.declarations[oldName]) && isNil(this.definition.declarations.get(oldName))
&& !contains(this.definition.variableNames, oldName)) { && !contains(this.definition.variableNames, oldName)) {
this.definition.body.expression.refactorVarInStack(oldName, newName); this.definition.body.expression.refactorVarInStack(oldName, newName);
} }

57
byob.js
Wyświetl plik

@ -95,7 +95,7 @@
*/ */
/*global modules, CommandBlockMorph, SpriteMorph, TemplateSlotMorph, /*global modules, CommandBlockMorph, SpriteMorph, TemplateSlotMorph, Map,
StringMorph, Color, DialogBoxMorph, ScriptsMorph, ScrollFrameMorph, StringMorph, Color, DialogBoxMorph, ScriptsMorph, ScrollFrameMorph,
Point, HandleMorph, HatBlockMorph, BlockMorph, detect, List, Process, Point, HandleMorph, HatBlockMorph, BlockMorph, detect, List, Process,
AlignmentMorph, ToggleMorph, InputFieldMorph, ReporterBlockMorph, AlignmentMorph, ToggleMorph, InputFieldMorph, ReporterBlockMorph,
@ -108,7 +108,7 @@ BooleanSlotMorph, XML_Serializer, SnapTranslator*/
// Global stuff //////////////////////////////////////////////////////// // Global stuff ////////////////////////////////////////////////////////
modules.byob = '2018-January-18'; modules.byob = '2018-June-06';
// Declarations // Declarations
@ -140,8 +140,9 @@ function CustomBlockDefinition(spec, receiver) {
this.isGlobal = false; this.isGlobal = false;
this.type = 'command'; this.type = 'command';
this.spec = spec || ''; this.spec = spec || '';
// format: {'inputName' : [type, default, options, readonly]} this.declarations = new Map();
this.declarations = {}; // key: inputName
// value: [type, default, options, isReadOnly]
this.variableNames = []; this.variableNames = [];
this.comment = null; this.comment = null;
this.codeMapping = null; // experimental, generate text code this.codeMapping = null; // experimental, generate text code
@ -203,7 +204,7 @@ CustomBlockDefinition.prototype.prototypeInstance = function () {
// assign slot declarations to prototype inputs // assign slot declarations to prototype inputs
block.parts().forEach(function (part) { block.parts().forEach(function (part) {
if (part instanceof BlockInputFragmentMorph) { if (part instanceof BlockInputFragmentMorph) {
slot = myself.declarations[part.fragment.labelString]; slot = myself.declarations.get(part.fragment.labelString);
if (slot) { if (slot) {
part.fragment.type = slot[0]; part.fragment.type = slot[0];
part.fragment.defaultValue = slot[1]; part.fragment.defaultValue = slot[1];
@ -223,7 +224,13 @@ CustomBlockDefinition.prototype.copyAndBindTo = function (sprite, headerOnly) {
delete c[XML_Serializer.prototype.idProperty]; delete c[XML_Serializer.prototype.idProperty];
c.receiver = sprite; // only for (kludgy) serialization 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 if (headerOnly) { // for serializing inherited method signatures
c.body = null; c.body = null;
return c; return c;
@ -276,15 +283,15 @@ CustomBlockDefinition.prototype.helpSpec = function () {
}; };
CustomBlockDefinition.prototype.typeOf = function (inputName) { CustomBlockDefinition.prototype.typeOf = function (inputName) {
if (this.declarations[inputName]) { if (this.declarations.has(inputName)) {
return this.declarations[inputName][0]; return this.declarations.get(inputName)[0];
} }
return '%s'; return '%s';
}; };
CustomBlockDefinition.prototype.defaultValueOf = function (inputName) { CustomBlockDefinition.prototype.defaultValueOf = function (inputName) {
if (this.declarations[inputName]) { if (this.declarations.has(inputName)) {
return this.declarations[inputName][1]; return this.declarations.get(inputName)[1];
} }
return ''; return '';
}; };
@ -310,8 +317,9 @@ CustomBlockDefinition.prototype.inputOptionsOfIdx = function (idx) {
}; };
CustomBlockDefinition.prototype.dropDownMenuOf = function (inputName) { CustomBlockDefinition.prototype.dropDownMenuOf = function (inputName) {
if (this.declarations[inputName] && this.declarations[inputName][2]) { if (this.declarations.has(inputName) &&
return this.parseChoices(this.declarations[inputName][2]); this.declarations.get(inputName)[2]) {
return this.parseChoices(this.declarations.get(inputName)[2]);
} }
return null; return null;
}; };
@ -336,8 +344,8 @@ CustomBlockDefinition.prototype.parseChoices = function (string) {
}; };
CustomBlockDefinition.prototype.isReadOnlyInput = function (inputName) { CustomBlockDefinition.prototype.isReadOnlyInput = function (inputName) {
return this.declarations[inputName] && return this.declarations.has(inputName) &&
this.declarations[inputName][3] === true; this.declarations.get(inputName)[3] === true;
}; };
CustomBlockDefinition.prototype.inputOptionsOf = function (inputName) { CustomBlockDefinition.prototype.inputOptionsOf = function (inputName) {
@ -830,17 +838,22 @@ CustomCommandBlockMorph.prototype.blockSpecFromFragments = function () {
}; };
CustomCommandBlockMorph.prototype.declarationsFromFragments = function () { CustomCommandBlockMorph.prototype.declarationsFromFragments = function () {
// format for type declarations: {inputName : [type, default]} // returns a Map object for type declarations:
var ans = {}; // key: inputName
// value: [type, default, options, isReadOnly]
var ans = new Map();
this.parts().forEach(function (part) { this.parts().forEach(function (part) {
if (part instanceof BlockInputFragmentMorph) { if (part instanceof BlockInputFragmentMorph) {
ans[part.fragment.labelString] = [ ans.set(
part.fragment.type, part.fragment.labelString,
part.fragment.defaultValue, [
part.fragment.options, part.fragment.type,
part.fragment.isReadOnly part.fragment.defaultValue,
]; part.fragment.options,
part.fragment.isReadOnly
]
);
} }
}); });
return ans; return ans;

Wyświetl plik

@ -4131,3 +4131,4 @@ in development:
* updated German translation, thanks, Jadga! * updated German translation, thanks, Jadga!
* updated Portuguese translation, thanks, Manuel! * updated Portuguese translation, thanks, Manuel!
* new Project Cloud Backups feature, thanks, Bernat! * new Project Cloud Backups feature, thanks, Bernat!
* BYOB, Blocks, Threads, Store: fixed support for numerical custom block input names

Wyświetl plik

@ -61,7 +61,7 @@ normalizeCanvas, contains*/
// Global stuff //////////////////////////////////////////////////////// // Global stuff ////////////////////////////////////////////////////////
modules.store = '2018-March-05'; modules.store = '2018-June-06';
// XML_Serializer /////////////////////////////////////////////////////// // XML_Serializer ///////////////////////////////////////////////////////
@ -914,14 +914,17 @@ SnapSerializer.prototype.loadCustomBlocks = function (
return; return;
} }
i += 1; i += 1;
definition.declarations[names[i]] = [ definition.declarations.set(
child.attributes.type, names[i],
contains(['%b', '%boolUE'], child.attributes.type) ? [
(child.contents ? child.contents === 'true' : null) child.attributes.type,
: child.contents, contains(['%b', '%boolUE'], child.attributes.type) ?
options ? options.contents : undefined, (child.contents ? child.contents === 'true' : null)
child.attributes.readonly === 'true' : child.contents,
]; options ? options.contents : undefined,
child.attributes.readonly === 'true'
]
);
}); });
} }
@ -2010,15 +2013,16 @@ CustomBlockDefinition.prototype.toXML = function (serializer) {
this.codeHeader || '', this.codeHeader || '',
this.codeMapping || '', this.codeMapping || '',
this.translationsAsText(), 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( return xml + serializer.format(
'<input type="@"$>$%</input>', '<input type="@"$>$%</input>',
myself.declarations[decl][0], myself.declarations.get(decl)[0],
myself.declarations[decl][3] ? myself.declarations.get(decl)[3] ?
' readonly="true"' : '', ' readonly="true"' : '',
myself.declarations[decl][1], myself.declarations.get(decl)[1],
myself.declarations[decl][2] ? myself.declarations.get(decl)[2] ?
'<options>' + myself.declarations[decl][2] + '<options>' + myself.declarations.get(decl)[2] +
'</options>' '</options>'
: '' : ''
); );

Wyświetl plik

@ -1397,7 +1397,7 @@ Process.prototype.evaluateCustomBlock = function () {
// if the parameter is an upvar, // if the parameter is an upvar,
// create a reference to the variable it points to // 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] = this.context.outerContext.variables.vars[value] =
outer.variables.vars[context.inputs[i]]; outer.variables.vars[context.inputs[i]];
} }