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 ////////////////////////////////////////////////////////
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);
}

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,
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;

Wyświetl plik

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

Wyświetl plik

@ -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(
'<input type="@"$>$%</input>',
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] ?
'<options>' + myself.declarations[decl][2] +
myself.declarations.get(decl)[1],
myself.declarations.get(decl)[2] ?
'<options>' + myself.declarations.get(decl)[2] +
'</options>'
: ''
);

Wyświetl plik

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