mirror of
https://github.com/google/blockly.git
synced 2026-01-31 20:50:10 +01:00
Add accessibility interfaces and fix navigation types (#3908)
* Add accessibility interfaces and fix navigation types
This commit is contained in:
@@ -30,6 +30,8 @@ goog.require('Blockly.utils.object');
|
||||
goog.require('Blockly.utils.string');
|
||||
goog.require('Blockly.Workspace');
|
||||
|
||||
goog.requireType('Blockly.IASTNodeLocation');
|
||||
|
||||
|
||||
/**
|
||||
* Class for one block.
|
||||
@@ -40,6 +42,7 @@ goog.require('Blockly.Workspace');
|
||||
* @param {string=} opt_id Optional ID. Use this ID if provided, otherwise
|
||||
* create a new ID.
|
||||
* @constructor
|
||||
* @implements {Blockly.IASTNodeLocation}
|
||||
* @throws When block is not valid or block name is not allowed.
|
||||
*/
|
||||
Blockly.Block = function(workspace, prototypeName, opt_id) {
|
||||
|
||||
@@ -32,9 +32,11 @@ goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.object');
|
||||
goog.require('Blockly.utils.Rect');
|
||||
|
||||
goog.requireType('Blockly.IASTNodeLocationSvg');
|
||||
goog.requireType('Blockly.IBoundedElement');
|
||||
goog.requireType('Blockly.ICopyable');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a block's SVG representation.
|
||||
* Not normally called directly, workspace.newBlock() is preferred.
|
||||
@@ -44,6 +46,7 @@ goog.requireType('Blockly.ICopyable');
|
||||
* @param {string=} opt_id Optional ID. Use this ID if provided, otherwise
|
||||
* create a new ID.
|
||||
* @extends {Blockly.Block}
|
||||
* @implements {Blockly.IASTNodeLocationSvg}
|
||||
* @implements {Blockly.IBoundedElement}
|
||||
* @implements {Blockly.ICopyable}
|
||||
* @constructor
|
||||
|
||||
@@ -160,7 +160,7 @@ Blockly.svgResize = function(workspace) {
|
||||
/**
|
||||
* Handle a key-down on SVG drawing surface. Does nothing if the main workspace
|
||||
* is not visible.
|
||||
* @param {!Event} e Key down event.
|
||||
* @param {!KeyboardEvent} e Key down event.
|
||||
* @package
|
||||
*/
|
||||
// TODO (https://github.com/google/blockly/issues/1998) handle cases where there
|
||||
|
||||
@@ -16,12 +16,15 @@ goog.require('Blockly.Events');
|
||||
goog.require('Blockly.Events.BlockMove');
|
||||
goog.require('Blockly.Xml');
|
||||
|
||||
goog.requireType('Blockly.IASTNodeLocationWithBlock');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a connection between blocks.
|
||||
* @param {!Blockly.Block} source The block establishing this connection.
|
||||
* @param {number} type The type of the connection.
|
||||
* @constructor
|
||||
* @implements {Blockly.IASTNodeLocationWithBlock}
|
||||
*/
|
||||
Blockly.Connection = function(source, type) {
|
||||
/**
|
||||
|
||||
@@ -24,6 +24,9 @@ goog.require('Blockly.utils.style');
|
||||
goog.require('Blockly.utils.userAgent');
|
||||
|
||||
goog.requireType('Blockly.blockRendering.ConstantProvider');
|
||||
goog.requireType('Blockly.IASTNodeLocationSvg');
|
||||
goog.requireType('Blockly.IASTNodeLocationWithBlock');
|
||||
goog.requireType('Blockly.IBlocklyActionable');
|
||||
|
||||
|
||||
/**
|
||||
@@ -36,6 +39,9 @@ goog.requireType('Blockly.blockRendering.ConstantProvider');
|
||||
* the individual field's documentation for a list of properties this
|
||||
* parameter supports.
|
||||
* @constructor
|
||||
* @implements {Blockly.IASTNodeLocationSvg}
|
||||
* @implements {Blockly.IASTNodeLocationWithBlock}
|
||||
* @implements {Blockly.IBlocklyActionable}
|
||||
*/
|
||||
Blockly.Field = function(value, opt_validator, opt_config) {
|
||||
/**
|
||||
@@ -1105,7 +1111,8 @@ Blockly.Field.prototype.setMarkerSvg = function(markerSvg) {
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Field.prototype.updateMarkers_ = function() {
|
||||
var workspace = this.sourceBlock_.workspace;
|
||||
var workspace =
|
||||
/** @type {!Blockly.WorkspaceSvg} */ (this.sourceBlock_.workspace);
|
||||
if (workspace.keyboardAccessibilityMode && this.cursorSvg_) {
|
||||
workspace.getCursor().draw();
|
||||
}
|
||||
|
||||
@@ -29,12 +29,15 @@ goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.WorkspaceSvg');
|
||||
goog.require('Blockly.Xml');
|
||||
|
||||
goog.requireType('Blockly.IBlocklyActionable');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a flyout.
|
||||
* @param {!Blockly.Options} workspaceOptions Dictionary of options for the
|
||||
* workspace.
|
||||
* @constructor
|
||||
* @implements {Blockly.IBlocklyActionable}
|
||||
*/
|
||||
Blockly.Flyout = function(workspaceOptions) {
|
||||
workspaceOptions.getMetrics = this.getMetrics_.bind(this);
|
||||
|
||||
72
core/interfaces/i_accessibility.js
Normal file
72
core/interfaces/i_accessibility.js
Normal file
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2020 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview AST Node and keyboard navigation interfaces.
|
||||
* @author samelh@google.com (Sam El-Husseini)
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.IASTNodeLocation');
|
||||
goog.provide('Blockly.IASTNodeLocationSvg');
|
||||
goog.provide('Blockly.IASTNodeLocationWithBlock');
|
||||
goog.provide('Blockly.IBlocklyActionable');
|
||||
|
||||
/**
|
||||
* An AST node location interface.
|
||||
* @interface
|
||||
*/
|
||||
Blockly.IASTNodeLocation = function() {};
|
||||
|
||||
/**
|
||||
* An AST node location SVG interface.
|
||||
* @interface
|
||||
* @extends {Blockly.IASTNodeLocation}
|
||||
*/
|
||||
Blockly.IASTNodeLocationSvg = function() {};
|
||||
|
||||
/**
|
||||
* Add the marker svg to this node's svg group.
|
||||
* @param {SVGElement} markerSvg The svg root of the marker to be added to the
|
||||
* svg group.
|
||||
*/
|
||||
Blockly.IASTNodeLocationSvg.prototype.setMarkerSvg;
|
||||
|
||||
/**
|
||||
* Add the cursor svg to this node's svg group.
|
||||
* @param {SVGElement} cursorSvg The svg root of the cursor to be added to the
|
||||
* svg group.
|
||||
*/
|
||||
Blockly.IASTNodeLocationSvg.prototype.setCursorSvg;
|
||||
|
||||
/**
|
||||
* An AST node location that has an associated block.
|
||||
* @interface
|
||||
* @extends {Blockly.IASTNodeLocation}
|
||||
*/
|
||||
Blockly.IASTNodeLocationWithBlock = function() {};
|
||||
|
||||
/**
|
||||
* Get the source block associated with this node.
|
||||
* @return {Blockly.Block} The source block.
|
||||
*/
|
||||
Blockly.IASTNodeLocationWithBlock.prototype.getSourceBlock;
|
||||
|
||||
|
||||
/**
|
||||
* An interface for an object that handles Blockly actions when keyboard
|
||||
* navigation is enabled.
|
||||
* @interface
|
||||
*/
|
||||
Blockly.IBlocklyActionable = function() {};
|
||||
|
||||
/**
|
||||
* Handles the given action.
|
||||
* @param {!Blockly.Action} action The action to be handled.
|
||||
* @return {boolean} True if the action has been handled, false otherwise.
|
||||
*/
|
||||
Blockly.IBlocklyActionable.prototype.onBlocklyAction;
|
||||
@@ -14,6 +14,9 @@ goog.provide('Blockly.ASTNode');
|
||||
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
|
||||
goog.requireType('Blockly.IASTNodeLocation');
|
||||
goog.requireType('Blockly.IASTNodeLocationWithBlock');
|
||||
|
||||
|
||||
/**
|
||||
* Class for an AST node.
|
||||
@@ -21,9 +24,8 @@ goog.require('Blockly.utils.Coordinate');
|
||||
* creating a node directly.
|
||||
* @param {string} type The type of the location.
|
||||
* Must be in Blockly.ASTNode.types.
|
||||
* @param {!(Blockly.Block|Blockly.Connection|Blockly.Field|Blockly.Workspace)}
|
||||
* location The position in the AST.
|
||||
* @param {!Object=} opt_params Optional dictionary of options.
|
||||
* @param {!Blockly.IASTNodeLocation} location The position in the AST.
|
||||
* @param {!Blockly.ASTNode.Params=} opt_params Optional dictionary of options.
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.ASTNode = function(type, location, opt_params) {
|
||||
@@ -48,14 +50,28 @@ Blockly.ASTNode = function(type, location, opt_params) {
|
||||
|
||||
/**
|
||||
* The location of the AST node.
|
||||
* @type {!(Blockly.Block|Blockly.Connection|Blockly.Field|Blockly.Workspace)}
|
||||
* @type {!Blockly.IASTNodeLocation}
|
||||
* @private
|
||||
*/
|
||||
this.location_ = location;
|
||||
|
||||
/**
|
||||
* The coordinate on the workspace.
|
||||
* @type {Blockly.utils.Coordinate}
|
||||
* @private
|
||||
*/
|
||||
this.wsCoordinate_ = null;
|
||||
|
||||
this.processParams_(opt_params || null);
|
||||
};
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* wsCoordinate: Blockly.utils.Coordinate,
|
||||
* }}
|
||||
*/
|
||||
Blockly.ASTNode.Params;
|
||||
|
||||
/**
|
||||
* Object holding different types for an AST node.
|
||||
* @enum {string}
|
||||
@@ -219,7 +235,7 @@ Blockly.ASTNode.createTopNode = function(block) {
|
||||
|
||||
/**
|
||||
* Parse the optional parameters.
|
||||
* @param {Object} params The user specified parameters.
|
||||
* @param {?Blockly.ASTNode.Params} params The user specified parameters.
|
||||
* @private
|
||||
*/
|
||||
Blockly.ASTNode.prototype.processParams_ = function(params) {
|
||||
@@ -235,8 +251,8 @@ Blockly.ASTNode.prototype.processParams_ = function(params) {
|
||||
* Gets the value pointed to by this node.
|
||||
* It is the callers responsibility to check the node type to figure out what
|
||||
* type of object they get back from this.
|
||||
* @return {!(Blockly.Field|Blockly.Connection|Blockly.Block|Blockly.Workspace)}
|
||||
* The current field, connection, workspace, or block the cursor is on.
|
||||
* @return {!Blockly.IASTNodeLocation} The current field, connection, workspace, or
|
||||
* block the cursor is on.
|
||||
*/
|
||||
Blockly.ASTNode.prototype.getLocation = function() {
|
||||
return this.location_;
|
||||
@@ -279,7 +295,8 @@ Blockly.ASTNode.prototype.isConnection = function() {
|
||||
* @private
|
||||
*/
|
||||
Blockly.ASTNode.prototype.findNextForInput_ = function() {
|
||||
var parentInput = this.location_.getParentInput();
|
||||
var location = /** @type {!Blockly.Connection} */ (this.location_);
|
||||
var parentInput = location.getParentInput();
|
||||
var block = parentInput.getSourceBlock();
|
||||
var curIdx = block.inputList.indexOf(parentInput);
|
||||
for (var i = curIdx + 1, input; (input = block.inputList[i]); i++) {
|
||||
@@ -335,11 +352,12 @@ Blockly.ASTNode.prototype.findNextForField_ = function() {
|
||||
* @private
|
||||
*/
|
||||
Blockly.ASTNode.prototype.findPrevForInput_ = function() {
|
||||
var location = this.location_.getParentInput();
|
||||
var block = location.getSourceBlock();
|
||||
var curIdx = block.inputList.indexOf(location);
|
||||
var location = /** @type {!Blockly.Connection} */ (this.location_);
|
||||
var parentInput = location.getParentInput();
|
||||
var block = parentInput.getSourceBlock();
|
||||
var curIdx = block.inputList.indexOf(parentInput);
|
||||
for (var i = curIdx, input; (input = block.inputList[i]); i--) {
|
||||
if (input.connection && input !== location) {
|
||||
if (input.connection && input !== parentInput) {
|
||||
return Blockly.ASTNode.createInputNode(input);
|
||||
}
|
||||
var fieldRow = input.fieldRow;
|
||||
@@ -394,7 +412,8 @@ Blockly.ASTNode.prototype.findPrevForField_ = function() {
|
||||
Blockly.ASTNode.prototype.navigateBetweenStacks_ = function(forward) {
|
||||
var curLocation = this.getLocation();
|
||||
if (!(curLocation instanceof Blockly.Block)) {
|
||||
curLocation = curLocation.getSourceBlock();
|
||||
curLocation = /** @type {!Blockly.IASTNodeLocationWithBlock} */ (
|
||||
curLocation).getSourceBlock();
|
||||
}
|
||||
if (!curLocation || !curLocation.workspace) {
|
||||
return null;
|
||||
@@ -499,7 +518,8 @@ Blockly.ASTNode.prototype.getSourceBlock = function() {
|
||||
} else if (this.getType() === Blockly.ASTNode.types.WORKSPACE) {
|
||||
return null;
|
||||
} else {
|
||||
return this.getLocation().getSourceBlock();
|
||||
return /** @type {Blockly.IASTNodeLocationWithBlock} */ (
|
||||
this.getLocation()).getSourceBlock();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -514,7 +534,8 @@ Blockly.ASTNode.prototype.next = function() {
|
||||
return this.navigateBetweenStacks_(true);
|
||||
|
||||
case Blockly.ASTNode.types.OUTPUT:
|
||||
return Blockly.ASTNode.createBlockNode(this.location_.getSourceBlock());
|
||||
var connection = /** @type {!Blockly.Connection} */ (this.location_);
|
||||
return Blockly.ASTNode.createBlockNode(connection.getSourceBlock());
|
||||
|
||||
case Blockly.ASTNode.types.FIELD:
|
||||
return this.findNextForField_();
|
||||
@@ -523,14 +544,17 @@ Blockly.ASTNode.prototype.next = function() {
|
||||
return this.findNextForInput_();
|
||||
|
||||
case Blockly.ASTNode.types.BLOCK:
|
||||
var nextConnection = this.location_.nextConnection;
|
||||
var block = /** @type {!Blockly.Block} */ (this.location_);
|
||||
var nextConnection = block.nextConnection;
|
||||
return Blockly.ASTNode.createConnectionNode(nextConnection);
|
||||
|
||||
case Blockly.ASTNode.types.PREVIOUS:
|
||||
return Blockly.ASTNode.createBlockNode(this.location_.getSourceBlock());
|
||||
var connection = /** @type {!Blockly.Connection} */ (this.location_);
|
||||
return Blockly.ASTNode.createBlockNode(connection.getSourceBlock());
|
||||
|
||||
case Blockly.ASTNode.types.NEXT:
|
||||
var targetConnection = this.location_.targetConnection;
|
||||
var connection = /** @type {!Blockly.Connection} */ (this.location_);
|
||||
var targetConnection = connection.targetConnection;
|
||||
return Blockly.ASTNode.createConnectionNode(targetConnection);
|
||||
}
|
||||
|
||||
@@ -546,7 +570,8 @@ Blockly.ASTNode.prototype.next = function() {
|
||||
Blockly.ASTNode.prototype.in = function() {
|
||||
switch (this.type_) {
|
||||
case Blockly.ASTNode.types.WORKSPACE:
|
||||
var topBlocks = this.location_.getTopBlocks(true);
|
||||
var workspace = /** @type {!Blockly.Workspace} */ (this.location_);
|
||||
var topBlocks = workspace.getTopBlocks(true);
|
||||
if (topBlocks.length > 0) {
|
||||
return Blockly.ASTNode.createStackNode(topBlocks[0]);
|
||||
}
|
||||
@@ -561,7 +586,8 @@ Blockly.ASTNode.prototype.in = function() {
|
||||
return this.findFirstFieldOrInput_(block);
|
||||
|
||||
case Blockly.ASTNode.types.INPUT:
|
||||
var targetConnection = this.location_.targetConnection;
|
||||
var connection = /** @type {!Blockly.Connection} */ (this.location_);
|
||||
var targetConnection = connection.targetConnection;
|
||||
return Blockly.ASTNode.createConnectionNode(targetConnection);
|
||||
}
|
||||
|
||||
@@ -589,19 +615,21 @@ Blockly.ASTNode.prototype.prev = function() {
|
||||
return this.findPrevForInput_();
|
||||
|
||||
case Blockly.ASTNode.types.BLOCK:
|
||||
var block = this.location_;
|
||||
var block = /** @type {!Blockly.Block} */ (this.location_);
|
||||
var topConnection = block.previousConnection || block.outputConnection;
|
||||
return Blockly.ASTNode.createConnectionNode(topConnection);
|
||||
|
||||
case Blockly.ASTNode.types.PREVIOUS:
|
||||
var targetConnection = this.location_.targetConnection;
|
||||
var connection = /** @type {!Blockly.Connection} */ (this.location_);
|
||||
var targetConnection = connection.targetConnection;
|
||||
if (targetConnection && !targetConnection.getParentInput()) {
|
||||
return Blockly.ASTNode.createConnectionNode(targetConnection);
|
||||
}
|
||||
break;
|
||||
|
||||
case Blockly.ASTNode.types.NEXT:
|
||||
return Blockly.ASTNode.createBlockNode(this.location_.getSourceBlock());
|
||||
var connection = /** @type {!Blockly.Connection} */ (this.location_);
|
||||
return Blockly.ASTNode.createBlockNode(connection.getSourceBlock());
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -616,35 +644,40 @@ Blockly.ASTNode.prototype.prev = function() {
|
||||
Blockly.ASTNode.prototype.out = function() {
|
||||
switch (this.type_) {
|
||||
case Blockly.ASTNode.types.STACK:
|
||||
var blockPos = this.location_.getRelativeToSurfaceXY();
|
||||
var block = /** @type {!Blockly.Block} */ (this.location_);
|
||||
var blockPos = block.getRelativeToSurfaceXY();
|
||||
// TODO: Make sure this is in the bounds of the workspace.
|
||||
var wsCoordinate = new Blockly.utils.Coordinate(
|
||||
blockPos.x, blockPos.y + Blockly.ASTNode.DEFAULT_OFFSET_Y);
|
||||
return Blockly.ASTNode.createWorkspaceNode(
|
||||
this.location_.workspace, wsCoordinate);
|
||||
return Blockly.ASTNode.createWorkspaceNode(block.workspace, wsCoordinate);
|
||||
|
||||
case Blockly.ASTNode.types.OUTPUT:
|
||||
var target = this.location_.targetConnection;
|
||||
var connection = /** @type {!Blockly.Connection} */ (this.location_);
|
||||
var target = connection.targetConnection;
|
||||
if (target) {
|
||||
return Blockly.ASTNode.createConnectionNode(target);
|
||||
}
|
||||
return Blockly.ASTNode.createStackNode(this.location_.getSourceBlock());
|
||||
return Blockly.ASTNode.createStackNode(connection.getSourceBlock());
|
||||
|
||||
case Blockly.ASTNode.types.FIELD:
|
||||
return Blockly.ASTNode.createBlockNode(this.location_.getSourceBlock());
|
||||
var field = /** @type {!Blockly.Field} */ (this.location_);
|
||||
return Blockly.ASTNode.createBlockNode(field.getSourceBlock());
|
||||
|
||||
case Blockly.ASTNode.types.INPUT:
|
||||
return Blockly.ASTNode.createBlockNode(this.location_.getSourceBlock());
|
||||
var connection = /** @type {!Blockly.Connection} */ (this.location_);
|
||||
return Blockly.ASTNode.createBlockNode(connection.getSourceBlock());
|
||||
|
||||
case Blockly.ASTNode.types.BLOCK:
|
||||
var block = /** @type {!Blockly.Block} */ (this.location_);
|
||||
return this.getOutAstNodeForBlock_(block);
|
||||
|
||||
case Blockly.ASTNode.types.PREVIOUS:
|
||||
return this.getOutAstNodeForBlock_(this.location_.getSourceBlock());
|
||||
var connection = /** @type {!Blockly.Connection} */ (this.location_);
|
||||
return this.getOutAstNodeForBlock_(connection.getSourceBlock());
|
||||
|
||||
case Blockly.ASTNode.types.NEXT:
|
||||
return this.getOutAstNodeForBlock_(this.location_.getSourceBlock());
|
||||
var connection = /** @type {!Blockly.Connection} */ (this.location_);
|
||||
return this.getOutAstNodeForBlock_(connection.getSourceBlock());
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -19,12 +19,15 @@ goog.require('Blockly.Marker');
|
||||
goog.require('Blockly.navigation');
|
||||
goog.require('Blockly.utils.object');
|
||||
|
||||
goog.requireType('Blockly.IBlocklyActionable');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a cursor.
|
||||
* A cursor controls how a user navigates the Blockly AST.
|
||||
* @constructor
|
||||
* @extends {Blockly.Marker}
|
||||
* @implements {Blockly.IBlocklyActionable}
|
||||
*/
|
||||
Blockly.Cursor = function() {
|
||||
Blockly.Cursor.superClass_.constructor.call(this);
|
||||
@@ -144,7 +147,8 @@ Blockly.Cursor.prototype.onBlocklyAction = function(action) {
|
||||
// If we are on a field give it the option to handle the action
|
||||
if (this.getCurNode() &&
|
||||
this.getCurNode().getType() === Blockly.ASTNode.types.FIELD &&
|
||||
this.getCurNode().getLocation().onBlocklyAction(action)) {
|
||||
(/** @type {!Blockly.Field} */ (this.getCurNode().getLocation()))
|
||||
.onBlocklyAction(action)) {
|
||||
return true;
|
||||
}
|
||||
switch (action.name) {
|
||||
|
||||
@@ -101,7 +101,7 @@ Blockly.user.keyMap.getKeyByAction = function(action) {
|
||||
|
||||
/**
|
||||
* Serialize the key event.
|
||||
* @param {!Event} e A key up event holding the key code.
|
||||
* @param {!KeyboardEvent} e A key up event holding the key code.
|
||||
* @return {string} A string containing the serialized key event.
|
||||
* @package
|
||||
*/
|
||||
|
||||
@@ -102,10 +102,19 @@ Blockly.navigation.MARKER_NAME = 'local_marker_1';
|
||||
|
||||
/**
|
||||
* Get the local marker.
|
||||
* @return {!Blockly.Marker} The local marker for the main workspace.
|
||||
* @return {Blockly.Marker} The local marker for the main workspace.
|
||||
*/
|
||||
Blockly.navigation.getMarker = function() {
|
||||
return Blockly.getMainWorkspace().getMarker(Blockly.navigation.MARKER_NAME);
|
||||
return Blockly.navigation.getNavigationWorkspace()
|
||||
.getMarker(Blockly.navigation.MARKER_NAME);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the workspace that is being navigated.
|
||||
* @return {!Blockly.WorkspaceSvg} The workspace being navigated.
|
||||
*/
|
||||
Blockly.navigation.getNavigationWorkspace = function() {
|
||||
return /** @type {!Blockly.WorkspaceSvg} */ (Blockly.getMainWorkspace());
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -114,8 +123,7 @@ Blockly.navigation.getMarker = function() {
|
||||
* @private
|
||||
*/
|
||||
Blockly.navigation.focusToolbox_ = function() {
|
||||
var workspace = Blockly.getMainWorkspace();
|
||||
var toolbox = workspace.getToolbox();
|
||||
var toolbox = Blockly.navigation.getNavigationWorkspace().getToolbox();
|
||||
if (toolbox) {
|
||||
Blockly.navigation.currentState_ = Blockly.navigation.STATE_TOOLBOX;
|
||||
Blockly.navigation.resetFlyout_(false /* shouldHide */);
|
||||
@@ -134,9 +142,9 @@ Blockly.navigation.focusToolbox_ = function() {
|
||||
Blockly.navigation.focusFlyout_ = function() {
|
||||
var topBlock = null;
|
||||
Blockly.navigation.currentState_ = Blockly.navigation.STATE_FLYOUT;
|
||||
var workspace = Blockly.getMainWorkspace();
|
||||
var workspace = Blockly.navigation.getNavigationWorkspace();
|
||||
var toolbox = workspace.getToolbox();
|
||||
var flyout = toolbox ? toolbox.flyout_ : workspace.getFlyout();
|
||||
var flyout = toolbox ? toolbox.getFlyout() : workspace.getFlyout();
|
||||
|
||||
if (!Blockly.navigation.getMarker().getCurNode()) {
|
||||
Blockly.navigation.markAtCursor_();
|
||||
@@ -159,7 +167,7 @@ Blockly.navigation.focusFlyout_ = function() {
|
||||
*/
|
||||
Blockly.navigation.focusWorkspace_ = function() {
|
||||
Blockly.hideChaff();
|
||||
var workspace = Blockly.getMainWorkspace();
|
||||
var workspace = Blockly.navigation.getNavigationWorkspace();
|
||||
var cursor = workspace.getCursor();
|
||||
var reset = !!workspace.getToolbox();
|
||||
var topBlocks = workspace.getTopBlocks(true);
|
||||
@@ -186,14 +194,14 @@ Blockly.navigation.focusWorkspace_ = function() {
|
||||
* @private
|
||||
*/
|
||||
Blockly.navigation.getFlyoutCursor_ = function() {
|
||||
var workspace = Blockly.getMainWorkspace();
|
||||
var workspace = Blockly.navigation.getNavigationWorkspace();
|
||||
var cursor = null;
|
||||
if (workspace.rendered) {
|
||||
var toolbox = workspace.getToolbox();
|
||||
var flyout = toolbox ? toolbox.flyout_ : workspace.getFlyout();
|
||||
cursor = flyout ? flyout.workspace_.getCursor() : null;
|
||||
var flyout = toolbox ? toolbox.getFlyout() : workspace.getFlyout();
|
||||
cursor = flyout ? flyout.getWorkspace().getCursor() : null;
|
||||
}
|
||||
return cursor;
|
||||
return /** @type {Blockly.FlyoutCursor} */ (cursor);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -202,7 +210,7 @@ Blockly.navigation.getFlyoutCursor_ = function() {
|
||||
* it on the workspace.
|
||||
*/
|
||||
Blockly.navigation.insertFromFlyout = function() {
|
||||
var workspace = Blockly.getMainWorkspace();
|
||||
var workspace = Blockly.navigation.getNavigationWorkspace();
|
||||
var flyout = workspace.getFlyout();
|
||||
if (!flyout || !flyout.isVisible()) {
|
||||
Blockly.navigation.warn_('Trying to insert from the flyout when the flyout does not ' +
|
||||
@@ -210,7 +218,8 @@ Blockly.navigation.insertFromFlyout = function() {
|
||||
return;
|
||||
}
|
||||
|
||||
var curBlock = Blockly.navigation.getFlyoutCursor_().getCurNode().getLocation();
|
||||
var curBlock = /** @type {!Blockly.BlockSvg} */ (
|
||||
Blockly.navigation.getFlyoutCursor_().getCurNode().getLocation());
|
||||
if (!curBlock.isEnabled()) {
|
||||
Blockly.navigation.warn_('Can\'t insert a disabled block.');
|
||||
return;
|
||||
@@ -243,7 +252,7 @@ Blockly.navigation.resetFlyout_ = function(shouldHide) {
|
||||
if (Blockly.navigation.getFlyoutCursor_()) {
|
||||
Blockly.navigation.getFlyoutCursor_().hide();
|
||||
if (shouldHide) {
|
||||
Blockly.getMainWorkspace().getFlyout().hide();
|
||||
Blockly.navigation.getNavigationWorkspace().getFlyout().hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -260,7 +269,8 @@ Blockly.navigation.resetFlyout_ = function(shouldHide) {
|
||||
*/
|
||||
Blockly.navigation.modifyWarn_ = function() {
|
||||
var markerNode = Blockly.navigation.getMarker().getCurNode();
|
||||
var cursorNode = Blockly.getMainWorkspace().getCursor().getCurNode();
|
||||
var cursorNode = Blockly.navigation.getNavigationWorkspace()
|
||||
.getCursor().getCurNode();
|
||||
|
||||
if (!markerNode) {
|
||||
Blockly.navigation.warn_('Cannot insert with no marked node.');
|
||||
@@ -300,7 +310,7 @@ Blockly.navigation.modifyWarn_ = function() {
|
||||
/**
|
||||
* Disconnect the block from its parent and move to the position of the
|
||||
* workspace node.
|
||||
* @param {Blockly.Block} block The block to be moved to the workspace.
|
||||
* @param {Blockly.BlockSvg} block The block to be moved to the workspace.
|
||||
* @param {!Blockly.ASTNode} wsNode The workspace node holding the position the
|
||||
* block will be moved to.
|
||||
* @return {boolean} True if the block can be moved to the workspace,
|
||||
@@ -331,7 +341,8 @@ Blockly.navigation.moveBlockToWorkspace_ = function(block, wsNode) {
|
||||
*/
|
||||
Blockly.navigation.modify_ = function() {
|
||||
var markerNode = Blockly.navigation.getMarker().getCurNode();
|
||||
var cursorNode = Blockly.getMainWorkspace().getCursor().getCurNode();
|
||||
var cursorNode = Blockly.navigation.getNavigationWorkspace()
|
||||
.getCursor().getCurNode();
|
||||
if (!Blockly.navigation.modifyWarn_()) {
|
||||
return false;
|
||||
}
|
||||
@@ -343,18 +354,19 @@ Blockly.navigation.modify_ = function() {
|
||||
var markerLoc = markerNode.getLocation();
|
||||
|
||||
if (markerNode.isConnection() && cursorNode.isConnection()) {
|
||||
cursorLoc = /** @type {!Blockly.Connection} */ (cursorLoc);
|
||||
markerLoc = /** @type {!Blockly.Connection} */ (markerLoc);
|
||||
cursorLoc = /** @type {!Blockly.RenderedConnection} */ (cursorLoc);
|
||||
markerLoc = /** @type {!Blockly.RenderedConnection} */ (markerLoc);
|
||||
return Blockly.navigation.connect_(cursorLoc, markerLoc);
|
||||
} else if (markerNode.isConnection() &&
|
||||
(cursorType == Blockly.ASTNode.types.BLOCK ||
|
||||
cursorType == Blockly.ASTNode.types.STACK)) {
|
||||
cursorLoc = /** @type {!Blockly.Block} */ (cursorLoc);
|
||||
markerLoc = /** @type {!Blockly.Connection} */ (markerLoc);
|
||||
cursorLoc = /** @type {!Blockly.BlockSvg} */ (cursorLoc);
|
||||
markerLoc = /** @type {!Blockly.RenderedConnection} */ (markerLoc);
|
||||
return Blockly.navigation.insertBlock(cursorLoc, markerLoc);
|
||||
} else if (markerType == Blockly.ASTNode.types.WORKSPACE) {
|
||||
var block = cursorNode ? cursorNode.getSourceBlock() : null;
|
||||
return Blockly.navigation.moveBlockToWorkspace_(block, markerNode);
|
||||
return Blockly.navigation.moveBlockToWorkspace_(
|
||||
/** @type {Blockly.BlockSvg} */ (block), markerNode);
|
||||
}
|
||||
Blockly.navigation.warn_('Unexpected state in Blockly.navigation.modify_.');
|
||||
return false;
|
||||
@@ -363,9 +375,10 @@ Blockly.navigation.modify_ = function() {
|
||||
/**
|
||||
* If one of the connections source blocks is a child of the other, disconnect
|
||||
* the child.
|
||||
* @param {!Blockly.Connection} movingConnection The connection that is being
|
||||
* moved.
|
||||
* @param {!Blockly.Connection} destConnection The connection to be moved to.
|
||||
* @param {!Blockly.RenderedConnection} movingConnection The connection that is
|
||||
* being moved.
|
||||
* @param {!Blockly.RenderedConnection} destConnection The connection to be
|
||||
* moved to.
|
||||
* @private
|
||||
*/
|
||||
Blockly.navigation.disconnectChild_ = function(movingConnection, destConnection) {
|
||||
@@ -384,9 +397,10 @@ Blockly.navigation.disconnectChild_ = function(movingConnection, destConnection)
|
||||
/**
|
||||
* If the two blocks are compatible move the moving connection to the target
|
||||
* connection and connect them.
|
||||
* @param {Blockly.Connection} movingConnection The connection that is being
|
||||
* moved.
|
||||
* @param {Blockly.Connection} destConnection The connection to be moved to.
|
||||
* @param {Blockly.RenderedConnection} movingConnection The connection that is
|
||||
* being moved.
|
||||
* @param {Blockly.RenderedConnection} destConnection The connection to be moved
|
||||
* to.
|
||||
* @return {boolean} True if the connections were connected, false otherwise.
|
||||
* @private
|
||||
*/
|
||||
@@ -414,8 +428,10 @@ Blockly.navigation.moveAndConnect_ = function(movingConnection, destConnection)
|
||||
/**
|
||||
* If the given connection is superior find the inferior connection on the
|
||||
* source block.
|
||||
* @param {Blockly.Connection} connection The connection trying to be connected.
|
||||
* @return {Blockly.Connection} The inferior connection or null if none exists.
|
||||
* @param {Blockly.RenderedConnection} connection The connection trying to be
|
||||
* connected.
|
||||
* @return {Blockly.RenderedConnection} The inferior connection or null if none
|
||||
* exists.
|
||||
* @private
|
||||
*/
|
||||
Blockly.navigation.getInferiorConnection_ = function(connection) {
|
||||
@@ -434,8 +450,10 @@ Blockly.navigation.getInferiorConnection_ = function(connection) {
|
||||
/**
|
||||
* If the given connection is inferior tries to find a superior connection to
|
||||
* connect to.
|
||||
* @param {Blockly.Connection} connection The connection trying to be connected.
|
||||
* @return {Blockly.Connection} The superior connection or null if none exists.
|
||||
* @param {Blockly.RenderedConnection} connection The connection trying to be
|
||||
* connected.
|
||||
* @return {Blockly.RenderedConnection} The superior connection or null if none
|
||||
* exists.
|
||||
* @private
|
||||
*/
|
||||
Blockly.navigation.getSuperiorConnection_ = function(connection) {
|
||||
@@ -453,9 +471,10 @@ Blockly.navigation.getSuperiorConnection_ = function(connection) {
|
||||
* If the given connections are not compatible try finding compatible connections
|
||||
* on the source blocks of the given connections.
|
||||
*
|
||||
* @param {Blockly.Connection} movingConnection The connection that is being
|
||||
* moved.
|
||||
* @param {Blockly.Connection} destConnection The connection to be moved to.
|
||||
* @param {Blockly.RenderedConnection} movingConnection The connection that is
|
||||
* being moved.
|
||||
* @param {Blockly.RenderedConnection} destConnection The connection to be moved
|
||||
* to.
|
||||
* @return {boolean} True if the two connections or their target connections
|
||||
* were connected, false otherwise.
|
||||
* @private
|
||||
@@ -495,8 +514,9 @@ Blockly.navigation.connect_ = function(movingConnection, destConnection) {
|
||||
/**
|
||||
* Tries to connect the given block to the destination connection, making an
|
||||
* intelligent guess about which connection to use to on the moving block.
|
||||
* @param {!Blockly.Block} block The block to move.
|
||||
* @param {!Blockly.Connection} destConnection The connection to connect to.
|
||||
* @param {!Blockly.BlockSvg} block The block to move.
|
||||
* @param {!Blockly.RenderedConnection} destConnection The connection to connect
|
||||
* to.
|
||||
* @return {boolean} Whether the connection was successful.
|
||||
*/
|
||||
Blockly.navigation.insertBlock = function(block, destConnection) {
|
||||
@@ -518,7 +538,8 @@ Blockly.navigation.insertBlock = function(block, destConnection) {
|
||||
break;
|
||||
case Blockly.OUTPUT_VALUE:
|
||||
for (var i = 0; i < block.inputList.length; i++) {
|
||||
var inputConnection = block.inputList[i].connection;
|
||||
var inputConnection = /** @type {Blockly.RenderedConnection} */ (
|
||||
block.inputList[i].connection);
|
||||
if (inputConnection && inputConnection.type === Blockly.INPUT_VALUE &&
|
||||
Blockly.navigation.connect_(inputConnection, destConnection)) {
|
||||
return true;
|
||||
@@ -543,13 +564,14 @@ Blockly.navigation.insertBlock = function(block, destConnection) {
|
||||
* @private
|
||||
*/
|
||||
Blockly.navigation.disconnectBlocks_ = function() {
|
||||
var workspace = Blockly.getMainWorkspace();
|
||||
var workspace = Blockly.navigation.getNavigationWorkspace();
|
||||
var curNode = workspace.getCursor().getCurNode();
|
||||
if (!curNode.isConnection()) {
|
||||
Blockly.navigation.log_('Cannot disconnect blocks when the cursor is not on a connection');
|
||||
return;
|
||||
}
|
||||
var curConnection = /** @type {!Blockly.Connection} */ (curNode.getLocation());
|
||||
var curConnection =
|
||||
/** @type {!Blockly.RenderedConnection} */ (curNode.getLocation());
|
||||
if (!curConnection.isConnected()) {
|
||||
Blockly.navigation.log_('Cannot disconnect unconnected connection');
|
||||
return;
|
||||
@@ -584,7 +606,7 @@ Blockly.navigation.disconnectBlocks_ = function() {
|
||||
*/
|
||||
Blockly.navigation.markAtCursor_ = function() {
|
||||
Blockly.navigation.getMarker().setCurNode(
|
||||
Blockly.getMainWorkspace().getCursor().getCurNode());
|
||||
Blockly.navigation.getNavigationWorkspace().getCursor().getCurNode());
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -608,10 +630,10 @@ Blockly.navigation.setState = function(newState) {
|
||||
|
||||
/**
|
||||
* Before a block is deleted move the cursor to the appropriate position.
|
||||
* @param {!Blockly.Block} deletedBlock The block that is being deleted.
|
||||
* @param {!Blockly.BlockSvg} deletedBlock The block that is being deleted.
|
||||
*/
|
||||
Blockly.navigation.moveCursorOnBlockDelete = function(deletedBlock) {
|
||||
var workspace = Blockly.getMainWorkspace();
|
||||
var workspace = Blockly.navigation.getNavigationWorkspace();
|
||||
if (!workspace) {
|
||||
return;
|
||||
}
|
||||
@@ -645,11 +667,11 @@ Blockly.navigation.moveCursorOnBlockDelete = function(deletedBlock) {
|
||||
/**
|
||||
* When a block that the cursor is on is mutated move the cursor to the block
|
||||
* level.
|
||||
* @param {!Blockly.Block} mutatedBlock The block that is being mutated.
|
||||
* @param {!Blockly.BlockSvg} mutatedBlock The block that is being mutated.
|
||||
* @package
|
||||
*/
|
||||
Blockly.navigation.moveCursorOnBlockMutation = function(mutatedBlock) {
|
||||
var cursor = Blockly.getMainWorkspace().getCursor();
|
||||
var cursor = Blockly.navigation.getNavigationWorkspace().getCursor();
|
||||
if (cursor) {
|
||||
var curNode = cursor.getCurNode();
|
||||
var block = curNode ? curNode.getSourceBlock() : null;
|
||||
@@ -664,8 +686,9 @@ Blockly.navigation.moveCursorOnBlockMutation = function(mutatedBlock) {
|
||||
* Enable accessibility mode.
|
||||
*/
|
||||
Blockly.navigation.enableKeyboardAccessibility = function() {
|
||||
if (!Blockly.getMainWorkspace().keyboardAccessibilityMode) {
|
||||
Blockly.getMainWorkspace().keyboardAccessibilityMode = true;
|
||||
var workspace = Blockly.navigation.getNavigationWorkspace();
|
||||
if (!workspace.keyboardAccessibilityMode) {
|
||||
workspace.keyboardAccessibilityMode = true;
|
||||
Blockly.navigation.focusWorkspace_();
|
||||
}
|
||||
};
|
||||
@@ -674,9 +697,9 @@ Blockly.navigation.enableKeyboardAccessibility = function() {
|
||||
* Disable accessibility mode.
|
||||
*/
|
||||
Blockly.navigation.disableKeyboardAccessibility = function() {
|
||||
if (Blockly.getMainWorkspace().keyboardAccessibilityMode) {
|
||||
var workspace = Blockly.getMainWorkspace();
|
||||
Blockly.getMainWorkspace().keyboardAccessibilityMode = false;
|
||||
var workspace = Blockly.navigation.getNavigationWorkspace();
|
||||
if (workspace.keyboardAccessibilityMode) {
|
||||
workspace.keyboardAccessibilityMode = false;
|
||||
workspace.getCursor().hide();
|
||||
Blockly.navigation.getMarker().hide();
|
||||
if (Blockly.navigation.getFlyoutCursor_()) {
|
||||
@@ -733,7 +756,7 @@ Blockly.navigation.error_ = function(msg) {
|
||||
|
||||
/**
|
||||
* Handler for all the keyboard navigation events.
|
||||
* @param {!Event} e The keyboard event.
|
||||
* @param {!KeyboardEvent} e The keyboard event.
|
||||
* @return {boolean} True if the key was handled false otherwise.
|
||||
*/
|
||||
Blockly.navigation.onKeyPress = function(e) {
|
||||
@@ -753,10 +776,11 @@ Blockly.navigation.onKeyPress = function(e) {
|
||||
* @return {boolean} True if the action has been handled, false otherwise.
|
||||
*/
|
||||
Blockly.navigation.onBlocklyAction = function(action) {
|
||||
var readOnly = Blockly.getMainWorkspace().options.readOnly;
|
||||
var workspace = Blockly.navigation.getNavigationWorkspace();
|
||||
var readOnly = workspace.options.readOnly;
|
||||
var actionHandled = false;
|
||||
|
||||
if (Blockly.getMainWorkspace().keyboardAccessibilityMode) {
|
||||
if (workspace.keyboardAccessibilityMode) {
|
||||
if (!readOnly) {
|
||||
actionHandled = Blockly.navigation.handleActions_(action);
|
||||
// If in readonly mode only handle valid actions.
|
||||
@@ -799,9 +823,9 @@ Blockly.navigation.handleActions_ = function(action) {
|
||||
* @private
|
||||
*/
|
||||
Blockly.navigation.flyoutOnAction_ = function(action) {
|
||||
var workspace = Blockly.getMainWorkspace();
|
||||
var workspace = Blockly.navigation.getNavigationWorkspace();
|
||||
var toolbox = workspace.getToolbox();
|
||||
var flyout = toolbox ? toolbox.flyout_ : workspace.getFlyout();
|
||||
var flyout = toolbox ? toolbox.getFlyout() : workspace.getFlyout();
|
||||
|
||||
if (flyout && flyout.onBlocklyAction(action)) {
|
||||
return true;
|
||||
@@ -829,7 +853,7 @@ Blockly.navigation.flyoutOnAction_ = function(action) {
|
||||
* @private
|
||||
*/
|
||||
Blockly.navigation.toolboxOnAction_ = function(action) {
|
||||
var workspace = Blockly.getMainWorkspace();
|
||||
var workspace = Blockly.navigation.getNavigationWorkspace();
|
||||
var toolbox = workspace.getToolbox();
|
||||
var handled = toolbox ? toolbox.onBlocklyAction(action) : false;
|
||||
|
||||
@@ -862,8 +886,9 @@ Blockly.navigation.toolboxOnAction_ = function(action) {
|
||||
* @private
|
||||
*/
|
||||
Blockly.navigation.moveWSCursor_ = function(xDirection, yDirection) {
|
||||
var cursor = Blockly.getMainWorkspace().getCursor();
|
||||
var curNode = Blockly.getMainWorkspace().getCursor().getCurNode();
|
||||
var workspace = Blockly.navigation.getNavigationWorkspace();
|
||||
var cursor = workspace.getCursor();
|
||||
var curNode = workspace.getCursor().getCurNode();
|
||||
|
||||
if (curNode.getType() !== Blockly.ASTNode.types.WORKSPACE) {
|
||||
return false;
|
||||
@@ -874,7 +899,7 @@ Blockly.navigation.moveWSCursor_ = function(xDirection, yDirection) {
|
||||
var newY = yDirection * Blockly.navigation.WS_MOVE_DISTANCE + wsCoord.y;
|
||||
|
||||
cursor.setCurNode(Blockly.ASTNode.createWorkspaceNode(
|
||||
Blockly.getMainWorkspace(), new Blockly.utils.Coordinate(newX, newY)));
|
||||
workspace, new Blockly.utils.Coordinate(newX, newY)));
|
||||
return true;
|
||||
};
|
||||
|
||||
@@ -885,7 +910,8 @@ Blockly.navigation.moveWSCursor_ = function(xDirection, yDirection) {
|
||||
* @private
|
||||
*/
|
||||
Blockly.navigation.workspaceOnAction_ = function(action) {
|
||||
if (Blockly.getMainWorkspace().getCursor().onBlocklyAction(action)) {
|
||||
var workspace = Blockly.navigation.getNavigationWorkspace();
|
||||
if (workspace.getCursor().onBlocklyAction(action)) {
|
||||
return true;
|
||||
}
|
||||
switch (action.name) {
|
||||
@@ -916,11 +942,11 @@ Blockly.navigation.workspaceOnAction_ = function(action) {
|
||||
* @private
|
||||
*/
|
||||
Blockly.navigation.handleEnterForWS_ = function() {
|
||||
var cursor = Blockly.getMainWorkspace().getCursor();
|
||||
var cursor = Blockly.navigation.getNavigationWorkspace().getCursor();
|
||||
var curNode = cursor.getCurNode();
|
||||
var nodeType = curNode.getType();
|
||||
if (nodeType == Blockly.ASTNode.types.FIELD) {
|
||||
curNode.getLocation().showEditor();
|
||||
(/** @type {!Blockly.Field} */(curNode.getLocation())).showEditor();
|
||||
} else if (curNode.isConnection() ||
|
||||
nodeType == Blockly.ASTNode.types.WORKSPACE) {
|
||||
Blockly.navigation.markAtCursor_();
|
||||
|
||||
@@ -38,10 +38,9 @@ Blockly.TabNavigateCursor.prototype.validNode_ = function(node) {
|
||||
var isValid = false;
|
||||
var type = node && node.getType();
|
||||
if (node) {
|
||||
var location = node.getLocation();
|
||||
var location = /** @type {Blockly.Field} */ (node.getLocation());
|
||||
if (type == Blockly.ASTNode.types.FIELD &&
|
||||
location && location.isTabNavigable() &&
|
||||
(/** @type {!Blockly.Field} */ (location)).isClickable()) {
|
||||
location && location.isTabNavigable() && location.isClickable()) {
|
||||
isValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,7 +378,8 @@ Blockly.Mutator.prototype.workspaceChanged_ = function(e) {
|
||||
block.initSvg();
|
||||
block.render();
|
||||
|
||||
if (Blockly.getMainWorkspace().keyboardAccessibilityMode) {
|
||||
if ((/** @type {!Blockly.WorkspaceSvg} */ (Blockly.getMainWorkspace()))
|
||||
.keyboardAccessibilityMode) {
|
||||
Blockly.navigation.moveCursorOnBlockMutation(block);
|
||||
}
|
||||
var newMutationDom = block.mutationToDom();
|
||||
|
||||
@@ -59,6 +59,12 @@ Blockly.RenderedConnection = function(source, type) {
|
||||
* @private
|
||||
*/
|
||||
this.trackedState_ = Blockly.RenderedConnection.TrackedState.WILL_TRACK;
|
||||
|
||||
/**
|
||||
* Connection this connection connects to. Null if not connected.
|
||||
* @type {Blockly.RenderedConnection}
|
||||
*/
|
||||
this.targetConnection = null;
|
||||
};
|
||||
Blockly.utils.object.inherits(Blockly.RenderedConnection, Blockly.Connection);
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ Blockly.blockRendering.MarkerSvg = function(workspace, constants, marker) {
|
||||
/**
|
||||
* The workspace, field, or block that the marker SVG element should be
|
||||
* attached to.
|
||||
* @type {Blockly.WorkspaceSvg|Blockly.Field|Blockly.BlockSvg}
|
||||
* @type {Blockly.IASTNodeLocationSvg}
|
||||
* @private
|
||||
*/
|
||||
this.parent_ = null;
|
||||
@@ -135,9 +135,8 @@ Blockly.blockRendering.MarkerSvg.prototype.createDom = function() {
|
||||
|
||||
/**
|
||||
* Attaches the SVG root of the marker to the SVG group of the parent.
|
||||
* @param {!Blockly.WorkspaceSvg|!Blockly.Field|!Blockly.BlockSvg} newParent
|
||||
* The workspace, field, or block that the marker SVG element should be
|
||||
* attached to.
|
||||
* @param {!Blockly.IASTNodeLocationSvg} newParent The workspace, field, or
|
||||
* block that the marker SVG element should be attached to.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.blockRendering.MarkerSvg.prototype.setParent_ = function(newParent) {
|
||||
@@ -191,13 +190,15 @@ Blockly.blockRendering.MarkerSvg.prototype.draw = function(oldNode, curNode) {
|
||||
* @protected
|
||||
*/
|
||||
Blockly.blockRendering.MarkerSvg.prototype.showAtLocation_ = function(curNode) {
|
||||
var curNodeAsConnection =
|
||||
/** @type {!Blockly.Connection} */ (curNode.getLocation());
|
||||
if (curNode.getType() == Blockly.ASTNode.types.BLOCK) {
|
||||
this.showWithBlock_(curNode);
|
||||
} else if (curNode.getType() == Blockly.ASTNode.types.OUTPUT) {
|
||||
this.showWithOutput_(curNode);
|
||||
} else if (curNode.getLocation().type == Blockly.INPUT_VALUE) {
|
||||
} else if (curNodeAsConnection.type == Blockly.INPUT_VALUE) {
|
||||
this.showWithInput_(curNode);
|
||||
} else if (curNode.getLocation().type == Blockly.NEXT_STATEMENT) {
|
||||
} else if (curNodeAsConnection.type == Blockly.NEXT_STATEMENT) {
|
||||
this.showWithNext_(curNode);
|
||||
} else if (curNode.getType() == Blockly.ASTNode.types.PREVIOUS) {
|
||||
this.showWithPrevious_(curNode);
|
||||
@@ -330,8 +331,10 @@ Blockly.blockRendering.MarkerSvg.prototype.showWithInput_ = function(curNode) {
|
||||
* @protected
|
||||
*/
|
||||
Blockly.blockRendering.MarkerSvg.prototype.showWithNext_ = function(curNode) {
|
||||
var connection = curNode.getLocation();
|
||||
var targetBlock = /** @type {Blockly.BlockSvg} */ (connection.getSourceBlock());
|
||||
var connection =
|
||||
/** @type {!Blockly.RenderedConnection} */ (curNode.getLocation());
|
||||
var targetBlock =
|
||||
/** @type {Blockly.BlockSvg} */ (connection.getSourceBlock());
|
||||
var x = 0;
|
||||
var y = connection.getOffsetInBlock().y;
|
||||
var width = targetBlock.getHeightWidth().width;
|
||||
@@ -548,7 +551,8 @@ Blockly.blockRendering.MarkerSvg.prototype.fireMarkerEvent_ = function(
|
||||
var eventType = this.isCursor() ? 'cursorMove' : 'markerMove';
|
||||
var event = new Blockly.Events.Ui(curBlock, eventType, oldNode, curNode);
|
||||
if (curNode.getType() == Blockly.ASTNode.types.WORKSPACE) {
|
||||
event.workspaceId = curNode.getLocation().id;
|
||||
event.workspaceId =
|
||||
(/** @type {!Blockly.Workspace} */ (curNode.getLocation())).id;
|
||||
}
|
||||
Blockly.Events.fire(event);
|
||||
};
|
||||
|
||||
@@ -38,7 +38,7 @@ Blockly.utils.object.inherits(Blockly.zelos.MarkerSvg,
|
||||
*/
|
||||
Blockly.zelos.MarkerSvg.prototype.showWithInputOutput_ = function(curNode) {
|
||||
var block = /** @type {!Blockly.BlockSvg} */ (curNode.getSourceBlock());
|
||||
var connection = curNode.getLocation();
|
||||
var connection = /** @type {!Blockly.Connection} */ (curNode.getLocation());
|
||||
var offsetInBlock = connection.getOffsetInBlock();
|
||||
|
||||
this.positionCircle_(offsetInBlock.x, offsetInBlock.y);
|
||||
|
||||
@@ -27,6 +27,8 @@ goog.require('Blockly.utils.object');
|
||||
goog.require('Blockly.utils.Rect');
|
||||
goog.require('Blockly.utils.toolbox');
|
||||
|
||||
goog.requireType('Blockly.IBlocklyActionable');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a Toolbox.
|
||||
@@ -34,6 +36,7 @@ goog.require('Blockly.utils.toolbox');
|
||||
* @param {!Blockly.WorkspaceSvg} workspace The workspace in which to create new
|
||||
* blocks.
|
||||
* @constructor
|
||||
* @implements {Blockly.IBlocklyActionable}
|
||||
*/
|
||||
Blockly.Toolbox = function(workspace) {
|
||||
/**
|
||||
|
||||
@@ -18,12 +18,15 @@ goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.math');
|
||||
goog.require('Blockly.VariableMap');
|
||||
|
||||
goog.requireType('Blockly.IASTNodeLocation');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a workspace. This is a data structure that contains blocks.
|
||||
* There is no UI, and can be created headlessly.
|
||||
* @param {!Blockly.Options=} opt_options Dictionary of options.
|
||||
* @constructor
|
||||
* @implements {Blockly.IASTNodeLocation}
|
||||
*/
|
||||
Blockly.Workspace = function(opt_options) {
|
||||
/** @type {string} */
|
||||
|
||||
@@ -39,6 +39,7 @@ goog.require('Blockly.WorkspaceDragSurfaceSvg');
|
||||
goog.require('Blockly.Xml');
|
||||
|
||||
goog.requireType('Blockly.blockRendering.Renderer');
|
||||
goog.requireType('Blockly.IASTNodeLocationSvg');
|
||||
goog.requireType('Blockly.IBoundedElement');
|
||||
|
||||
|
||||
@@ -51,6 +52,7 @@ goog.requireType('Blockly.IBoundedElement');
|
||||
* @param {Blockly.WorkspaceDragSurfaceSvg=} opt_wsDragSurface Drag surface for
|
||||
* the workspace.
|
||||
* @extends {Blockly.Workspace}
|
||||
* @implements {Blockly.IASTNodeLocationSvg}
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.WorkspaceSvg = function(options,
|
||||
@@ -1298,8 +1300,9 @@ Blockly.WorkspaceSvg.prototype.pasteBlock_ = function(xmlBlock) {
|
||||
if (this.keyboardAccessibilityMode && markedNode &&
|
||||
markedNode.isConnection()) {
|
||||
var markedLocation =
|
||||
/** @type {!Blockly.Connection} */ (markedNode.getLocation());
|
||||
Blockly.navigation.insertBlock(block, markedLocation);
|
||||
/** @type {!Blockly.RenderedConnection} */ (markedNode.getLocation());
|
||||
Blockly.navigation.insertBlock(/** @type {!Blockly.BlockSvg} */ (block),
|
||||
markedLocation);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user