in core/xml.js [407:506]
Blockly.Xml.domToWorkspace = function(xml, workspace) {
if (xml instanceof Blockly.Workspace) {
var swap = xml;
// Closure Compiler complains here because the arguments are reversed.
/** @suppress {checkTypes} */
xml = workspace;
workspace = swap;
console.warn('Deprecated call to Blockly.Xml.domToWorkspace, ' +
'swap the arguments.');
}
// pxtblockly
workspace.loadingEventsDisabled = true;
var width; // Not used in LTR.
if (workspace.RTL) {
width = workspace.getWidth();
}
var newBlockIds = []; // A list of block IDs added by this call.
Blockly.utils.dom.startTextWidthCache();
var existingGroup = Blockly.Events.getGroup();
if (!existingGroup) {
Blockly.Events.setGroup(true);
}
// Disable workspace resizes as an optimization.
if (workspace.setResizesEnabled) {
workspace.setResizesEnabled(false);
}
var variablesFirst = true;
try {
for (var i = 0, xmlChild; (xmlChild = xml.childNodes[i]); i++) {
var name = xmlChild.nodeName.toLowerCase();
var xmlChildElement = /** @type {!Element} */ (xmlChild);
if (name == 'block' ||
(name == 'shadow' && !Blockly.Events.recordUndo)) {
// Allow top-level shadow blocks if recordUndo is disabled since
// that means an undo is in progress. Such a block is expected
// to be moved to a nested destination in the next operation.
var block = Blockly.Xml.domToBlock(xmlChildElement, workspace);
newBlockIds.push(block.id);
var blockX = xmlChildElement.hasAttribute('x') ?
parseInt(xmlChildElement.getAttribute('x'), 10) : 10;
var blockY = xmlChildElement.hasAttribute('y') ?
parseInt(xmlChildElement.getAttribute('y'), 10) : 10;
if (!isNaN(blockX) && !isNaN(blockY)) {
block.moveBy(workspace.RTL ? width - blockX : blockX, blockY);
}
variablesFirst = false;
} else if (name == 'shadow') {
throw TypeError('Shadow block cannot be a top-level block.');
} else if (name == 'comment') {
if (workspace.rendered) {
if (!Blockly.WorkspaceCommentSvg) {
console.warn('Missing require for Blockly.WorkspaceCommentSvg, ' +
'ignoring workspace comment.');
} else {
Blockly.WorkspaceCommentSvg.fromXml(
xmlChildElement, workspace, width);
}
} else {
if (!Blockly.WorkspaceComment) {
console.warn('Missing require for Blockly.WorkspaceComment, ' +
'ignoring workspace comment.');
} else {
Blockly.WorkspaceComment.fromXml(xmlChildElement, workspace);
}
}
} else if (name == 'variables') {
if (variablesFirst) {
Blockly.Xml.domToVariables(xmlChildElement, workspace);
} else {
throw Error('\'variables\' tag must exist once before block and ' +
'shadow tag elements in the workspace XML, but it was found in ' +
'another location.');
}
variablesFirst = false;
}
}
} finally {
if (!existingGroup) {
Blockly.Events.setGroup(false);
}
Blockly.utils.dom.stopTextWidthCache();
}
// Re-enable workspace resizing.
if (workspace.setResizesEnabled) {
workspace.setResizesEnabled(true);
}
// pxtblockly
workspace.loadingEventsDisabled = false;
workspace.getAllBlocks(false).forEach(function (block) {
block.onLoadedIntoWorkspace();
});
Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.FINISHED_LOADING))(
workspace));
return newBlockIds;
};