mirror of
https://github.com/google/blockly.git
synced 2026-01-06 16:40:07 +01:00
feat: upgrade block defs to have JSO serialization hooks (#5329)
* Respect nulls from blocks.save * Upgrade list blocks to use JSO serialization * Upgrade logic blocks to use JSO serialization * Upgrade math blocks to use JSO serialization * Upgrade text blocks to use JSO serialization * Upgrade procedure blocks to use JSO serialization * Add more mutator tests * Fix firing enabled events * PR Comments
This commit is contained in:
committed by
alschmiedt
parent
bd77b4ad3d
commit
ee78b41987
@@ -131,6 +131,7 @@ Blockly.Blocks['lists_create_with'] = {
|
||||
},
|
||||
/**
|
||||
* Create XML to represent list inputs.
|
||||
* Backwards compatible serialization implementation.
|
||||
* @return {!Element} XML storage element.
|
||||
* @this {Blockly.Block}
|
||||
*/
|
||||
@@ -141,6 +142,7 @@ Blockly.Blocks['lists_create_with'] = {
|
||||
},
|
||||
/**
|
||||
* Parse XML to restore the list inputs.
|
||||
* Backwards compatible serialization implementation.
|
||||
* @param {!Element} xmlElement XML storage element.
|
||||
* @this {Blockly.Block}
|
||||
*/
|
||||
@@ -148,6 +150,23 @@ Blockly.Blocks['lists_create_with'] = {
|
||||
this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10);
|
||||
this.updateShape_();
|
||||
},
|
||||
/**
|
||||
* Returns the state of this block as a JSON serializable object.
|
||||
* @return {{itemCount: number}} The state of this block, ie the item count.
|
||||
*/
|
||||
saveExtraState: function() {
|
||||
return {
|
||||
'itemCount': this.itemCount_,
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Applies the given state to this block.
|
||||
* @param {*} state The state to apply to this block, ie the item count.
|
||||
*/
|
||||
loadExtraState: function(state) {
|
||||
this.itemCount_ = state['itemCount'];
|
||||
this.updateShape_();
|
||||
},
|
||||
/**
|
||||
* Populate the mutator's dialog with this block's components.
|
||||
* @param {!Blockly.Workspace} workspace Mutator's workspace.
|
||||
@@ -424,6 +443,12 @@ Blockly.Blocks['lists_getIndex'] = {
|
||||
var isAt = (xmlElement.getAttribute('at') != 'false');
|
||||
this.updateAt_(isAt);
|
||||
},
|
||||
|
||||
// This block does not need JSO serialization hooks (saveExtraState and
|
||||
// loadExtraState) because the state of this object is already encoded in the
|
||||
// dropdown values.
|
||||
// XML hooks are kept for backwards compatibility.
|
||||
|
||||
/**
|
||||
* Switch between a value block and a statement block.
|
||||
* @param {boolean} newStatement True if the block should be a statement.
|
||||
@@ -584,6 +609,12 @@ Blockly.Blocks['lists_setIndex'] = {
|
||||
var isAt = (xmlElement.getAttribute('at') != 'false');
|
||||
this.updateAt_(isAt);
|
||||
},
|
||||
|
||||
// This block does not need JSO serialization hooks (saveExtraState and
|
||||
// loadExtraState) because the state of this object is already encoded in the
|
||||
// dropdown values.
|
||||
// XML hooks are kept for backwards compatibility.
|
||||
|
||||
/**
|
||||
* Create or delete an input for the numeric index.
|
||||
* @param {boolean} isAt True if the input should exist.
|
||||
@@ -684,6 +715,12 @@ Blockly.Blocks['lists_getSublist'] = {
|
||||
this.updateAt_(1, isAt1);
|
||||
this.updateAt_(2, isAt2);
|
||||
},
|
||||
|
||||
// This block does not need JSO serialization hooks (saveExtraState and
|
||||
// loadExtraState) because the state of this object is already encoded in the
|
||||
// dropdown values.
|
||||
// XML hooks are kept for backwards compatibility.
|
||||
|
||||
/**
|
||||
* Create or delete an input for a numeric index.
|
||||
* This block has two such inputs, independent of each other.
|
||||
@@ -857,5 +894,10 @@ Blockly.Blocks['lists_split'] = {
|
||||
*/
|
||||
domToMutation: function(xmlElement) {
|
||||
this.updateType_(xmlElement.getAttribute('mode'));
|
||||
}
|
||||
},
|
||||
|
||||
// This block does not need JSO serialization hooks (saveExtraState and
|
||||
// loadExtraState) because the state of this object is already encoded in the
|
||||
// dropdown values.
|
||||
// XML hooks are kept for backwards compatibility.
|
||||
};
|
||||
|
||||
@@ -303,6 +303,7 @@ Blockly.Constants.Logic.CONTROLS_IF_MUTATOR_MIXIN = {
|
||||
|
||||
/**
|
||||
* Create XML to represent the number of else-if and else inputs.
|
||||
* Backwards compatible serialization implementation.
|
||||
* @return {Element} XML storage element.
|
||||
* @this {Blockly.Block}
|
||||
*/
|
||||
@@ -321,6 +322,7 @@ Blockly.Constants.Logic.CONTROLS_IF_MUTATOR_MIXIN = {
|
||||
},
|
||||
/**
|
||||
* Parse XML to restore the else-if and else inputs.
|
||||
* Backwards compatible serialization implementation.
|
||||
* @param {!Element} xmlElement XML storage element.
|
||||
* @this {Blockly.Block}
|
||||
*/
|
||||
@@ -329,6 +331,34 @@ Blockly.Constants.Logic.CONTROLS_IF_MUTATOR_MIXIN = {
|
||||
this.elseCount_ = parseInt(xmlElement.getAttribute('else'), 10) || 0;
|
||||
this.rebuildShape_();
|
||||
},
|
||||
/**
|
||||
* Returns the state of this block as a JSON serializable object.
|
||||
* @return {?{elseIfCount: (number|undefined), haseElse: (boolean|undefined)}}
|
||||
* The state of this block, ie the else if count and else state.
|
||||
*/
|
||||
saveExtraState: function() {
|
||||
if (!this.elseifCount_ && !this.elseCount_) {
|
||||
return null;
|
||||
}
|
||||
var state = Object.create(null);
|
||||
if (this.elseifCount_) {
|
||||
state['elseIfCount'] = this.elseifCount_;
|
||||
}
|
||||
if (this.elseCount_) {
|
||||
state['hasElse'] = true;
|
||||
}
|
||||
return state;
|
||||
},
|
||||
/**
|
||||
* Applies the given state to this block.
|
||||
* @param {*} state The state to apply to this block, ie the else if count and
|
||||
* else state.
|
||||
*/
|
||||
loadExtraState: function(state) {
|
||||
this.elseifCount_ = state['elseIfCount'] || 0;
|
||||
this.elseCount_ = state['hasElse'] ? 1 : 0;
|
||||
this.updateShape_();
|
||||
},
|
||||
/**
|
||||
* Populate the mutator's dialog with this block's components.
|
||||
* @param {!Blockly.Workspace} workspace Mutator's workspace.
|
||||
|
||||
@@ -446,6 +446,7 @@ Blockly.Extensions.register('math_op_tooltip',
|
||||
Blockly.Constants.Math.IS_DIVISIBLEBY_MUTATOR_MIXIN = {
|
||||
/**
|
||||
* Create XML to represent whether the 'divisorInput' should be present.
|
||||
* Backwards compatible serialization implementation.
|
||||
* @return {!Element} XML storage element.
|
||||
* @this {Blockly.Block}
|
||||
*/
|
||||
@@ -457,6 +458,7 @@ Blockly.Constants.Math.IS_DIVISIBLEBY_MUTATOR_MIXIN = {
|
||||
},
|
||||
/**
|
||||
* Parse XML to restore the 'divisorInput'.
|
||||
* Backwards compatible serialization implementation.
|
||||
* @param {!Element} xmlElement XML storage element.
|
||||
* @this {Blockly.Block}
|
||||
*/
|
||||
@@ -464,6 +466,12 @@ Blockly.Constants.Math.IS_DIVISIBLEBY_MUTATOR_MIXIN = {
|
||||
var divisorInput = (xmlElement.getAttribute('divisor_input') == 'true');
|
||||
this.updateShape_(divisorInput);
|
||||
},
|
||||
|
||||
// This block does not need JSO serialization hooks (saveExtraState and
|
||||
// loadExtraState) because the state of this object is already encoded in the
|
||||
// dropdown values.
|
||||
// XML hooks are kept for backwards compatibility.
|
||||
|
||||
/**
|
||||
* Modify this block to have (or not have) an input for 'is divisible by'.
|
||||
* @param {boolean} divisorInput True if this block has a divisor input.
|
||||
@@ -531,6 +539,7 @@ Blockly.Constants.Math.LIST_MODES_MUTATOR_MIXIN = {
|
||||
},
|
||||
/**
|
||||
* Create XML to represent the output type.
|
||||
* Backwards compatible serialization implementation.
|
||||
* @return {!Element} XML storage element.
|
||||
* @this {Blockly.Block}
|
||||
*/
|
||||
@@ -541,12 +550,18 @@ Blockly.Constants.Math.LIST_MODES_MUTATOR_MIXIN = {
|
||||
},
|
||||
/**
|
||||
* Parse XML to restore the output type.
|
||||
* Backwards compatible serialization implementation.
|
||||
* @param {!Element} xmlElement XML storage element.
|
||||
* @this {Blockly.Block}
|
||||
*/
|
||||
domToMutation: function(xmlElement) {
|
||||
this.updateType_(xmlElement.getAttribute('op'));
|
||||
}
|
||||
},
|
||||
|
||||
// This block does not need JSO serialization hooks (saveExtraState and
|
||||
// loadExtraState) because the state of this object is already encoded in the
|
||||
// dropdown values.
|
||||
// XML hooks are kept for backwards compatibility.
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -95,6 +95,7 @@ Blockly.Blocks['procedures_defnoreturn'] = {
|
||||
},
|
||||
/**
|
||||
* Create XML to represent the argument inputs.
|
||||
* Backwards compatible serialization implementation.
|
||||
* @param {boolean=} opt_paramIds If true include the IDs of the parameter
|
||||
* quarks. Used by Blockly.Procedures.mutateCallers for reconnection.
|
||||
* @return {!Element} XML storage element.
|
||||
@@ -124,6 +125,7 @@ Blockly.Blocks['procedures_defnoreturn'] = {
|
||||
},
|
||||
/**
|
||||
* Parse XML to restore the argument inputs.
|
||||
* Backwards compatible serialization implementation.
|
||||
* @param {!Element} xmlElement XML storage element.
|
||||
* @this {Blockly.Block}
|
||||
*/
|
||||
@@ -150,6 +152,54 @@ Blockly.Blocks['procedures_defnoreturn'] = {
|
||||
// Show or hide the statement input.
|
||||
this.setStatements_(xmlElement.getAttribute('statements') !== 'false');
|
||||
},
|
||||
/**
|
||||
* Returns the state of this block as a JSON serializable object.
|
||||
* @return {?{params: (!Array<{name: string, id: string}>|undefined),
|
||||
* hasStatements: (boolean|undefined)}} The state of this block, eg the
|
||||
* parameters and statements.
|
||||
*/
|
||||
saveExtraState: function() {
|
||||
if (!this.argumentVarModels_.length && this.hasStatements_) {
|
||||
return null;
|
||||
}
|
||||
var state = Object.create(null);
|
||||
if (this.argumentVarModels_.length) {
|
||||
state['params'] = [];
|
||||
for (var i = 0; i < this.argumentVarModels_.length; i++) {
|
||||
state['params'].push({
|
||||
// We don't need to serialize the name, but just in case we decide
|
||||
// to separate params from variables.
|
||||
'name': this.argumentVarModels_[i].name,
|
||||
'id': this.argumentVarModels_[i].getId()
|
||||
});
|
||||
}
|
||||
}
|
||||
if (!this.hasStatements_) {
|
||||
state['hasStatements'] = false;
|
||||
}
|
||||
return state;
|
||||
},
|
||||
/**
|
||||
* Applies the given state to this block.
|
||||
* @param {*} state The state to apply to this block, eg the parameters and
|
||||
* statements.
|
||||
*/
|
||||
loadExtraState: function(state) {
|
||||
this.arguments_ = [];
|
||||
this.argumentVarModels_ = [];
|
||||
if (state['params']) {
|
||||
for (var i = 0; i < state['params'].length; i++) {
|
||||
var param = state['params'][i];
|
||||
var variable = Blockly.Variables.getOrCreateVariablePackage(
|
||||
this.workspace, param['id'], param['name'], '');
|
||||
this.arguments_.push(variable.name);
|
||||
this.argumentVarModels_.push(variable);
|
||||
}
|
||||
}
|
||||
this.updateParams_();
|
||||
Blockly.Procedures.mutateCallers(this);
|
||||
this.setStatements_(state['hasStatements'] === false ? false : true);
|
||||
},
|
||||
/**
|
||||
* Populate the mutator's dialog with this block's components.
|
||||
* @param {!Blockly.Workspace} workspace Mutator's workspace.
|
||||
@@ -436,6 +486,8 @@ Blockly.Blocks['procedures_defreturn'] = {
|
||||
updateParams_: Blockly.Blocks['procedures_defnoreturn'].updateParams_,
|
||||
mutationToDom: Blockly.Blocks['procedures_defnoreturn'].mutationToDom,
|
||||
domToMutation: Blockly.Blocks['procedures_defnoreturn'].domToMutation,
|
||||
saveExtraState: Blockly.Blocks['procedures_defnoreturn'].saveExtraState,
|
||||
loadExtraState: Blockly.Blocks['procedures_defnoreturn'].loadExtraState,
|
||||
decompose: Blockly.Blocks['procedures_defnoreturn'].decompose,
|
||||
compose: Blockly.Blocks['procedures_defnoreturn'].compose,
|
||||
/**
|
||||
@@ -776,6 +828,7 @@ Blockly.Blocks['procedures_callnoreturn'] = {
|
||||
},
|
||||
/**
|
||||
* Create XML to represent the (non-editable) name and arguments.
|
||||
* Backwards compatible serialization implementation.
|
||||
* @return {!Element} XML storage element.
|
||||
* @this {Blockly.Block}
|
||||
*/
|
||||
@@ -791,6 +844,7 @@ Blockly.Blocks['procedures_callnoreturn'] = {
|
||||
},
|
||||
/**
|
||||
* Parse XML to restore the (non-editable) name and parameters.
|
||||
* Backwards compatible serialization implementation.
|
||||
* @param {!Element} xmlElement XML storage element.
|
||||
* @this {Blockly.Block}
|
||||
*/
|
||||
@@ -807,6 +861,34 @@ Blockly.Blocks['procedures_callnoreturn'] = {
|
||||
}
|
||||
this.setProcedureParameters_(args, paramIds);
|
||||
},
|
||||
/**
|
||||
* Returns the state of this block as a JSON serializable object.
|
||||
* @return {{name: string, params:(!Array<string>|undefined)}} The state of
|
||||
* this block, ie the params and procedure name.
|
||||
*/
|
||||
saveExtraState: function() {
|
||||
var state = Object.create(null);
|
||||
state['name'] = this.getProcedureCall();
|
||||
if (this.arguments_.length) {
|
||||
state['params'] = this.arguments_;
|
||||
}
|
||||
return state;
|
||||
},
|
||||
/**
|
||||
* Applies the given state to this block.
|
||||
* @param {*} state The state to apply to this block, ie the params and
|
||||
* procedure name.
|
||||
*/
|
||||
loadExtraState: function(state) {
|
||||
this.renameProcedure(this.getProcedureCall(), state['name']);
|
||||
const params = state['params'];
|
||||
if (params) {
|
||||
const ids = [];
|
||||
ids.length = params.length;
|
||||
ids.fill(null);
|
||||
this.setProcedureParameters_(params, ids);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Return all variables referenced by this block.
|
||||
* @return {!Array<string>} List of variable names.
|
||||
@@ -975,6 +1057,8 @@ Blockly.Blocks['procedures_callreturn'] = {
|
||||
updateShape_: Blockly.Blocks['procedures_callnoreturn'].updateShape_,
|
||||
mutationToDom: Blockly.Blocks['procedures_callnoreturn'].mutationToDom,
|
||||
domToMutation: Blockly.Blocks['procedures_callnoreturn'].domToMutation,
|
||||
saveExtraState: Blockly.Blocks['procedures_callnoreturn'].saveExtraState,
|
||||
loadExtraState: Blockly.Blocks['procedures_callnoreturn'].loadExtraState,
|
||||
getVars: Blockly.Blocks['procedures_callnoreturn'].getVars,
|
||||
getVarModels: Blockly.Blocks['procedures_callnoreturn'].getVarModels,
|
||||
onchange: Blockly.Blocks['procedures_callnoreturn'].onchange,
|
||||
@@ -1026,6 +1110,12 @@ Blockly.Blocks['procedures_ifreturn'] = {
|
||||
.appendField(Blockly.Msg['PROCEDURES_DEFRETURN_RETURN']);
|
||||
}
|
||||
},
|
||||
|
||||
// This block does not need JSO serialization hooks (saveExtraState and
|
||||
// loadExtraState) because the state of this block is already encoded in the
|
||||
// block's position in the workspace.
|
||||
// XML hooks are kept for backwards compatibility.
|
||||
|
||||
/**
|
||||
* Called whenever anything on the workspace changes.
|
||||
* Add warning if this flow block is not nested inside a loop.
|
||||
@@ -1033,7 +1123,7 @@ Blockly.Blocks['procedures_ifreturn'] = {
|
||||
* @this {Blockly.Block}
|
||||
*/
|
||||
onchange: function(_e) {
|
||||
if (!this.workspace.isDragging || this.workspace.isDragging()) {
|
||||
if (this.workspace.isDragging && this.workspace.isDragging()) {
|
||||
return; // Don't change state at the start of a drag.
|
||||
}
|
||||
var legal = false;
|
||||
|
||||
@@ -261,6 +261,7 @@ Blockly.Blocks['text_getSubstring'] = {
|
||||
},
|
||||
/**
|
||||
* Create XML to represent whether there are 'AT' inputs.
|
||||
* Backwards compatible serialization implementation.
|
||||
* @return {!Element} XML storage element.
|
||||
* @this {Blockly.Block}
|
||||
*/
|
||||
@@ -274,6 +275,7 @@ Blockly.Blocks['text_getSubstring'] = {
|
||||
},
|
||||
/**
|
||||
* Parse XML to restore the 'AT' inputs.
|
||||
* Backwards compatible serialization implementation.
|
||||
* @param {!Element} xmlElement XML storage element.
|
||||
* @this {Blockly.Block}
|
||||
*/
|
||||
@@ -283,6 +285,12 @@ Blockly.Blocks['text_getSubstring'] = {
|
||||
this.updateAt_(1, isAt1);
|
||||
this.updateAt_(2, isAt2);
|
||||
},
|
||||
|
||||
// This block does not need JSO serialization hooks (saveExtraState and
|
||||
// loadExtraState) because the state of this object is already encoded in the
|
||||
// dropdown values.
|
||||
// XML hooks are kept for backwards compatibility.
|
||||
|
||||
/**
|
||||
* Create or delete an input for a numeric index.
|
||||
* This block has two such inputs, independent of each other.
|
||||
@@ -441,6 +449,7 @@ Blockly.Blocks['text_prompt_ext'] = {
|
||||
},
|
||||
/**
|
||||
* Create XML to represent the output type.
|
||||
* Backwards compatible serialization implementation.
|
||||
* @return {!Element} XML storage element.
|
||||
* @this {Blockly.Block}
|
||||
*/
|
||||
@@ -451,12 +460,18 @@ Blockly.Blocks['text_prompt_ext'] = {
|
||||
},
|
||||
/**
|
||||
* Parse XML to restore the output type.
|
||||
* Backwards compatible serialization implementation.
|
||||
* @param {!Element} xmlElement XML storage element.
|
||||
* @this {Blockly.Block}
|
||||
*/
|
||||
domToMutation: function(xmlElement) {
|
||||
this.updateType_(xmlElement.getAttribute('type'));
|
||||
}
|
||||
},
|
||||
|
||||
// This block does not need JSO serialization hooks (saveExtraState and
|
||||
// loadExtraState) because the state of this object is already encoded in the
|
||||
// dropdown values.
|
||||
// XML hooks are kept for backwards compatibility.
|
||||
};
|
||||
|
||||
Blockly.Blocks['text_prompt'] = {
|
||||
@@ -678,6 +693,7 @@ Blockly.Constants.Text.TEXT_QUOTES_EXTENSION = function() {
|
||||
Blockly.Constants.Text.TEXT_JOIN_MUTATOR_MIXIN = {
|
||||
/**
|
||||
* Create XML to represent number of text inputs.
|
||||
* Backwards compatible serialization implementation.
|
||||
* @return {!Element} XML storage element.
|
||||
* @this {Blockly.Block}
|
||||
*/
|
||||
@@ -688,6 +704,7 @@ Blockly.Constants.Text.TEXT_JOIN_MUTATOR_MIXIN = {
|
||||
},
|
||||
/**
|
||||
* Parse XML to restore the text inputs.
|
||||
* Backwards compatible serialization implementation.
|
||||
* @param {!Element} xmlElement XML storage element.
|
||||
* @this {Blockly.Block}
|
||||
*/
|
||||
@@ -695,6 +712,23 @@ Blockly.Constants.Text.TEXT_JOIN_MUTATOR_MIXIN = {
|
||||
this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10);
|
||||
this.updateShape_();
|
||||
},
|
||||
/**
|
||||
* Returns the state of this block as a JSON serializable object.
|
||||
* @return {{itemCount: number}} The state of this block, ie the item count.
|
||||
*/
|
||||
saveExtraState: function() {
|
||||
return {
|
||||
'itemCount': this.itemCount_,
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Applies the given state to this block.
|
||||
* @param {*} state The state to apply to this block, ie the item count.
|
||||
*/
|
||||
loadExtraState: function(state) {
|
||||
this.itemCount_ = state['itemCount'];
|
||||
this.updateShape_();
|
||||
},
|
||||
/**
|
||||
* Populate the mutator's dialog with this block's components.
|
||||
* @param {!Blockly.Workspace} workspace Mutator's workspace.
|
||||
@@ -829,6 +863,7 @@ Blockly.Constants.Text.TEXT_INDEXOF_TOOLTIP_EXTENSION = function() {
|
||||
Blockly.Constants.Text.TEXT_CHARAT_MUTATOR_MIXIN = {
|
||||
/**
|
||||
* Create XML to represent whether there is an 'AT' input.
|
||||
* Backwards compatible serialization implementation.
|
||||
* @return {!Element} XML storage element.
|
||||
* @this {Blockly.Block}
|
||||
*/
|
||||
@@ -839,6 +874,7 @@ Blockly.Constants.Text.TEXT_CHARAT_MUTATOR_MIXIN = {
|
||||
},
|
||||
/**
|
||||
* Parse XML to restore the 'AT' input.
|
||||
* Backwards compatible serialization implementation.
|
||||
* @param {!Element} xmlElement XML storage element.
|
||||
* @this {Blockly.Block}
|
||||
*/
|
||||
@@ -848,6 +884,12 @@ Blockly.Constants.Text.TEXT_CHARAT_MUTATOR_MIXIN = {
|
||||
var isAt = (xmlElement.getAttribute('at') != 'false');
|
||||
this.updateAt_(isAt);
|
||||
},
|
||||
|
||||
// This block does not need JSO serialization hooks (saveExtraState and
|
||||
// loadExtraState) because the state of this object is already encoded in the
|
||||
// dropdown values.
|
||||
// XML hooks are kept for backwards compatibility.
|
||||
|
||||
/**
|
||||
* Create or delete an input for the numeric index.
|
||||
* @param {boolean} isAt True if the input should exist.
|
||||
|
||||
@@ -1335,9 +1335,10 @@ Block.prototype.isEnabled = function() {
|
||||
*/
|
||||
Block.prototype.setEnabled = function(enabled) {
|
||||
if (this.isEnabled() != enabled) {
|
||||
Events.fire(new (Events.get(Events.BLOCK_CHANGE))(
|
||||
this, 'disabled', null, this.disabled, !enabled));
|
||||
const oldValue = this.disabled;
|
||||
this.disabled = !enabled;
|
||||
Events.fire(new (Events.get(Events.BLOCK_CHANGE))(
|
||||
this, 'disabled', null, oldValue, !enabled));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -41,8 +41,7 @@ const save = function(workspace) {
|
||||
|
||||
const blockStates = [];
|
||||
for (let block of workspace.getTopBlocks(false)) {
|
||||
const blockState =
|
||||
blocks.save(block, {addCoordinates: true});
|
||||
const blockState = blocks.save(block, {addCoordinates: true});
|
||||
if (blockState) {
|
||||
blockStates.push(blockState);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
goog.addDependency('../../blocks/colour.js', ['Blockly.Blocks.colour', 'Blockly.Constants.Colour'], ['Blockly', 'Blockly.Blocks', 'Blockly.FieldColour', 'Blockly.FieldLabel']);
|
||||
goog.addDependency('../../blocks/lists.js', ['Blockly.Constants.Lists'], ['Blockly', 'Blockly.Blocks', 'Blockly.FieldDropdown', 'Blockly.FieldLabel', 'Blockly.Mutator']);
|
||||
goog.addDependency('../../blocks/lists.js', ['Blockly.Constants.Lists'], ['Blockly', 'Blockly.Blocks', 'Blockly.FieldDropdown', 'Blockly.FieldLabel', 'Blockly.Mutator'], {'lang': 'es5'});
|
||||
goog.addDependency('../../blocks/logic.js', ['Blockly.Blocks.logic', 'Blockly.Constants.Logic'], ['Blockly', 'Blockly.Blocks', 'Blockly.FieldDropdown', 'Blockly.FieldLabel', 'Blockly.Mutator']);
|
||||
goog.addDependency('../../blocks/loops.js', ['Blockly.Blocks.loops', 'Blockly.Constants.Loops'], ['Blockly', 'Blockly.Blocks', 'Blockly.FieldDropdown', 'Blockly.FieldLabel', 'Blockly.FieldNumber', 'Blockly.FieldVariable', 'Blockly.Warning']);
|
||||
goog.addDependency('../../blocks/math.js', ['Blockly.Blocks.math', 'Blockly.Constants.Math'], ['Blockly', 'Blockly.Blocks', 'Blockly.FieldDropdown', 'Blockly.FieldLabel', 'Blockly.FieldNumber', 'Blockly.FieldVariable']);
|
||||
goog.addDependency('../../blocks/procedures.js', ['Blockly.Blocks.procedures'], ['Blockly', 'Blockly.Blocks', 'Blockly.Comment', 'Blockly.FieldCheckbox', 'Blockly.FieldLabel', 'Blockly.FieldTextInput', 'Blockly.Mutator', 'Blockly.Warning'], {'lang': 'es5'});
|
||||
goog.addDependency('../../blocks/text.js', ['Blockly.Blocks.texts', 'Blockly.Constants.Text'], ['Blockly', 'Blockly.Blocks', 'Blockly.FieldDropdown', 'Blockly.FieldImage', 'Blockly.FieldMultilineInput', 'Blockly.FieldTextInput', 'Blockly.FieldVariable', 'Blockly.Mutator']);
|
||||
goog.addDependency('../../blocks/math.js', ['Blockly.Blocks.math', 'Blockly.Constants.Math'], ['Blockly', 'Blockly.Blocks', 'Blockly.FieldDropdown', 'Blockly.FieldLabel', 'Blockly.FieldNumber', 'Blockly.FieldVariable'], {'lang': 'es5'});
|
||||
goog.addDependency('../../blocks/procedures.js', ['Blockly.Blocks.procedures'], ['Blockly', 'Blockly.Blocks', 'Blockly.Comment', 'Blockly.FieldCheckbox', 'Blockly.FieldLabel', 'Blockly.FieldTextInput', 'Blockly.Mutator', 'Blockly.Warning'], {'lang': 'es6'});
|
||||
goog.addDependency('../../blocks/text.js', ['Blockly.Blocks.texts', 'Blockly.Constants.Text'], ['Blockly', 'Blockly.Blocks', 'Blockly.FieldDropdown', 'Blockly.FieldImage', 'Blockly.FieldMultilineInput', 'Blockly.FieldTextInput', 'Blockly.FieldVariable', 'Blockly.Mutator'], {'lang': 'es5'});
|
||||
goog.addDependency('../../blocks/variables.js', ['Blockly.Blocks.variables', 'Blockly.Constants.Variables'], ['Blockly', 'Blockly.Blocks', 'Blockly.FieldLabel', 'Blockly.FieldVariable']);
|
||||
goog.addDependency('../../blocks/variables_dynamic.js', ['Blockly.Constants.VariablesDynamic'], ['Blockly', 'Blockly.Blocks', 'Blockly.FieldLabel', 'Blockly.FieldVariable']);
|
||||
goog.addDependency('../../core/block.js', ['Blockly.Block'], ['Blockly.ASTNode', 'Blockly.Blocks', 'Blockly.Connection', 'Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Events.BlockCreate', 'Blockly.Events.BlockDelete', 'Blockly.Events.BlockMove', 'Blockly.Extensions', 'Blockly.Input', 'Blockly.Tooltip', 'Blockly.common', 'Blockly.connectionTypes', 'Blockly.constants', 'Blockly.fieldRegistry', 'Blockly.inputTypes', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Size', 'Blockly.utils.idGenerator', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'});
|
||||
|
||||
@@ -1313,6 +1313,30 @@ Serializer.Connections.testSuites = [
|
||||
];
|
||||
|
||||
Serializer.Mutations = new SerializerTestSuite('Mutations');
|
||||
Serializer.Mutations.ListGetIndex = new SerializerTestCase('ListGetIndex',
|
||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
||||
'<block type="lists_getIndex" id="id" x="42" y="42">' +
|
||||
'<mutation statement="true" at="false"></mutation>' +
|
||||
'<field name="MODE">REMOVE</field>' +
|
||||
'<field name="WHERE">LAST</field>' +
|
||||
'</block>' +
|
||||
'</xml>');
|
||||
Serializer.Mutations.ListSetIndex = new SerializerTestCase('ListSetIndex',
|
||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
||||
'<block type="lists_setIndex" id="id" x="42" y="42">' +
|
||||
'<mutation at="false"></mutation>' +
|
||||
'<field name="MODE">SET</field>' +
|
||||
'<field name="WHERE">LAST</field>' +
|
||||
'</block>' +
|
||||
'</xml>');
|
||||
Serializer.Mutations.ListGetSublist = new SerializerTestCase('ListGetSublist',
|
||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
||||
'<block type="lists_getSublist" id="id" x="42" y="42">' +
|
||||
'<mutation at1="false" at2="false"></mutation>' +
|
||||
'<field name="WHERE1">FIRST</field>' +
|
||||
'<field name="WHERE2">LAST</field>' +
|
||||
'</block>' +
|
||||
'</xml>');
|
||||
Serializer.Mutations.MathNumberProperty = new SerializerTestCase(
|
||||
'MathNumberProperty',
|
||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
||||
@@ -1371,6 +1395,9 @@ Serializer.Mutations.TextPrompt = new SerializerTestCase(
|
||||
'</block>' +
|
||||
'</xml>');
|
||||
Serializer.Mutations.testCases = [
|
||||
Serializer.Mutations.ListGetIndex,
|
||||
Serializer.Mutations.ListSetIndex,
|
||||
Serializer.Mutations.ListGetSublist,
|
||||
Serializer.Mutations.MathNumberProperty,
|
||||
Serializer.Mutations.MathOnList,
|
||||
Serializer.Mutations.TextJoin,
|
||||
@@ -1621,10 +1648,45 @@ Serializer.Mutations.Procedure.NoStatements = new SerializerTestCase(
|
||||
'<field name="NAME">do something</field>' +
|
||||
'</block>' +
|
||||
'</xml>');
|
||||
Serializer.Mutations.Procedure.IfReturn = new SerializerTestCase(
|
||||
'IfReturn',
|
||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
||||
'<block type="procedures_defnoreturn" id="id" x="42" y="42">' +
|
||||
'<field name="NAME">do something</field>' +
|
||||
'<statement name="STACK">' +
|
||||
'<block type="procedures_ifreturn" id="id2">' +
|
||||
'<mutation value="0"></mutation>' +
|
||||
'</block>' +
|
||||
'</statement>' +
|
||||
'</block>' +
|
||||
'</xml>');
|
||||
Serializer.Mutations.Procedure.Caller = new SerializerTestCase(
|
||||
'Caller',
|
||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
||||
'<variables>' +
|
||||
'<variable id="aaaaaaaaaaaaaaaaaaaa">x</variable>' +
|
||||
'<variable id="bbbbbbbbbbbbbbbbbbbb">y</variable>' +
|
||||
'</variables>' +
|
||||
'<block type="procedures_defreturn" id="id2*****************" x="42" y="42">' +
|
||||
'<mutation>' +
|
||||
'<arg name="x" varid="aaaaaaaaaaaaaaaaaaaa"></arg>' +
|
||||
'<arg name="y" varid="bbbbbbbbbbbbbbbbbbbb"></arg>' +
|
||||
'</mutation>' +
|
||||
'<field name="NAME">do something</field>' +
|
||||
'</block>' +
|
||||
'<block type="procedures_callreturn" id="id******************" x="52" y="52">' +
|
||||
'<mutation name="do something">' +
|
||||
'<arg name="x"></arg>' +
|
||||
'<arg name="y"></arg>' +
|
||||
'</mutation>' +
|
||||
'</block>' +
|
||||
'</xml>');
|
||||
Serializer.Mutations.Procedure.testCases = [
|
||||
Serializer.Mutations.Procedure.NoMutation,
|
||||
Serializer.Mutations.Procedure.Variables,
|
||||
Serializer.Mutations.Procedure.NoStatements,
|
||||
Serializer.Mutations.Procedure.IfReturn,
|
||||
Serializer.Mutations.Procedure.Caller,
|
||||
];
|
||||
|
||||
Serializer.Mutations.Procedure.Names = new SerializerTestSuite('Names');
|
||||
@@ -1773,5 +1835,4 @@ var runSerializerTestSuite = (serializer, deserializer, testSuite) => {
|
||||
|
||||
runSerializerTestSuite(null, null, Serializer);
|
||||
Serializer.Icons.skip = true;
|
||||
Serializer.Mutations.skip = true;
|
||||
runSerializerTestSuite(state => state, state => state, Serializer);
|
||||
|
||||
Reference in New Issue
Block a user