diff --git a/core/block.js b/core/block.js index 4730c1cd6..25f09ee14 100644 --- a/core/block.js +++ b/core/block.js @@ -1335,3 +1335,37 @@ Blockly.Block.prototype.moveBy = function(dx, dy) { Blockly.Block.prototype.makeConnection_ = function(type) { return new Blockly.Connection(this, type); }; + +/** + * Recursively checks whether all statement and value inputs are filled with + * blocks. Also checks all following statement blocks in this stack. + * @param {boolean=} opt_shadowBlocksAreFilled An optional argument controlling + * whether shadow blocks are counted as filled. Defaults to true. + * @return {boolean} True if all inputs are filled, false otherwise. + */ +Blockly.Block.prototype.allInputsFilled = function(opt_shadowBlocksAreFilled) { + // Handle the default value for the optional argument. + if (opt_shadowBlocksAreFilled === undefined) { + opt_shadowBlocksAreFilled = true; + } + + for (var i = 0, input; input = this.inputList[i]; i++) { + if (!input.connection) { + continue; + } + var target = input.connection.targetBlock(); + if (!target || !target.allInputsFilled(opt_shadowBlocksAreFilled)) { + return false; + } + if (!opt_shadowBlocksAreFilled && target.isShadow()) { + return false; + } + } + + var next = this.getNextBlock(); + if (next) { + return next.allInputsFilled(opt_shadowBlocksAreFilled); + } + + return true; +}; diff --git a/core/workspace.js b/core/workspace.js index 46661f532..95dc26c00 100644 --- a/core/workspace.js +++ b/core/workspace.js @@ -478,6 +478,23 @@ Blockly.Workspace.prototype.getBlockById = function(id) { return this.blockDB_[id] || null; }; +/** + * Checks whether all value and statement inputs in the workspace are filled + * with blocks. + * @param {boolean=} opt_shadowBlocksAreFilled An optional argument controlling + * whether shadow blocks are counted as filled. Defaults to true. + * @return {boolean} True if all inputs are filled, false otherwise. + */ +Blockly.Workspace.prototype.allInputsFilled = function(opt_shadowBlocksAreFilled) { + var blocks = this.getTopBlocks(false); + for (var i = 0, block; block = blocks[i]; i++) { + if (!block.allInputsFilled(opt_shadowBlocksAreFilled)) { + return false; + } + } + return true; +}; + /** * Database of all workspaces. * @private