From 1db8092f15a81b1475e8785c080b17f53780fa34 Mon Sep 17 00:00:00 2001 From: Neil Fraser Date: Sun, 29 May 2016 14:53:29 -0700 Subject: [PATCH] Do not allow shadow blocks to have non-shadow children. --- core/connection.js | 18 ++++++++++++++---- core/xml.js | 6 ++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/core/connection.js b/core/connection.js index c52280464..77da88b43 100644 --- a/core/connection.js +++ b/core/connection.js @@ -62,6 +62,7 @@ Blockly.Connection.REASON_WRONG_TYPE = 2; Blockly.Connection.REASON_TARGET_NULL = 3; Blockly.Connection.REASON_CHECKS_FAILED = 4; Blockly.Connection.REASON_DIFFERENT_WORKSPACES = 5; +Blockly.Connection.REASON_SHADOW_PARENT = 6; /** * Connection this connection connects to. Null if not connected. @@ -283,18 +284,25 @@ Blockly.Connection.prototype.isConnected = function() { * @private */ Blockly.Connection.prototype.canConnectWithReason_ = function(target) { + if (this.isSuperior()) { + var blockA = this.sourceBlock_; + var blockB = target.getSourceBlock(); + } else { + var blockB = this.sourceBlock_; + var blockA = target.getSourceBlock(); + } if (!target) { return Blockly.Connection.REASON_TARGET_NULL; - } else if (this.sourceBlock_ && - target.getSourceBlock() == this.sourceBlock_) { + } else if (blockA && blockA == blockB) { return Blockly.Connection.REASON_SELF_CONNECTION; } else if (target.type != Blockly.OPPOSITE_TYPE[this.type]) { return Blockly.Connection.REASON_WRONG_TYPE; - } else if (this.sourceBlock_ && target.getSourceBlock() && - this.sourceBlock_.workspace !== target.getSourceBlock().workspace) { + } else if (blockA && blockB && blockA.workspace !== blockB.workspace) { return Blockly.Connection.REASON_DIFFERENT_WORKSPACES; } else if (!this.checkType_(target)) { return Blockly.Connection.REASON_CHECKS_FAILED; + } else if (blockA.isShadow() && !blockB.isShadow()) { + return Blockly.Connection.REASON_SHADOW_PARENT; } return Blockly.Connection.CAN_CONNECT; }; @@ -321,6 +329,8 @@ Blockly.Connection.prototype.checkConnection_ = function(target) { throw 'Target connection is null.'; case Blockly.Connection.REASON_CHECKS_FAILED: throw 'Connection checks failed.'; + case Blockly.Connection.REASON_SHADOW_PARENT: + throw 'Connecting non-shadow to shadow block.'; default: throw 'Unknown connection failure: this should never happen!'; } diff --git a/core/xml.js b/core/xml.js index 07ac7b8e4..48cef7216 100644 --- a/core/xml.js +++ b/core/xml.js @@ -521,6 +521,12 @@ Blockly.Xml.domToBlockHeadless_ = function(xmlBlock, workspace) { block.setCollapsed(collapsed == 'true'); } if (xmlBlock.nodeName.toLowerCase() == 'shadow') { + // Ensure all children are also shadows. + var children = block.getChildren(); + for (var i = 0, child; child = children[i]; i++) { + goog.asserts.assert(child.isShadow(), + 'Shadow block not allowed non-shadow child.'); + } block.setShadow(true); } // Give the block a chance to clean up any initial inputs.