From ae1a41fd20cb4044ed9fdfc1192502502d2d0519 Mon Sep 17 00:00:00 2001 From: alschmiedt Date: Fri, 25 Oct 2019 10:55:24 -0700 Subject: [PATCH] Fire UI events when cursor moves or a marker is added (#3338) * Fire UI events when cursor moves or a marker is added --- core/keyboard_nav/ast_node.js | 17 +++++++++++++++++ core/keyboard_nav/cursor.js | 3 ++- core/keyboard_nav/cursor_svg.js | 21 ++++++++++++++++++++- core/keyboard_nav/navigation.js | 28 +++------------------------- 4 files changed, 42 insertions(+), 27 deletions(-) diff --git a/core/keyboard_nav/ast_node.js b/core/keyboard_nav/ast_node.js index b1ee7c70f..ed74df6a7 100644 --- a/core/keyboard_nav/ast_node.js +++ b/core/keyboard_nav/ast_node.js @@ -470,6 +470,23 @@ Blockly.ASTNode.prototype.findFirstFieldOrInput_ = function(block) { return null; }; +/** + * Finds the source block of the location of this node. + * @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) { + return /** @type {Blockly.Block} */ (this.getLocation()); + } else if (this.getType() === Blockly.ASTNode.types.STACK) { + return /** @type {Blockly.Block} */ (this.getLocation()); + } else if (this.getType() === Blockly.ASTNode.types.WORKSPACE) { + return null; + } else { + return this.getLocation().getSourceBlock(); + } +}; + /** * 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, diff --git a/core/keyboard_nav/cursor.js b/core/keyboard_nav/cursor.js index be9e2d48c..f7550273e 100644 --- a/core/keyboard_nav/cursor.js +++ b/core/keyboard_nav/cursor.js @@ -78,9 +78,10 @@ Blockly.Cursor.prototype.getCurNode = function() { * @param {Blockly.ASTNode} newNode The new location of the cursor. */ Blockly.Cursor.prototype.setCurNode = function(newNode) { + var oldNode = this.curNode_; this.curNode_ = newNode; if (this.drawer_) { - this.drawer_.draw(this.getCurNode()); + this.drawer_.draw(oldNode, this.curNode_); } }; diff --git a/core/keyboard_nav/cursor_svg.js b/core/keyboard_nav/cursor_svg.js index 13a5e4a8d..329059ba7 100644 --- a/core/keyboard_nav/cursor_svg.js +++ b/core/keyboard_nav/cursor_svg.js @@ -483,10 +483,11 @@ Blockly.CursorSvg.prototype.hide = function() { /** * Update the cursor. + * @param {Blockly.ASTNode} oldNode The previous node the cursor was on or null. * @param {Blockly.ASTNode} curNode The node that we want to draw the cursor for. * @package */ -Blockly.CursorSvg.prototype.draw = function(curNode) { +Blockly.CursorSvg.prototype.draw = function(oldNode, curNode) { if (!curNode) { this.hide(); return; @@ -513,6 +514,8 @@ Blockly.CursorSvg.prototype.draw = function(curNode) { this.showWithStack_(curNode); } + this.fireCursorEvent_(oldNode, curNode); + // Ensures the cursor will be visible immediately after the move. var animate = this.currentCursorSvg.childNodes[0]; if (animate !== undefined) { @@ -520,6 +523,22 @@ Blockly.CursorSvg.prototype.draw = function(curNode) { } }; +/** + * Fire event for the cursor or marker. + * @param {Blockly.ASTNode} oldNode The old node the cursor used to be on. + * @param {!Blockly.ASTNode} curNode The new node the cursor is currently on. + * @private + */ +Blockly.CursorSvg.prototype.fireCursorEvent_ = function(oldNode, curNode) { + var curBlock = curNode.getSourceBlock(); + var eventType = this.isMarker_ ? 'markedNode' : 'cursorMove'; + var event = new Blockly.Events.Ui(curBlock, eventType, oldNode, curNode); + if (curNode.getType() == Blockly.ASTNode.types.WORKSPACE) { + event.workspaceId = curNode.getLocation().id; + } + Blockly.Events.fire(event); +}; + /** * Create the cursor SVG. * @return {Element} The SVG node created. diff --git a/core/keyboard_nav/navigation.js b/core/keyboard_nav/navigation.js index 6d397abf3..90319cb9b 100644 --- a/core/keyboard_nav/navigation.js +++ b/core/keyboard_nav/navigation.js @@ -336,7 +336,7 @@ Blockly.navigation.modify_ = function() { markerLoc = /** @type {!Blockly.Connection} */ (markerLoc); return Blockly.navigation.insertBlock(cursorLoc, markerLoc); } else if (markerType == Blockly.ASTNode.types.WORKSPACE) { - var block = Blockly.navigation.getSourceBlock_(cursorNode); + var block = cursorNode ? cursorNode.getSourceBlock() : null; return Blockly.navigation.moveBlockToWorkspace_(block, markerNode); } Blockly.navigation.warn_('Unexpected state in Blockly.navigation.modify_.'); @@ -589,28 +589,6 @@ Blockly.navigation.setState = function(newState) { Blockly.navigation.currentState_ = newState; }; -/** - * Finds the source block of the location on a given node. - * @param {Blockly.ASTNode} node The node to find the source block on. - * @return {Blockly.Block} The source block of the location on the given node, - * or null if the node is of type workspace. - * @private - */ -Blockly.navigation.getSourceBlock_ = function(node) { - if (!node) { - return null; - } - if (node.getType() === Blockly.ASTNode.types.BLOCK) { - return /** @type {Blockly.Block} */ (node.getLocation()); - } else if (node.getType() === Blockly.ASTNode.types.STACK) { - return /** @type {Blockly.Block} */ (node.getLocation()); - } else if (node.getType() === Blockly.ASTNode.types.WORKSPACE) { - return null; - } else { - return node.getLocation().getSourceBlock(); - } -}; - /** * Gets the top node on a block. * This is either the previous connection, output connection or the block. @@ -642,7 +620,7 @@ Blockly.navigation.moveCursorOnBlockDelete = function(deletedBlock) { var cursor = workspace.getCursor(); if (cursor) { var curNode = cursor.getCurNode(); - var block = Blockly.navigation.getSourceBlock_(curNode); + var block = curNode ? curNode.getSourceBlock() : null; if (block === deletedBlock) { // If the block has a parent move the cursor to their connection point. @@ -676,7 +654,7 @@ Blockly.navigation.moveCursorOnBlockMutation = function(mutatedBlock) { var cursor = Blockly.getMainWorkspace().getCursor(); if (cursor) { var curNode = cursor.getCurNode(); - var block = Blockly.navigation.getSourceBlock_(curNode); + var block = curNode ? curNode.getSourceBlock() : null; if (block === mutatedBlock) { cursor.setCurNode(Blockly.ASTNode.createBlockNode(block));