mirror of
https://github.com/google/blockly.git
synced 2026-01-09 01:50:11 +01:00
Add 'ordered' option to descendant getting functions. (#1786)
This commit is contained in:
@@ -457,12 +457,30 @@ Blockly.Block.prototype.getRootBlock = function() {
|
||||
|
||||
/**
|
||||
* Find all the blocks that are directly nested inside this one.
|
||||
* Includes value and block inputs, as well as any following statement.
|
||||
* Includes value and statement inputs, as well as any following statement.
|
||||
* Excludes any connection on an output tab or any preceding statement.
|
||||
* Blocks are optionally sorted by position; top to bottom.
|
||||
* @param {boolean} ordered Sort the list if true.
|
||||
* @return {!Array.<!Blockly.Block>} Array of blocks.
|
||||
*/
|
||||
Blockly.Block.prototype.getChildren = function() {
|
||||
return this.childBlocks_;
|
||||
Blockly.Block.prototype.getChildren = function(ordered) {
|
||||
if (!ordered) {
|
||||
return this.childBlocks_;
|
||||
}
|
||||
var blocks = [];
|
||||
for (var i = 0, input; input = this.inputList[i]; i++) {
|
||||
if (input.connection) {
|
||||
var child = input.connection.targetBlock();
|
||||
if (child) {
|
||||
blocks.push(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
var next = this.getNextBlock();
|
||||
if (next) {
|
||||
blocks.push(next);
|
||||
}
|
||||
return blocks;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -504,14 +522,17 @@ Blockly.Block.prototype.setParent = function(newParent) {
|
||||
/**
|
||||
* Find all the blocks that are directly or indirectly nested inside this one.
|
||||
* Includes this block in the list.
|
||||
* Includes value and block inputs, as well as any following statements.
|
||||
* Includes value and statement inputs, as well as any following statements.
|
||||
* Excludes any connection on an output tab or any preceding statements.
|
||||
* Blocks are optionally sorted by position; top to bottom.
|
||||
* @param {boolean} ordered Sort the list if true.
|
||||
* @return {!Array.<!Blockly.Block>} Flattened array of blocks.
|
||||
*/
|
||||
Blockly.Block.prototype.getDescendants = function() {
|
||||
Blockly.Block.prototype.getDescendants = function(ordered) {
|
||||
var blocks = [this];
|
||||
for (var child, x = 0; child = this.childBlocks_[x]; x++) {
|
||||
blocks.push.apply(blocks, child.getDescendants());
|
||||
var childBlocks = this.getChildren(ordered);
|
||||
for (var child, i = 0; child = childBlocks[i]; i++) {
|
||||
blocks.push.apply(blocks, child.getDescendants(ordered));
|
||||
}
|
||||
return blocks;
|
||||
};
|
||||
|
||||
@@ -124,7 +124,7 @@ Blockly.BlockDragger.prototype.dispose = function() {
|
||||
Blockly.BlockDragger.initIconData_ = function(block) {
|
||||
// Build a list of icons that need to be moved and where they started.
|
||||
var dragIconData = [];
|
||||
var descendants = block.getDescendants();
|
||||
var descendants = block.getDescendants(false);
|
||||
for (var i = 0, descendant; descendant = descendants[i]; i++) {
|
||||
var icons = descendant.getIcons();
|
||||
for (var j = 0; j < icons.length; j++) {
|
||||
|
||||
@@ -1070,7 +1070,7 @@ Blockly.BlockSvg.prototype.updateDisabled = function() {
|
||||
this.updateColour();
|
||||
}
|
||||
}
|
||||
var children = this.getChildren();
|
||||
var children = this.getChildren(false);
|
||||
for (var i = 0, child; child = children[i]; i++) {
|
||||
child.updateDisabled();
|
||||
}
|
||||
|
||||
@@ -215,11 +215,11 @@ Blockly.ContextMenu.callbackFactory = function(block, xml) {
|
||||
Blockly.ContextMenu.blockDeleteOption = function(block) {
|
||||
// Option to delete this block but not blocks lower in the stack.
|
||||
// Count the number of blocks that are nested in this block.
|
||||
var descendantCount = block.getDescendants(true).length;
|
||||
var descendantCount = block.getDescendants(false).length;
|
||||
var nextBlock = block.getNextBlock();
|
||||
if (nextBlock) {
|
||||
// Blocks in the current stack would survive this block's deletion.
|
||||
descendantCount -= nextBlock.getDescendants(true).length;
|
||||
descendantCount -= nextBlock.getDescendants(false).length;
|
||||
}
|
||||
var deleteOption = {
|
||||
text: descendantCount == 1 ? Blockly.Msg.DELETE_BLOCK :
|
||||
@@ -260,7 +260,8 @@ Blockly.ContextMenu.blockHelpOption = function(block) {
|
||||
*/
|
||||
Blockly.ContextMenu.blockDuplicateOption = function(block) {
|
||||
var enabled = true;
|
||||
if (block.getDescendants().length > block.workspace.remainingCapacity()) {
|
||||
if (block.getDescendants(false).length >
|
||||
block.workspace.remainingCapacity()) {
|
||||
enabled = false;
|
||||
}
|
||||
var duplicateOption = {
|
||||
|
||||
@@ -287,7 +287,7 @@ Blockly.Events.setGroup = function(state) {
|
||||
*/
|
||||
Blockly.Events.getDescendantIds_ = function(block) {
|
||||
var ids = [];
|
||||
var descendants = block.getDescendants();
|
||||
var descendants = block.getDescendants(false);
|
||||
for (var i = 0, descendant; descendant = descendants[i]; i++) {
|
||||
ids[i] = descendant.id;
|
||||
}
|
||||
@@ -350,7 +350,7 @@ Blockly.Events.disableOrphans = function(event) {
|
||||
var block = workspace.getBlockById(event.blockId);
|
||||
if (block) {
|
||||
if (block.getParent() && !block.getParent().disabled) {
|
||||
var children = block.getDescendants();
|
||||
var children = block.getDescendants(false);
|
||||
for (var i = 0, child; child = children[i]; i++) {
|
||||
child.setDisabled(false);
|
||||
}
|
||||
|
||||
@@ -717,7 +717,7 @@ Blockly.Flyout.prototype.filterForCapacity_ = function() {
|
||||
var blocks = this.workspace_.getTopBlocks(false);
|
||||
for (var i = 0, block; block = blocks[i]; i++) {
|
||||
if (this.permanentlyDisabled_.indexOf(block) == -1) {
|
||||
var allBlocks = block.getDescendants();
|
||||
var allBlocks = block.getDescendants(false);
|
||||
block.setDisabled(allBlocks.length > remainingCapacity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,7 +261,7 @@ Blockly.HorizontalFlyout.prototype.layout_ = function(contents, gaps) {
|
||||
for (var i = 0, item; item = contents[i]; i++) {
|
||||
if (item.type == 'block') {
|
||||
var block = item.block;
|
||||
var allBlocks = block.getDescendants();
|
||||
var allBlocks = block.getDescendants(false);
|
||||
for (var j = 0, child; child = allBlocks[j]; j++) {
|
||||
// Mark blocks as being inside a flyout. This is used to detect and
|
||||
// prevent the closure of the flyout if the user right-clicks on such a
|
||||
|
||||
@@ -247,7 +247,7 @@ Blockly.VerticalFlyout.prototype.layout_ = function(contents, gaps) {
|
||||
for (var i = 0, item; item = contents[i]; i++) {
|
||||
if (item.type == 'block') {
|
||||
var block = item.block;
|
||||
var allBlocks = block.getDescendants();
|
||||
var allBlocks = block.getDescendants(false);
|
||||
for (var j = 0, child; child = allBlocks[j]; j++) {
|
||||
// Mark blocks as being inside a flyout. This is used to detect and
|
||||
// prevent the closure of the flyout if the user right-clicks on such a
|
||||
|
||||
@@ -142,7 +142,7 @@ Blockly.Generator.prototype.prefixLines = function(text, prefix) {
|
||||
*/
|
||||
Blockly.Generator.prototype.allNestedComments = function(block) {
|
||||
var comments = [];
|
||||
var blocks = block.getDescendants();
|
||||
var blocks = block.getDescendants(true);
|
||||
for (var i = 0; i < blocks.length; i++) {
|
||||
var comment = blocks[i].getCommentText();
|
||||
if (comment) {
|
||||
|
||||
@@ -258,7 +258,7 @@ Blockly.Mutator.prototype.setVisible = function(visible) {
|
||||
}
|
||||
|
||||
this.rootBlock_ = this.block_.decompose(this.workspace_);
|
||||
var blocks = this.rootBlock_.getDescendants();
|
||||
var blocks = this.rootBlock_.getDescendants(false);
|
||||
for (var i = 0, child; child = blocks[i]; i++) {
|
||||
child.render();
|
||||
}
|
||||
|
||||
@@ -286,7 +286,7 @@ Blockly.RenderedConnection.prototype.setHidden = function(hidden) {
|
||||
Blockly.RenderedConnection.prototype.hideAll = function() {
|
||||
this.setHidden(true);
|
||||
if (this.targetConnection) {
|
||||
var blocks = this.targetBlock().getDescendants();
|
||||
var blocks = this.targetBlock().getDescendants(false);
|
||||
for (var i = 0; i < blocks.length; i++) {
|
||||
var block = blocks[i];
|
||||
// Hide all connections of all children.
|
||||
|
||||
@@ -396,7 +396,7 @@ Blockly.Toolbox.prototype.syncTrees_ = function(treeIn, treeOut, pathToMedia) {
|
||||
*/
|
||||
Blockly.Toolbox.prototype.addColour_ = function(opt_tree) {
|
||||
var tree = opt_tree || this.tree_;
|
||||
var children = tree.getChildren();
|
||||
var children = tree.getChildren(false);
|
||||
for (var i = 0, child; child = children[i]; i++) {
|
||||
var element = child.getRowElement();
|
||||
if (element) {
|
||||
|
||||
@@ -171,13 +171,25 @@ Blockly.Workspace.prototype.getTopBlocks = function(ordered) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Find all blocks in workspace. No particular order.
|
||||
* Find all blocks in workspace. Blocks are optionally sorted
|
||||
* by position; top to bottom (with slight LTR or RTL bias).
|
||||
* @param {boolean} ordered Sort the list if true.
|
||||
* @return {!Array.<!Blockly.Block>} Array of blocks.
|
||||
*/
|
||||
Blockly.Workspace.prototype.getAllBlocks = function() {
|
||||
var blocks = this.getTopBlocks(false);
|
||||
for (var i = 0; i < blocks.length; i++) {
|
||||
blocks.push.apply(blocks, blocks[i].getChildren());
|
||||
Blockly.Workspace.prototype.getAllBlocks = function(ordered) {
|
||||
if (ordered) {
|
||||
// Slow, but ordered.
|
||||
var topBlocks = this.getTopBlocks(true);
|
||||
var blocks = [];
|
||||
for (var i = 0; i < topBlocks.length; i++) {
|
||||
blocks.push.apply(blocks, topBlocks[i].getDescendants(true));
|
||||
}
|
||||
} else {
|
||||
// Fast, but in no particular order.
|
||||
var blocks = this.getTopBlocks(false);
|
||||
for (var i = 0; i < blocks.length; i++) {
|
||||
blocks.push.apply(blocks, blocks[i].getChildren(false));
|
||||
}
|
||||
}
|
||||
return blocks;
|
||||
};
|
||||
|
||||
@@ -1268,9 +1268,9 @@ Blockly.WorkspaceSvg.prototype.showContextMenu_ = function(e) {
|
||||
var deleteList = [];
|
||||
function addDeletableBlocks(block) {
|
||||
if (block.isDeletable()) {
|
||||
deleteList = deleteList.concat(block.getDescendants());
|
||||
deleteList = deleteList.concat(block.getDescendants(false));
|
||||
} else {
|
||||
var children = block.getChildren();
|
||||
var children = block.getChildren(false);
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
addDeletableBlocks(children[i]);
|
||||
}
|
||||
|
||||
@@ -517,7 +517,7 @@ Blockly.Xml.domToBlock = function(xmlBlock, workspace) {
|
||||
try {
|
||||
var topBlock = Blockly.Xml.domToBlockHeadless_(xmlBlock, workspace);
|
||||
// Generate list of all blocks.
|
||||
var blocks = topBlock.getDescendants();
|
||||
var blocks = topBlock.getDescendants(false);
|
||||
if (workspace.rendered) {
|
||||
// Hide connections to speed up assembly.
|
||||
topBlock.setConnectionsHidden(true);
|
||||
@@ -735,7 +735,7 @@ Blockly.Xml.domToBlockHeadless_ = function(xmlBlock, workspace) {
|
||||
}
|
||||
if (xmlBlock.nodeName.toLowerCase() == 'shadow') {
|
||||
// Ensure all children are also shadows.
|
||||
var children = block.getChildren();
|
||||
var children = block.getChildren(false);
|
||||
for (var i = 0, child; child = children[i]; i++) {
|
||||
goog.asserts.assert(
|
||||
child.isShadow(), 'Shadow block not allowed non-shadow child.');
|
||||
|
||||
Reference in New Issue
Block a user