From 9804b31bb015b1d2e799c8cdab156a7b0282fb25 Mon Sep 17 00:00:00 2001 From: Neil Fraser Date: Thu, 21 Jan 2016 18:16:25 -0800 Subject: [PATCH] Allow easier addition of custom loops or functions. --- blocks/loops.js | 15 +++++++++------ blocks/procedures.js | 11 ++++++++--- core/block.js | 17 ++++++++++++++++- core/connection.js | 2 ++ core/events.js | 7 +------ demos/headless/index.html | 2 +- 6 files changed, 37 insertions(+), 17 deletions(-) diff --git a/blocks/loops.js b/blocks/loops.js index 06e55960d..347d60ea9 100644 --- a/blocks/loops.js +++ b/blocks/loops.js @@ -300,11 +300,7 @@ Blockly.Blocks['controls_flow_statements'] = { // Is the block nested in a loop? var block = this; do { - if (block.type == 'controls_repeat' || - block.type == 'controls_repeat_ext' || - block.type == 'controls_forEach' || - block.type == 'controls_for' || - block.type == 'controls_whileUntil') { + if (this.LOOP_TYPES.indexOf(block.type) != -1) { legal = true; break; } @@ -315,5 +311,12 @@ Blockly.Blocks['controls_flow_statements'] = { } else { this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); } - } + }, + /** + * List of block types that are loops and thus do not need warnings. + * To add a new loop type add this to your code: + * Blockly.Blocks['controls_flow_statements'].LOOP_TYPES.push('custom_loop'); + */ + LOOP_TYPES: ['controls_repeat', 'controls_repeat_ext', 'controls_forEach', + 'controls_for', 'controls_whileUntil'] }; diff --git a/blocks/procedures.js b/blocks/procedures.js index eab8646a8..d8acb93e3 100644 --- a/blocks/procedures.js +++ b/blocks/procedures.js @@ -749,8 +749,7 @@ Blockly.Blocks['procedures_ifreturn'] = { // Is the block nested in a procedure? var block = this; do { - if (block.type == 'procedures_defnoreturn' || - block.type == 'procedures_defreturn') { + if (this.FUNCTION_TYPES.indexOf(block.type) != -1) { legal = true; break; } @@ -774,5 +773,11 @@ Blockly.Blocks['procedures_ifreturn'] = { } else { this.setWarningText(Blockly.Msg.PROCEDURES_IFRETURN_WARNING); } - } + }, + /** + * List of block types that are functions and thus do not need warnings. + * To add a new function type add this to your code: + * Blockly.Blocks['procedures_ifreturn'].FUNCTION_TYPES.push('custom_func'); + */ + FUNCTION_TYPES: ['procedures_defnoreturn', 'procedures_defreturn'] }; diff --git a/core/block.js b/core/block.js index e07e2337a..c93deff6b 100644 --- a/core/block.js +++ b/core/block.js @@ -330,6 +330,20 @@ Blockly.Block.prototype.getParent = function() { return this.parentBlock_; }; +/** + * Return the input that connects to the specified block. + * @param {!Blockly.Block} A block connected to an input on this block. + * @return {Blockly.Input} The input that connects to the specified block. + */ +Blockly.Block.prototype.getInputWithBlock = function(block) { + for (var i = 0, input; input = this.inputList[i]; i++) { + if (input.connection && input.connection.targetBlock() == block) { + return input + } + } + return null; +}; + /** * Return the parent block that surrounds the current block, or null if this * block has no surrounding block. A parent block might just be the previous @@ -866,7 +880,8 @@ Blockly.Block.prototype.toString = function(opt_maxLength) { text = goog.string.trim(text.join(' ')) || '???'; if (opt_maxLength) { // TODO: Improve truncation so that text from this block is given priority. - // TODO: Handle FieldImage better. + // E.g. "1+2+3+4+5+6+7+8+9=0" should be "...6+7+8+9=0", not "1+2+3+4+5...". + // E.g. "1+2+3+4+5=6+7+8+9+0" should be "...4+5=6+7...". text = goog.string.truncate(text, opt_maxLength); } return text; diff --git a/core/connection.js b/core/connection.js index db5a8a6b9..53be62779 100644 --- a/core/connection.js +++ b/core/connection.js @@ -157,6 +157,7 @@ Blockly.Connection.prototype.connect = function(otherConnection) { throw 'Attempt to connect incompatible types.'; } if (this.type == Blockly.INPUT_VALUE || this.type == Blockly.OUTPUT_VALUE) { + // Value connections. if (this.targetConnection) { // Can't make a value connection if male block is already connected. throw 'Source connection already connected (value).'; @@ -193,6 +194,7 @@ Blockly.Connection.prototype.connect = function(otherConnection) { } } } else { + // Statement connections. if (this.targetConnection) { throw 'Source connection already connected (block).'; } else if (otherConnection.targetConnection) { diff --git a/core/events.js b/core/events.js index 1d0ac1df5..9fcd27578 100644 --- a/core/events.js +++ b/core/events.js @@ -133,12 +133,7 @@ Blockly.Events.Delete = function(block) { var parent = block.getParent(); if (parent) { this.oldParentId = parent.id; - for (var i = 0, input; input = parent.inputList[i]; i++) { - if (input.connection && input.connection.targetBlock() == block) { - this.oldInput = input.name; - break; - } - } + this.oldInput = getInputWithBlock(block).name } }; goog.inherits(Blockly.Events.Delete, Blockly.Events.Abstract); diff --git a/demos/headless/index.html b/demos/headless/index.html index c3bad9d3b..9df0dc806 100644 --- a/demos/headless/index.html +++ b/demos/headless/index.html @@ -36,7 +36,7 @@