diff --git a/core/block_svg.js b/core/block_svg.js index b12d5d90..6bb838e9 100644 --- a/core/block_svg.js +++ b/core/block_svg.js @@ -690,6 +690,10 @@ Blockly.BlockSvg.prototype.duplicateAndDragCallback_ = function() { // Using domToBlock instead of domToWorkspace means that the new block // will be placed at position (0, 0) in main workspace units. var newBlock = Blockly.Xml.domToBlock(xml, ws); + + // Scratch-specific: Give shadow dom new IDs to prevent duplicating on paste + Blockly.utils.changeObscuredShadowIds(newBlock); + var svgRootNew = newBlock.getSvgRoot(); if (!svgRootNew) { throw new Error('newBlock is not rendered.'); diff --git a/core/utils.js b/core/utils.js index 9b088977..4669ea2c 100644 --- a/core/utils.js +++ b/core/utils.js @@ -931,3 +931,26 @@ Blockly.utils.setCssTransform = function(node, transform) { node.style['transform'] = transform; node.style['-webkit-transform'] = transform; }; + + +/** + * Re-assign obscured shadow blocks new IDs to prevent collisions + * Scratch specific to help the VM handle deleting obscured shadows. + * @param {Blockly.Block} block the root block to be processed. + */ +Blockly.utils.changeObscuredShadowIds = function(block) { + var blocks = block.getDescendants(); + for (var i = blocks.length - 1; i >= 0; i--) { + var descendant = blocks[i]; + for (var j = 0; j < descendant.inputList.length; j++) { + var connection = descendant.inputList[j].connection; + if (connection) { + var shadowDom = connection.getShadowDom(); + if (shadowDom) { + shadowDom.setAttribute('id', Blockly.utils.genUid()); + connection.setShadowDom(shadowDom); + } + } + } + } +}; diff --git a/core/workspace_svg.js b/core/workspace_svg.js index 69d58eba..985dcf78 100644 --- a/core/workspace_svg.js +++ b/core/workspace_svg.js @@ -945,22 +945,12 @@ Blockly.WorkspaceSvg.prototype.paste = function(xmlBlock) { try { var block = Blockly.Xml.domToBlock(xmlBlock, this); + // Scratch-specific: Give shadow dom new IDs to prevent duplicating on paste + Blockly.utils.changeObscuredShadowIds(block); + var blocks = block.getDescendants(); for (var i = blocks.length - 1; i >= 0; i--) { var descendant = blocks[i]; - - // Scratch-specific: Give shadow dom new IDs to prevent duplicating on paste - for (var j = 0; j < descendant.inputList.length; j++) { - var connection = descendant.inputList[j].connection; - if (connection) { - var shadowDom = connection.getShadowDom(); - if (shadowDom) { - shadowDom.setAttribute('id', Blockly.utils.genUid()); - connection.setShadowDom(shadowDom); - } - } - } - // Rerender to get around problem with IE and Edge not measuring text // correctly when it is hidden. if (goog.userAgent.IE || goog.userAgent.EDGE) {