Connecting block to parent in domToBlockHeadless_ (#4461)

* Attaching parent before setting field values when processing xml
This commit is contained in:
Monica Kozbial
2021-01-20 09:48:37 -08:00
committed by GitHub
parent a3adc42e8a
commit c94f40d02b
2 changed files with 51 additions and 17 deletions

View File

@@ -156,6 +156,20 @@ Blockly.FieldDropdown.fromJson = function(options) {
return new Blockly.FieldDropdown(options['options'], undefined, options);
};
/**
* Sets the field's value based on the given XML element. Should only be
* called by Blockly.Xml.
* @param {!Element} fieldElement The element containing info about the
* field's state.
* @package
*/
Blockly.FieldDropdown.prototype.fromXml = function(fieldElement) {
if (this.isOptionListDynamic()) {
this.getOptions(false);
}
this.setValue(fieldElement.textContent);
};
/**
* Serializable fields are saved by the XML renderer, non-serializable fields
* are not. Editable fields should also be serializable.

View File

@@ -741,6 +741,7 @@ Blockly.Xml.applyDataTagNodes_ = function(xmlChildren, block) {
block.data = xmlChild.textContent;
}
};
/**
* Applies field tag child nodes to the given block.
* @param {Array<!Element>} xmlChildren Child nodes.
@@ -796,17 +797,11 @@ Blockly.Xml.applyInputTagNodes_ = function(xmlChildren, workspace, block,
}
var childBlockInfo = Blockly.Xml.findChildBlocks_(xmlChild);
if (childBlockInfo.childBlockElement) {
// Create child block.
var blockChild = Blockly.Xml.domToBlockHeadless_(
childBlockInfo.childBlockElement, workspace);
if (blockChild.outputConnection) {
input.connection.connect(blockChild.outputConnection);
} else if (blockChild.previousConnection) {
input.connection.connect(blockChild.previousConnection);
} else {
throw TypeError(
'Child block does not have output or previous statement.');
if (!input.connection) {
throw TypeError('Input connection does not exist.');
}
Blockly.Xml.domToBlockHeadless_(childBlockInfo.childBlockElement,
workspace, input.connection, false);
}
// Set shadow after so we don't create a shadow we delete immediately.
if (childBlockInfo.childShadowElement) {
@@ -834,12 +829,10 @@ Blockly.Xml.applyNextTagNodes_ = function(xmlChildren, workspace, block) {
if (block.nextConnection.isConnected()) {
throw TypeError('Next statement is already connected.');
}
var blockChild = Blockly.Xml.domToBlockHeadless_(
childBlockInfo.childBlockElement, workspace);
if (!blockChild.previousConnection) {
throw TypeError('Next block does not have previous statement.');
}
block.nextConnection.connect(blockChild.previousConnection);
// Create child block.
Blockly.Xml.domToBlockHeadless_(childBlockInfo.childBlockElement,
workspace, block.nextConnection,
true);
}
// Set shadow after so we don't create a shadow we delete immediately.
if (childBlockInfo.childShadowElement && block.nextConnection) {
@@ -854,10 +847,15 @@ Blockly.Xml.applyNextTagNodes_ = function(xmlChildren, workspace, block) {
* workspace.
* @param {!Element} xmlBlock XML block element.
* @param {!Blockly.Workspace} workspace The workspace.
* @param {!Blockly.Connection=} parentConnection The parent connection to
* to connect this block to after instantiating.
* @param {boolean=} connectedToParentNext Whether the provided parent connection
* is a next connection, rather than output or statement.
* @return {!Blockly.Block} The root block created.
* @private
*/
Blockly.Xml.domToBlockHeadless_ = function(xmlBlock, workspace) {
Blockly.Xml.domToBlockHeadless_ = function(xmlBlock, workspace,
parentConnection, connectedToParentNext) {
var block = null;
var prototypeName = xmlBlock.getAttribute('type');
if (!prototypeName) {
@@ -873,6 +871,28 @@ Blockly.Xml.domToBlockHeadless_ = function(xmlBlock, workspace) {
Blockly.Xml.applyMutationTagNodes_(xmlChildNameMap.mutation, block);
Blockly.Xml.applyCommentTagNodes_(xmlChildNameMap.comment, block);
Blockly.Xml.applyDataTagNodes_(xmlChildNameMap.data, block);
// Connect parent after processing mutation and before setting fields.
if (parentConnection) {
if (connectedToParentNext) {
if (block.previousConnection) {
parentConnection.connect(block.previousConnection);
} else {
throw TypeError(
'Next block does not have previous statement.');
}
} else {
if (block.outputConnection) {
parentConnection.connect(block.outputConnection);
} else if (block.previousConnection) {
parentConnection.connect(block.previousConnection);
} else {
throw TypeError(
'Child block does not have output or previous statement.');
}
}
}
Blockly.Xml.applyFieldTagNodes_(xmlChildNameMap.field, block);
Blockly.Xml.applyInputTagNodes_(
xmlChildNameMap.input, workspace, block, prototypeName);