From ea89be63d99bb26d68a1e1af37aa79944bbbd430 Mon Sep 17 00:00:00 2001 From: Paul Kaplan <pkaplan@media.mit.edu> Date: Wed, 26 Jul 2017 15:21:50 -0400 Subject: [PATCH 1/2] Add shadow dom ID uniquifier to 'Duplicate' code path --- core/block_svg.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/core/block_svg.js b/core/block_svg.js index d5984299..f0cfd812 100644 --- a/core/block_svg.js +++ b/core/block_svg.js @@ -684,6 +684,23 @@ 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 + var blocks = newBlock.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); + } + } + } + } + var svgRootNew = newBlock.getSvgRoot(); if (!svgRootNew) { throw new Error('newBlock is not rendered.'); From 3efae4ce3f419d4b54028a67794626332f56fa69 Mon Sep 17 00:00:00 2001 From: Paul Kaplan <pkaplan@media.mit.edu> Date: Sat, 5 Aug 2017 13:37:10 -0400 Subject: [PATCH 2/2] Move function into helper --- core/block_svg.js | 15 +-------------- core/utils.js | 23 +++++++++++++++++++++++ core/workspace_svg.js | 16 +++------------- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/core/block_svg.js b/core/block_svg.js index f0cfd812..43c8ef8d 100644 --- a/core/block_svg.js +++ b/core/block_svg.js @@ -686,20 +686,7 @@ Blockly.BlockSvg.prototype.duplicateAndDragCallback_ = function() { var newBlock = Blockly.Xml.domToBlock(xml, ws); // Scratch-specific: Give shadow dom new IDs to prevent duplicating on paste - var blocks = newBlock.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); - } - } - } - } + Blockly.utils.changeObscuredShadowIds(newBlock); var svgRootNew = newBlock.getSvgRoot(); if (!svgRootNew) { 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) {