mirror of
https://github.com/google/blockly.git
synced 2026-01-07 17:10:11 +01:00
Migrate core/keyboard_nav/ast_node.js to goog.module
This commit is contained in:
@@ -10,7 +10,8 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.ASTNode');
|
||||
goog.module('Blockly.ASTNode');
|
||||
goog.module.declareLegacyNamespace();
|
||||
|
||||
goog.require('Blockly.connectionTypes');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
@@ -29,19 +30,19 @@ goog.requireType('Blockly.Workspace');
|
||||
* It is recommended that you use one of the createNode methods instead of
|
||||
* creating a node directly.
|
||||
* @param {string} type The type of the location.
|
||||
* Must be in Blockly.ASTNode.types.
|
||||
* Must be in ASTNode.types.
|
||||
* @param {!Blockly.IASTNodeLocation} location The position in the AST.
|
||||
* @param {!Blockly.ASTNode.Params=} opt_params Optional dictionary of options.
|
||||
* @param {!ASTNode.Params=} opt_params Optional dictionary of options.
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.ASTNode = function(type, location, opt_params) {
|
||||
const ASTNode = function(type, location, opt_params) {
|
||||
if (!location) {
|
||||
throw Error('Cannot create a node without a location.');
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of the location.
|
||||
* One of Blockly.ASTNode.types
|
||||
* One of ASTNode.types
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
@@ -52,7 +53,7 @@ Blockly.ASTNode = function(type, location, opt_params) {
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
this.isConnection_ = Blockly.ASTNode.isConnectionType_(type);
|
||||
this.isConnection_ = ASTNode.isConnectionType_(type);
|
||||
|
||||
/**
|
||||
* The location of the AST node.
|
||||
@@ -76,13 +77,13 @@ Blockly.ASTNode = function(type, location, opt_params) {
|
||||
* wsCoordinate: Blockly.utils.Coordinate
|
||||
* }}
|
||||
*/
|
||||
Blockly.ASTNode.Params;
|
||||
ASTNode.Params;
|
||||
|
||||
/**
|
||||
* Object holding different types for an AST node.
|
||||
* @enum {string}
|
||||
*/
|
||||
Blockly.ASTNode.types = {
|
||||
ASTNode.types = {
|
||||
FIELD: 'field',
|
||||
BLOCK: 'block',
|
||||
INPUT: 'input',
|
||||
@@ -97,7 +98,7 @@ Blockly.ASTNode.types = {
|
||||
* True to navigate to all fields. False to only navigate to clickable fields.
|
||||
* @type {boolean}
|
||||
*/
|
||||
Blockly.ASTNode.NAVIGATE_ALL_FIELDS = false;
|
||||
ASTNode.NAVIGATE_ALL_FIELDS = false;
|
||||
|
||||
/**
|
||||
* The default y offset to use when moving the cursor from a stack to the
|
||||
@@ -105,20 +106,20 @@ Blockly.ASTNode.NAVIGATE_ALL_FIELDS = false;
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
Blockly.ASTNode.DEFAULT_OFFSET_Y = -20;
|
||||
ASTNode.DEFAULT_OFFSET_Y = -20;
|
||||
|
||||
/**
|
||||
* Whether an AST node of the given type points to a connection.
|
||||
* @param {string} type The type to check. One of Blockly.ASTNode.types.
|
||||
* @param {string} type The type to check. One of ASTNode.types.
|
||||
* @return {boolean} True if a node of the given type points to a connection.
|
||||
* @private
|
||||
*/
|
||||
Blockly.ASTNode.isConnectionType_ = function(type) {
|
||||
ASTNode.isConnectionType_ = function(type) {
|
||||
switch (type) {
|
||||
case Blockly.ASTNode.types.PREVIOUS:
|
||||
case Blockly.ASTNode.types.NEXT:
|
||||
case Blockly.ASTNode.types.INPUT:
|
||||
case Blockly.ASTNode.types.OUTPUT:
|
||||
case ASTNode.types.PREVIOUS:
|
||||
case ASTNode.types.NEXT:
|
||||
case ASTNode.types.INPUT:
|
||||
case ASTNode.types.OUTPUT:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -127,13 +128,13 @@ Blockly.ASTNode.isConnectionType_ = function(type) {
|
||||
/**
|
||||
* Create an AST node pointing to a field.
|
||||
* @param {Blockly.Field} field The location of the AST node.
|
||||
* @return {Blockly.ASTNode} An AST node pointing to a field.
|
||||
* @return {ASTNode} An AST node pointing to a field.
|
||||
*/
|
||||
Blockly.ASTNode.createFieldNode = function(field) {
|
||||
ASTNode.createFieldNode = function(field) {
|
||||
if (!field) {
|
||||
return null;
|
||||
}
|
||||
return new Blockly.ASTNode(Blockly.ASTNode.types.FIELD, field);
|
||||
return new ASTNode(ASTNode.types.FIELD, field);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -141,24 +142,24 @@ Blockly.ASTNode.createFieldNode = function(field) {
|
||||
* input then create an AST node of type input that will hold the connection.
|
||||
* @param {Blockly.Connection} connection This is the connection the node will
|
||||
* point to.
|
||||
* @return {Blockly.ASTNode} An AST node pointing to a connection.
|
||||
* @return {ASTNode} An AST node pointing to a connection.
|
||||
*/
|
||||
Blockly.ASTNode.createConnectionNode = function(connection) {
|
||||
ASTNode.createConnectionNode = function(connection) {
|
||||
if (!connection) {
|
||||
return null;
|
||||
}
|
||||
const type = connection.type;
|
||||
if (type == Blockly.connectionTypes.INPUT_VALUE) {
|
||||
return Blockly.ASTNode.createInputNode(connection.getParentInput());
|
||||
return ASTNode.createInputNode(connection.getParentInput());
|
||||
} else if (type == Blockly.connectionTypes.NEXT_STATEMENT &&
|
||||
connection.getParentInput()) {
|
||||
return Blockly.ASTNode.createInputNode(connection.getParentInput());
|
||||
return ASTNode.createInputNode(connection.getParentInput());
|
||||
} else if (type == Blockly.connectionTypes.NEXT_STATEMENT) {
|
||||
return new Blockly.ASTNode(Blockly.ASTNode.types.NEXT, connection);
|
||||
return new ASTNode(ASTNode.types.NEXT, connection);
|
||||
} else if (type == Blockly.connectionTypes.OUTPUT_VALUE) {
|
||||
return new Blockly.ASTNode(Blockly.ASTNode.types.OUTPUT, connection);
|
||||
return new ASTNode(ASTNode.types.OUTPUT, connection);
|
||||
} else if (type == Blockly.connectionTypes.PREVIOUS_STATEMENT) {
|
||||
return new Blockly.ASTNode(Blockly.ASTNode.types.PREVIOUS, connection);
|
||||
return new ASTNode(ASTNode.types.PREVIOUS, connection);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
@@ -167,25 +168,25 @@ Blockly.ASTNode.createConnectionNode = function(connection) {
|
||||
* Creates an AST node pointing to an input. Stores the input connection as the
|
||||
* location.
|
||||
* @param {Blockly.Input} input The input used to create an AST node.
|
||||
* @return {Blockly.ASTNode} An AST node pointing to a input.
|
||||
* @return {ASTNode} An AST node pointing to a input.
|
||||
*/
|
||||
Blockly.ASTNode.createInputNode = function(input) {
|
||||
ASTNode.createInputNode = function(input) {
|
||||
if (!input || !input.connection) {
|
||||
return null;
|
||||
}
|
||||
return new Blockly.ASTNode(Blockly.ASTNode.types.INPUT, input.connection);
|
||||
return new ASTNode(ASTNode.types.INPUT, input.connection);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an AST node pointing to a block.
|
||||
* @param {Blockly.Block} block The block used to create an AST node.
|
||||
* @return {Blockly.ASTNode} An AST node pointing to a block.
|
||||
* @return {ASTNode} An AST node pointing to a block.
|
||||
*/
|
||||
Blockly.ASTNode.createBlockNode = function(block) {
|
||||
ASTNode.createBlockNode = function(block) {
|
||||
if (!block) {
|
||||
return null;
|
||||
}
|
||||
return new Blockly.ASTNode(Blockly.ASTNode.types.BLOCK, block);
|
||||
return new ASTNode(ASTNode.types.BLOCK, block);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -193,14 +194,14 @@ Blockly.ASTNode.createBlockNode = function(block) {
|
||||
* the set of all blocks connected to a top block, including the top block.
|
||||
* @param {Blockly.Block} topBlock A top block has no parent and can be found
|
||||
* in the list returned by workspace.getTopBlocks().
|
||||
* @return {Blockly.ASTNode} An AST node of type stack that points to the top
|
||||
* @return {ASTNode} An AST node of type stack that points to the top
|
||||
* block on the stack.
|
||||
*/
|
||||
Blockly.ASTNode.createStackNode = function(topBlock) {
|
||||
ASTNode.createStackNode = function(topBlock) {
|
||||
if (!topBlock) {
|
||||
return null;
|
||||
}
|
||||
return new Blockly.ASTNode(Blockly.ASTNode.types.STACK, topBlock);
|
||||
return new ASTNode(ASTNode.types.STACK, topBlock);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -208,44 +209,44 @@ Blockly.ASTNode.createStackNode = function(topBlock) {
|
||||
* @param {!Blockly.Workspace} workspace The workspace that we are on.
|
||||
* @param {Blockly.utils.Coordinate} wsCoordinate The position on the workspace
|
||||
* for this node.
|
||||
* @return {Blockly.ASTNode} An AST node pointing to a workspace and a position
|
||||
* @return {ASTNode} An AST node pointing to a workspace and a position
|
||||
* on the workspace.
|
||||
*/
|
||||
Blockly.ASTNode.createWorkspaceNode = function(workspace, wsCoordinate) {
|
||||
ASTNode.createWorkspaceNode = function(workspace, wsCoordinate) {
|
||||
if (!wsCoordinate || !workspace) {
|
||||
return null;
|
||||
}
|
||||
const params = {
|
||||
wsCoordinate: wsCoordinate
|
||||
};
|
||||
return new Blockly.ASTNode(
|
||||
Blockly.ASTNode.types.WORKSPACE, workspace, params);
|
||||
return new ASTNode(
|
||||
ASTNode.types.WORKSPACE, workspace, params);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an AST node for the top position on a block.
|
||||
* This is either an output connection, previous connection, or block.
|
||||
* @param {!Blockly.Block} block The block to find the top most AST node on.
|
||||
* @return {Blockly.ASTNode} The AST node holding the top most position on the
|
||||
* @return {ASTNode} The AST node holding the top most position on the
|
||||
* block.
|
||||
*/
|
||||
Blockly.ASTNode.createTopNode = function(block) {
|
||||
ASTNode.createTopNode = function(block) {
|
||||
let astNode;
|
||||
const topConnection = block.previousConnection || block.outputConnection;
|
||||
if (topConnection) {
|
||||
astNode = Blockly.ASTNode.createConnectionNode(topConnection);
|
||||
astNode = ASTNode.createConnectionNode(topConnection);
|
||||
} else {
|
||||
astNode = Blockly.ASTNode.createBlockNode(block);
|
||||
astNode = ASTNode.createBlockNode(block);
|
||||
}
|
||||
return astNode;
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse the optional parameters.
|
||||
* @param {?Blockly.ASTNode.Params} params The user specified parameters.
|
||||
* @param {?ASTNode.Params} params The user specified parameters.
|
||||
* @private
|
||||
*/
|
||||
Blockly.ASTNode.prototype.processParams_ = function(params) {
|
||||
ASTNode.prototype.processParams_ = function(params) {
|
||||
if (!params) {
|
||||
return;
|
||||
}
|
||||
@@ -261,16 +262,16 @@ Blockly.ASTNode.prototype.processParams_ = function(params) {
|
||||
* @return {!Blockly.IASTNodeLocation} The current field, connection, workspace, or
|
||||
* block the cursor is on.
|
||||
*/
|
||||
Blockly.ASTNode.prototype.getLocation = function() {
|
||||
ASTNode.prototype.getLocation = function() {
|
||||
return this.location_;
|
||||
};
|
||||
|
||||
/**
|
||||
* The type of the current location.
|
||||
* One of Blockly.ASTNode.types
|
||||
* One of ASTNode.types
|
||||
* @return {string} The type of the location.
|
||||
*/
|
||||
Blockly.ASTNode.prototype.getType = function() {
|
||||
ASTNode.prototype.getType = function() {
|
||||
return this.type_;
|
||||
};
|
||||
|
||||
@@ -279,7 +280,7 @@ Blockly.ASTNode.prototype.getType = function() {
|
||||
* @return {Blockly.utils.Coordinate} The workspace coordinate or null if the
|
||||
* location is not a workspace.
|
||||
*/
|
||||
Blockly.ASTNode.prototype.getWsCoordinate = function() {
|
||||
ASTNode.prototype.getWsCoordinate = function() {
|
||||
return this.wsCoordinate_;
|
||||
};
|
||||
|
||||
@@ -288,7 +289,7 @@ Blockly.ASTNode.prototype.getWsCoordinate = function() {
|
||||
* @return {boolean} [description]
|
||||
* @package
|
||||
*/
|
||||
Blockly.ASTNode.prototype.isConnection = function() {
|
||||
ASTNode.prototype.isConnection = function() {
|
||||
return this.isConnection_;
|
||||
};
|
||||
|
||||
@@ -296,12 +297,12 @@ Blockly.ASTNode.prototype.isConnection = function() {
|
||||
* Given an input find the next editable field or an input with a non null
|
||||
* connection in the same block. The current location must be an input
|
||||
* connection.
|
||||
* @return {Blockly.ASTNode} The AST node holding the next field or connection
|
||||
* @return {ASTNode} The AST node holding the next field or connection
|
||||
* or null if there is no editable field or input connection after the given
|
||||
* input.
|
||||
* @private
|
||||
*/
|
||||
Blockly.ASTNode.prototype.findNextForInput_ = function() {
|
||||
ASTNode.prototype.findNextForInput_ = function() {
|
||||
const location = /** @type {!Blockly.Connection} */ (this.location_);
|
||||
const parentInput = location.getParentInput();
|
||||
const block = parentInput.getSourceBlock();
|
||||
@@ -311,12 +312,12 @@ Blockly.ASTNode.prototype.findNextForInput_ = function() {
|
||||
const fieldRow = input.fieldRow;
|
||||
let j = 0, field;
|
||||
for (; (field = fieldRow[j]); j++) {
|
||||
if (field.isClickable() || Blockly.ASTNode.NAVIGATE_ALL_FIELDS) {
|
||||
return Blockly.ASTNode.createFieldNode(field);
|
||||
if (field.isClickable() || ASTNode.NAVIGATE_ALL_FIELDS) {
|
||||
return ASTNode.createFieldNode(field);
|
||||
}
|
||||
}
|
||||
if (input.connection) {
|
||||
return Blockly.ASTNode.createInputNode(input);
|
||||
return ASTNode.createInputNode(input);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -325,12 +326,12 @@ Blockly.ASTNode.prototype.findNextForInput_ = function() {
|
||||
/**
|
||||
* Given a field find the next editable field or an input with a non null
|
||||
* connection in the same block. The current location must be a field.
|
||||
* @return {Blockly.ASTNode} The AST node pointing to the next field or
|
||||
* @return {ASTNode} The AST node pointing to the next field or
|
||||
* connection or null if there is no editable field or input connection
|
||||
* after the given input.
|
||||
* @private
|
||||
*/
|
||||
Blockly.ASTNode.prototype.findNextForField_ = function() {
|
||||
ASTNode.prototype.findNextForField_ = function() {
|
||||
const location = /** @type {!Blockly.Field} */ (this.location_);
|
||||
const input = location.getParentInput();
|
||||
const block = location.getSourceBlock();
|
||||
@@ -340,14 +341,14 @@ Blockly.ASTNode.prototype.findNextForField_ = function() {
|
||||
for (; (newInput = block.inputList[i]); i++) {
|
||||
const fieldRow = newInput.fieldRow;
|
||||
while (fieldIdx < fieldRow.length) {
|
||||
if (fieldRow[fieldIdx].isClickable() || Blockly.ASTNode.NAVIGATE_ALL_FIELDS) {
|
||||
return Blockly.ASTNode.createFieldNode(fieldRow[fieldIdx]);
|
||||
if (fieldRow[fieldIdx].isClickable() || ASTNode.NAVIGATE_ALL_FIELDS) {
|
||||
return ASTNode.createFieldNode(fieldRow[fieldIdx]);
|
||||
}
|
||||
fieldIdx++;
|
||||
}
|
||||
fieldIdx = 0;
|
||||
if (newInput.connection) {
|
||||
return Blockly.ASTNode.createInputNode(newInput);
|
||||
return ASTNode.createInputNode(newInput);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -357,11 +358,11 @@ Blockly.ASTNode.prototype.findNextForField_ = function() {
|
||||
* Given an input find the previous editable field or an input with a non null
|
||||
* connection in the same block. The current location must be an input
|
||||
* connection.
|
||||
* @return {Blockly.ASTNode} The AST node holding the previous field or
|
||||
* @return {ASTNode} The AST node holding the previous field or
|
||||
* connection.
|
||||
* @private
|
||||
*/
|
||||
Blockly.ASTNode.prototype.findPrevForInput_ = function() {
|
||||
ASTNode.prototype.findPrevForInput_ = function() {
|
||||
const location = /** @type {!Blockly.Connection} */ (this.location_);
|
||||
const parentInput = location.getParentInput();
|
||||
const block = parentInput.getSourceBlock();
|
||||
@@ -369,13 +370,13 @@ Blockly.ASTNode.prototype.findPrevForInput_ = function() {
|
||||
let i = curIdx, input;
|
||||
for (; (input = block.inputList[i]); i--) {
|
||||
if (input.connection && input !== parentInput) {
|
||||
return Blockly.ASTNode.createInputNode(input);
|
||||
return ASTNode.createInputNode(input);
|
||||
}
|
||||
const fieldRow = input.fieldRow;
|
||||
let j = fieldRow.length - 1, field;
|
||||
for (; (field = fieldRow[j]); j--) {
|
||||
if (field.isClickable() || Blockly.ASTNode.NAVIGATE_ALL_FIELDS) {
|
||||
return Blockly.ASTNode.createFieldNode(field);
|
||||
if (field.isClickable() || ASTNode.NAVIGATE_ALL_FIELDS) {
|
||||
return ASTNode.createFieldNode(field);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -385,10 +386,10 @@ Blockly.ASTNode.prototype.findPrevForInput_ = function() {
|
||||
/**
|
||||
* Given a field find the previous editable field or an input with a non null
|
||||
* connection in the same block. The current location must be a field.
|
||||
* @return {Blockly.ASTNode} The AST node holding the previous input or field.
|
||||
* @return {ASTNode} The AST node holding the previous input or field.
|
||||
* @private
|
||||
*/
|
||||
Blockly.ASTNode.prototype.findPrevForField_ = function() {
|
||||
ASTNode.prototype.findPrevForField_ = function() {
|
||||
const location = /** @type {!Blockly.Field} */ (this.location_);
|
||||
const parentInput = location.getParentInput();
|
||||
const block = location.getSourceBlock();
|
||||
@@ -398,12 +399,12 @@ Blockly.ASTNode.prototype.findPrevForField_ = function() {
|
||||
let i = curIdx, input;
|
||||
for (; (input = block.inputList[i]); i--) {
|
||||
if (input.connection && input !== parentInput) {
|
||||
return Blockly.ASTNode.createInputNode(input);
|
||||
return ASTNode.createInputNode(input);
|
||||
}
|
||||
const fieldRow = input.fieldRow;
|
||||
while (fieldIdx > -1) {
|
||||
if (fieldRow[fieldIdx].isClickable() || Blockly.ASTNode.NAVIGATE_ALL_FIELDS) {
|
||||
return Blockly.ASTNode.createFieldNode(fieldRow[fieldIdx]);
|
||||
if (fieldRow[fieldIdx].isClickable() || ASTNode.NAVIGATE_ALL_FIELDS) {
|
||||
return ASTNode.createFieldNode(fieldRow[fieldIdx]);
|
||||
}
|
||||
fieldIdx--;
|
||||
}
|
||||
@@ -418,11 +419,11 @@ Blockly.ASTNode.prototype.findPrevForField_ = function() {
|
||||
/**
|
||||
* Navigate between stacks of blocks on the workspace.
|
||||
* @param {boolean} forward True to go forward. False to go backwards.
|
||||
* @return {Blockly.ASTNode} The first block of the next stack or null if there
|
||||
* @return {ASTNode} The first block of the next stack or null if there
|
||||
* are no blocks on the workspace.
|
||||
* @private
|
||||
*/
|
||||
Blockly.ASTNode.prototype.navigateBetweenStacks_ = function(forward) {
|
||||
ASTNode.prototype.navigateBetweenStacks_ = function(forward) {
|
||||
var curLocation = this.getLocation();
|
||||
if (curLocation.getSourceBlock) {
|
||||
curLocation = /** @type {!Blockly.IASTNodeLocationWithBlock} */ (
|
||||
@@ -441,7 +442,7 @@ Blockly.ASTNode.prototype.navigateBetweenStacks_ = function(forward) {
|
||||
if (resultIndex == -1 || resultIndex == topBlocks.length) {
|
||||
return null;
|
||||
}
|
||||
return Blockly.ASTNode.createStackNode(topBlocks[resultIndex]);
|
||||
return ASTNode.createStackNode(topBlocks[resultIndex]);
|
||||
}
|
||||
}
|
||||
throw Error('Couldn\'t find ' + (forward ? 'next' : 'previous') + ' stack?!');
|
||||
@@ -453,16 +454,16 @@ Blockly.ASTNode.prototype.navigateBetweenStacks_ = function(forward) {
|
||||
* on what kind of connections the block has.
|
||||
* @param {!Blockly.Block} block The block that we want to find the top
|
||||
* connection on.
|
||||
* @return {!Blockly.ASTNode} The AST node containing the top connection.
|
||||
* @return {!ASTNode} The AST node containing the top connection.
|
||||
* @private
|
||||
*/
|
||||
Blockly.ASTNode.prototype.findTopASTNodeForBlock_ = function(block) {
|
||||
ASTNode.prototype.findTopASTNodeForBlock_ = function(block) {
|
||||
const topConnection = block.previousConnection || block.outputConnection;
|
||||
if (topConnection) {
|
||||
return /** @type {!Blockly.ASTNode} */ (Blockly.ASTNode.createConnectionNode(
|
||||
return /** @type {!ASTNode} */ (ASTNode.createConnectionNode(
|
||||
topConnection));
|
||||
} else {
|
||||
return /** @type {!Blockly.ASTNode} */ (Blockly.ASTNode.createBlockNode(
|
||||
return /** @type {!ASTNode} */ (ASTNode.createBlockNode(
|
||||
block));
|
||||
}
|
||||
};
|
||||
@@ -471,11 +472,11 @@ Blockly.ASTNode.prototype.findTopASTNodeForBlock_ = function(block) {
|
||||
* Get the AST node pointing to the input that the block is nested under or if
|
||||
* the block is not nested then get the stack AST node.
|
||||
* @param {Blockly.Block} block The source block of the current location.
|
||||
* @return {Blockly.ASTNode} The AST node pointing to the input connection or
|
||||
* @return {ASTNode} The AST node pointing to the input connection or
|
||||
* the top block of the stack this block is in.
|
||||
* @private
|
||||
*/
|
||||
Blockly.ASTNode.prototype.getOutAstNodeForBlock_ = function(block) {
|
||||
ASTNode.prototype.getOutAstNodeForBlock_ = function(block) {
|
||||
if (!block) {
|
||||
return null;
|
||||
}
|
||||
@@ -489,34 +490,34 @@ Blockly.ASTNode.prototype.getOutAstNodeForBlock_ = function(block) {
|
||||
// that input.
|
||||
if (topConnection && topConnection.targetConnection &&
|
||||
topConnection.targetConnection.getParentInput()) {
|
||||
return Blockly.ASTNode.createInputNode(
|
||||
return ASTNode.createInputNode(
|
||||
topConnection.targetConnection.getParentInput());
|
||||
} else {
|
||||
// Go to stack level if you are not underneath an input.
|
||||
return Blockly.ASTNode.createStackNode(topBlock);
|
||||
return ASTNode.createStackNode(topBlock);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Find the first editable field or input with a connection on a given block.
|
||||
* @param {!Blockly.Block} block The source block of the current location.
|
||||
* @return {Blockly.ASTNode} An AST node pointing to the first field or input.
|
||||
* @return {ASTNode} An AST node pointing to the first field or input.
|
||||
* Null if there are no editable fields or inputs with connections on the block.
|
||||
* @private
|
||||
*/
|
||||
Blockly.ASTNode.prototype.findFirstFieldOrInput_ = function(block) {
|
||||
ASTNode.prototype.findFirstFieldOrInput_ = function(block) {
|
||||
const inputs = block.inputList;
|
||||
let i = 0, input;
|
||||
for (; (input = inputs[i]); i++) {
|
||||
const fieldRow = input.fieldRow;
|
||||
let j = 0, field;
|
||||
for (; (field = fieldRow[j]); j++) {
|
||||
if (field.isClickable() || Blockly.ASTNode.NAVIGATE_ALL_FIELDS) {
|
||||
return Blockly.ASTNode.createFieldNode(field);
|
||||
if (field.isClickable() || ASTNode.NAVIGATE_ALL_FIELDS) {
|
||||
return ASTNode.createFieldNode(field);
|
||||
}
|
||||
}
|
||||
if (input.connection) {
|
||||
return Blockly.ASTNode.createInputNode(input);
|
||||
return ASTNode.createInputNode(input);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -527,12 +528,12 @@ Blockly.ASTNode.prototype.findFirstFieldOrInput_ = function(block) {
|
||||
* @return {Blockly.Block} The source block of the location, or null if the node
|
||||
* is of type workspace.
|
||||
*/
|
||||
Blockly.ASTNode.prototype.getSourceBlock = function() {
|
||||
if (this.getType() === Blockly.ASTNode.types.BLOCK) {
|
||||
ASTNode.prototype.getSourceBlock = function() {
|
||||
if (this.getType() === ASTNode.types.BLOCK) {
|
||||
return /** @type {Blockly.Block} */ (this.getLocation());
|
||||
} else if (this.getType() === Blockly.ASTNode.types.STACK) {
|
||||
} else if (this.getType() === ASTNode.types.STACK) {
|
||||
return /** @type {Blockly.Block} */ (this.getLocation());
|
||||
} else if (this.getType() === Blockly.ASTNode.types.WORKSPACE) {
|
||||
} else if (this.getType() === ASTNode.types.WORKSPACE) {
|
||||
return null;
|
||||
} else {
|
||||
return /** @type {Blockly.IASTNodeLocationWithBlock} */ (
|
||||
@@ -542,38 +543,38 @@ Blockly.ASTNode.prototype.getSourceBlock = function() {
|
||||
|
||||
/**
|
||||
* Find the element to the right of the current element in the AST.
|
||||
* @return {Blockly.ASTNode} An AST node that wraps the next field, connection,
|
||||
* @return {ASTNode} An AST node that wraps the next field, connection,
|
||||
* block, or workspace. Or null if there is no node to the right.
|
||||
*/
|
||||
Blockly.ASTNode.prototype.next = function() {
|
||||
ASTNode.prototype.next = function() {
|
||||
let connection, block, nextConnection, targetConnection;
|
||||
switch (this.type_) {
|
||||
case Blockly.ASTNode.types.STACK:
|
||||
case ASTNode.types.STACK:
|
||||
return this.navigateBetweenStacks_(true);
|
||||
|
||||
case Blockly.ASTNode.types.OUTPUT:
|
||||
case ASTNode.types.OUTPUT:
|
||||
connection = /** @type {!Blockly.Connection} */ (this.location_);
|
||||
return Blockly.ASTNode.createBlockNode(connection.getSourceBlock());
|
||||
return ASTNode.createBlockNode(connection.getSourceBlock());
|
||||
|
||||
case Blockly.ASTNode.types.FIELD:
|
||||
case ASTNode.types.FIELD:
|
||||
return this.findNextForField_();
|
||||
|
||||
case Blockly.ASTNode.types.INPUT:
|
||||
case ASTNode.types.INPUT:
|
||||
return this.findNextForInput_();
|
||||
|
||||
case Blockly.ASTNode.types.BLOCK:
|
||||
case ASTNode.types.BLOCK:
|
||||
block = /** @type {!Blockly.Block} */ (this.location_);
|
||||
nextConnection = block.nextConnection;
|
||||
return Blockly.ASTNode.createConnectionNode(nextConnection);
|
||||
return ASTNode.createConnectionNode(nextConnection);
|
||||
|
||||
case Blockly.ASTNode.types.PREVIOUS:
|
||||
case ASTNode.types.PREVIOUS:
|
||||
connection = /** @type {!Blockly.Connection} */ (this.location_);
|
||||
return Blockly.ASTNode.createBlockNode(connection.getSourceBlock());
|
||||
return ASTNode.createBlockNode(connection.getSourceBlock());
|
||||
|
||||
case Blockly.ASTNode.types.NEXT:
|
||||
case ASTNode.types.NEXT:
|
||||
connection = /** @type {!Blockly.Connection} */ (this.location_);
|
||||
targetConnection = connection.targetConnection;
|
||||
return Blockly.ASTNode.createConnectionNode(targetConnection);
|
||||
return ASTNode.createConnectionNode(targetConnection);
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -582,32 +583,32 @@ Blockly.ASTNode.prototype.next = function() {
|
||||
/**
|
||||
* Find the element one level below and all the way to the left of the current
|
||||
* location.
|
||||
* @return {Blockly.ASTNode} An AST node that wraps the next field, connection,
|
||||
* @return {ASTNode} An AST node that wraps the next field, connection,
|
||||
* workspace, or block. Or null if there is nothing below this node.
|
||||
*/
|
||||
Blockly.ASTNode.prototype.in = function() {
|
||||
ASTNode.prototype.in = function() {
|
||||
let workspace, topBlocks, block, connection, targetConnection;
|
||||
switch (this.type_) {
|
||||
case Blockly.ASTNode.types.WORKSPACE:
|
||||
case ASTNode.types.WORKSPACE:
|
||||
workspace = /** @type {!Blockly.Workspace} */ (this.location_);
|
||||
topBlocks = workspace.getTopBlocks(true);
|
||||
if (topBlocks.length > 0) {
|
||||
return Blockly.ASTNode.createStackNode(topBlocks[0]);
|
||||
return ASTNode.createStackNode(topBlocks[0]);
|
||||
}
|
||||
break;
|
||||
|
||||
case Blockly.ASTNode.types.STACK:
|
||||
case ASTNode.types.STACK:
|
||||
block = /** @type {!Blockly.Block} */ (this.location_);
|
||||
return this.findTopASTNodeForBlock_(block);
|
||||
|
||||
case Blockly.ASTNode.types.BLOCK:
|
||||
case ASTNode.types.BLOCK:
|
||||
block = /** @type {!Blockly.Block} */ (this.location_);
|
||||
return this.findFirstFieldOrInput_(block);
|
||||
|
||||
case Blockly.ASTNode.types.INPUT:
|
||||
case ASTNode.types.INPUT:
|
||||
connection = /** @type {!Blockly.Connection} */ (this.location_);
|
||||
targetConnection = connection.targetConnection;
|
||||
return Blockly.ASTNode.createConnectionNode(targetConnection);
|
||||
return ASTNode.createConnectionNode(targetConnection);
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -615,41 +616,41 @@ Blockly.ASTNode.prototype.in = function() {
|
||||
|
||||
/**
|
||||
* Find the element to the left of the current element in the AST.
|
||||
* @return {Blockly.ASTNode} An AST node that wraps the previous field,
|
||||
* @return {ASTNode} An AST node that wraps the previous field,
|
||||
* connection, workspace or block. Or null if no node exists to the left.
|
||||
* null.
|
||||
*/
|
||||
Blockly.ASTNode.prototype.prev = function() {
|
||||
ASTNode.prototype.prev = function() {
|
||||
let block, topConnection, connection, targetConnection;
|
||||
switch (this.type_) {
|
||||
case Blockly.ASTNode.types.STACK:
|
||||
case ASTNode.types.STACK:
|
||||
return this.navigateBetweenStacks_(false);
|
||||
|
||||
case Blockly.ASTNode.types.OUTPUT:
|
||||
case ASTNode.types.OUTPUT:
|
||||
return null;
|
||||
|
||||
case Blockly.ASTNode.types.FIELD:
|
||||
case ASTNode.types.FIELD:
|
||||
return this.findPrevForField_();
|
||||
|
||||
case Blockly.ASTNode.types.INPUT:
|
||||
case ASTNode.types.INPUT:
|
||||
return this.findPrevForInput_();
|
||||
|
||||
case Blockly.ASTNode.types.BLOCK:
|
||||
case ASTNode.types.BLOCK:
|
||||
block = /** @type {!Blockly.Block} */ (this.location_);
|
||||
topConnection = block.previousConnection || block.outputConnection;
|
||||
return Blockly.ASTNode.createConnectionNode(topConnection);
|
||||
return ASTNode.createConnectionNode(topConnection);
|
||||
|
||||
case Blockly.ASTNode.types.PREVIOUS:
|
||||
case ASTNode.types.PREVIOUS:
|
||||
connection = /** @type {!Blockly.Connection} */ (this.location_);
|
||||
targetConnection = connection.targetConnection;
|
||||
if (targetConnection && !targetConnection.getParentInput()) {
|
||||
return Blockly.ASTNode.createConnectionNode(targetConnection);
|
||||
return ASTNode.createConnectionNode(targetConnection);
|
||||
}
|
||||
break;
|
||||
|
||||
case Blockly.ASTNode.types.NEXT:
|
||||
case ASTNode.types.NEXT:
|
||||
connection = /** @type {!Blockly.Connection} */ (this.location_);
|
||||
return Blockly.ASTNode.createBlockNode(connection.getSourceBlock());
|
||||
return ASTNode.createBlockNode(connection.getSourceBlock());
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -658,48 +659,50 @@ Blockly.ASTNode.prototype.prev = function() {
|
||||
/**
|
||||
* Find the next element that is one position above and all the way to the left
|
||||
* of the current location.
|
||||
* @return {Blockly.ASTNode} An AST node that wraps the next field, connection,
|
||||
* @return {ASTNode} An AST node that wraps the next field, connection,
|
||||
* workspace or block. Or null if we are at the workspace level.
|
||||
*/
|
||||
Blockly.ASTNode.prototype.out = function() {
|
||||
ASTNode.prototype.out = function() {
|
||||
let block, blockPos, wsCoordinate, connection, target, field;
|
||||
switch (this.type_) {
|
||||
case Blockly.ASTNode.types.STACK:
|
||||
case ASTNode.types.STACK:
|
||||
block = /** @type {!Blockly.Block} */ (this.location_);
|
||||
blockPos = block.getRelativeToSurfaceXY();
|
||||
// TODO: Make sure this is in the bounds of the workspace.
|
||||
wsCoordinate = new Blockly.utils.Coordinate(
|
||||
blockPos.x, blockPos.y + Blockly.ASTNode.DEFAULT_OFFSET_Y);
|
||||
return Blockly.ASTNode.createWorkspaceNode(block.workspace, wsCoordinate);
|
||||
blockPos.x, blockPos.y + ASTNode.DEFAULT_OFFSET_Y);
|
||||
return ASTNode.createWorkspaceNode(block.workspace, wsCoordinate);
|
||||
|
||||
case Blockly.ASTNode.types.OUTPUT:
|
||||
case ASTNode.types.OUTPUT:
|
||||
connection = /** @type {!Blockly.Connection} */ (this.location_);
|
||||
target = connection.targetConnection;
|
||||
if (target) {
|
||||
return Blockly.ASTNode.createConnectionNode(target);
|
||||
return ASTNode.createConnectionNode(target);
|
||||
}
|
||||
return Blockly.ASTNode.createStackNode(connection.getSourceBlock());
|
||||
return ASTNode.createStackNode(connection.getSourceBlock());
|
||||
|
||||
case Blockly.ASTNode.types.FIELD:
|
||||
case ASTNode.types.FIELD:
|
||||
field = /** @type {!Blockly.Field} */ (this.location_);
|
||||
return Blockly.ASTNode.createBlockNode(field.getSourceBlock());
|
||||
return ASTNode.createBlockNode(field.getSourceBlock());
|
||||
|
||||
case Blockly.ASTNode.types.INPUT:
|
||||
case ASTNode.types.INPUT:
|
||||
connection = /** @type {!Blockly.Connection} */ (this.location_);
|
||||
return Blockly.ASTNode.createBlockNode(connection.getSourceBlock());
|
||||
return ASTNode.createBlockNode(connection.getSourceBlock());
|
||||
|
||||
case Blockly.ASTNode.types.BLOCK:
|
||||
case ASTNode.types.BLOCK:
|
||||
block = /** @type {!Blockly.Block} */ (this.location_);
|
||||
return this.getOutAstNodeForBlock_(block);
|
||||
|
||||
case Blockly.ASTNode.types.PREVIOUS:
|
||||
case ASTNode.types.PREVIOUS:
|
||||
connection = /** @type {!Blockly.Connection} */ (this.location_);
|
||||
return this.getOutAstNodeForBlock_(connection.getSourceBlock());
|
||||
|
||||
case Blockly.ASTNode.types.NEXT:
|
||||
case ASTNode.types.NEXT:
|
||||
connection = /** @type {!Blockly.Connection} */ (this.location_);
|
||||
return this.getOutAstNodeForBlock_(connection.getSourceBlock());
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
exports = ASTNode;
|
||||
|
||||
Reference in New Issue
Block a user