Blockly.Xml.domToWorkspace = function()

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