Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions src/actions/action_menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const createSerializedKey = ShortcutRegistry.registry.createSerializedKey.bind(
);

/**
* Keyboard shortcut to show the action menu on Cmr/Ctrl/Alt+Enter key.
* Keyboard shortcut to show the action menu on Cmd/Ctrl/Alt+Enter key.
*/
export class ActionMenu {
/**
Expand Down Expand Up @@ -86,14 +86,13 @@ export class ActionMenu {
const node = cursor.getCurNode();
if (!node) return false;
// TODO(google/blockly#8847): Add typeguard for IContextMenu in core when this moves over
const location = node.getLocation();
if (
'showContextMenu' in location &&
typeof location.showContextMenu === 'function'
'showContextMenu' in node &&
typeof node.showContextMenu === 'function'
) {
location.showContextMenu(menuOpenEvent);
node.showContextMenu(menuOpenEvent);
} else {
console.info(`No action menu for ASTNode of type ${node.getType()}`);
console.info(`No action menu for node ${node}`);
return false;
}

Expand Down
8 changes: 4 additions & 4 deletions src/actions/arrow_navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
* SPDX-License-Identifier: Apache-2.0
*/

import {ASTNode, ShortcutRegistry, utils as BlocklyUtils} from 'blockly/core';
import {ShortcutRegistry, utils as BlocklyUtils, Field} from 'blockly/core';

import type {Field, Toolbox, WorkspaceSvg} from 'blockly/core';
import type {Toolbox, WorkspaceSvg} from 'blockly/core';

import * as Blockly from 'blockly/core';
import * as Constants from '../constants';
Expand Down Expand Up @@ -38,8 +38,8 @@ export class ArrowNavigation {
return false;
}
const curNode = cursor.getCurNode();
if (curNode?.getType() === ASTNode.types.FIELD) {
return (curNode.getLocation() as Field).onShortcut(shortcut);
if (curNode instanceof Field) {
return curNode.onShortcut(shortcut);
}
return false;
}
Expand Down
44 changes: 18 additions & 26 deletions src/actions/clipboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@
clipboard,
ICopyData,
LineCursor,
FocusableTreeTraverser,
getFocusManager,
} from 'blockly';
import * as Constants from '../constants';
import type {BlockSvg, WorkspaceSvg} from 'blockly';
import type {BlockSvg, WorkspaceSvg, INavigable} from 'blockly';
import {Navigation} from '../navigation';
import {getShortActionShortcut} from '../shortcut_formatting';
import * as Blockly from 'blockly';
Expand Down Expand Up @@ -134,17 +135,15 @@
*/
private cutPrecondition(workspace: WorkspaceSvg) {
if (this.navigation.canCurrentlyEdit(workspace)) {
const curNode = workspace.getCursor()?.getCurNode();
if (curNode && curNode.getSourceBlock()) {
const sourceBlock = curNode.getSourceBlock();
return !!(
!Gesture.inProgress() &&
sourceBlock &&
sourceBlock.isDeletable() &&
sourceBlock.isMovable() &&
!sourceBlock.workspace.isFlyout
);
}
const sourceBlock = workspace.getCursor()?.getSourceBlock();

return !!(
!Gesture.inProgress() &&
sourceBlock &&
sourceBlock.isDeletable() &&
sourceBlock.isMovable() &&
!sourceBlock.workspace.isFlyout
);
}
return false;
}
Expand All @@ -161,9 +160,7 @@
private cutCallback(workspace: WorkspaceSvg) {
const cursor = workspace.getCursor();
if (!cursor) throw new TypeError('no cursor');
const sourceBlock = cursor
.getCurNode()
?.getSourceBlock() as BlockSvg | null;
const sourceBlock = cursor.getSourceBlock();
if (!sourceBlock) throw new TypeError('no source block');
this.copyData = sourceBlock.toCopyData();
this.copyWorkspace = sourceBlock.workspace;
Expand Down Expand Up @@ -235,8 +232,7 @@
if (!this.navigation.canCurrentlyEdit(workspace)) return false;
switch (this.navigation.getState(workspace)) {
case Constants.STATE.WORKSPACE: {
const curNode = workspace?.getCursor()?.getCurNode();
const source = curNode?.getSourceBlock();
const source = workspace?.getCursor()?.getSourceBlock();
return !!(
source?.isDeletable() &&
source?.isMovable() &&
Expand All @@ -245,10 +241,7 @@
}
case Constants.STATE.FLYOUT: {
const flyoutWorkspace = workspace.getFlyout()?.getWorkspace();
const sourceBlock = flyoutWorkspace
?.getCursor()
?.getCurNode()
?.getSourceBlock();
const sourceBlock = flyoutWorkspace?.getCursor()?.getSourceBlock();
return !!(sourceBlock && !Gesture.inProgress());
}
default:
Expand All @@ -271,10 +264,7 @@
if (navigationState === Constants.STATE.FLYOUT) {
activeWorkspace = workspace.getFlyout()?.getWorkspace();
}
const sourceBlock = activeWorkspace
?.getCursor()
?.getCurNode()
?.getSourceBlock() as BlockSvg;
const sourceBlock = activeWorkspace?.getCursor()?.getSourceBlock();
if (!sourceBlock) return false;

this.copyData = sourceBlock.toCopyData();
Expand Down Expand Up @@ -376,7 +366,9 @@
? workspace
: this.copyWorkspace;

const targetNode = this.navigation.getFocusedASTNode(pasteWorkspace);
const targetNode = FocusableTreeTraverser.findFocusedNode(
pasteWorkspace,
) as unknown as INavigable<any>;

Check warning on line 371 in src/actions/clipboard.ts

View workflow job for this annotation

GitHub Actions / Eslint check

Unexpected any. Specify a different type
// If we're pasting in the flyout it still targets the workspace. Focus
// first as to ensure correct selection handling.
getFocusManager().focusTree(workspace);
Expand Down
6 changes: 2 additions & 4 deletions src/actions/delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
LineCursor,
} from 'blockly';
import * as Constants from '../constants';
import type {BlockSvg, WorkspaceSvg} from 'blockly';

Check warning on line 15 in src/actions/delete.ts

View workflow job for this annotation

GitHub Actions / Eslint check

'BlockSvg' is defined but never used
import {Navigation} from '../navigation';

const KeyCodes = BlocklyUtils.KeyCodes;
Expand Down Expand Up @@ -155,7 +155,7 @@
* @returns True iff `deleteCallback` function should be called.
*/
private deletePrecondition(workspace: WorkspaceSvg) {
const sourceBlock = workspace.getCursor()?.getCurNode()?.getSourceBlock();
const sourceBlock = workspace.getCursor()?.getSourceBlock();
return (
!workspace.isDragging() &&
this.navigation.canCurrentlyEdit(workspace) &&
Expand All @@ -178,9 +178,7 @@
const cursor = workspace.getCursor();
if (!cursor) return false;

const sourceBlock = cursor
.getCurNode()
?.getSourceBlock() as BlockSvg | null;
const sourceBlock = cursor.getSourceBlock();
if (!sourceBlock) return false;
// Delete or backspace.
// There is an event if this is triggered from a keyboard shortcut,
Expand Down
39 changes: 19 additions & 20 deletions src/actions/disconnect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@
*/

import {
ASTNode,
BlockSvg,
RenderedConnection,
ShortcutRegistry,
utils as BlocklyUtils,
} from 'blockly';
import * as Constants from '../constants';
import type {WorkspaceSvg} from 'blockly';
import type {WorkspaceSvg, INavigable} from 'blockly';
import {Navigation} from '../navigation';

const KeyCodes = BlocklyUtils.KeyCodes;
Expand Down Expand Up @@ -80,45 +79,46 @@
if (!cursor) {
return;
}
let curNode: ASTNode | null = cursor.getCurNode();
let curNode: INavigable<any> | null = cursor.getCurNode();

Check warning on line 82 in src/actions/disconnect.ts

View workflow job for this annotation

GitHub Actions / Eslint check

Unexpected any. Specify a different type
let wasVisitingConnection = true;
while (curNode && !curNode.isConnection()) {
const location = curNode.getLocation();
if (location instanceof BlockSvg) {
const previous = location.previousConnection;
const output = location.outputConnection;
while (
curNode &&
!(curNode instanceof RenderedConnection && curNode.isConnected())
) {
if (curNode instanceof BlockSvg) {
const previous = curNode.previousConnection;
const output = curNode.outputConnection;
if (previous?.isConnected()) {
curNode = ASTNode.createConnectionNode(previous);
curNode = previous;
break;
} else if (output?.isConnected()) {
curNode = ASTNode.createConnectionNode(output);
curNode = output;
break;
}
}

curNode = curNode.out();
curNode = workspace.getNavigator().getParent(curNode);
wasVisitingConnection = false;
}
if (!curNode) {
console.log('Unable to find a connection to disconnect');
return;
}
const curConnection = curNode.getLocation() as RenderedConnection;
if (!curConnection.isConnected()) {
if (!(curNode instanceof RenderedConnection && curNode.isConnected())) {
return;
}
const targetConnection = curConnection.targetConnection;
const targetConnection = curNode.targetConnection;
if (!targetConnection) {
throw new Error('Must have target if connected');
}

const superiorConnection = curConnection.isSuperior()
? curConnection
const superiorConnection = curNode.isSuperior()
? curNode
: targetConnection;

const inferiorConnection = curConnection.isSuperior()
const inferiorConnection = curNode.isSuperior()
? targetConnection
: curConnection;
: curNode;

if (inferiorConnection.getSourceBlock().isShadow()) {
return;
Expand All @@ -135,8 +135,7 @@
rootBlock.bringToFront();

if (wasVisitingConnection) {
const connectionNode = ASTNode.createConnectionNode(superiorConnection);
workspace.getCursor()?.setCurNode(connectionNode);
workspace.getCursor()?.setCurNode(superiorConnection);
}
}
}
62 changes: 25 additions & 37 deletions src/actions/enter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,20 @@
*/

import {
ASTNode,
Events,
ShortcutRegistry,
utils as BlocklyUtils,
getFocusManager,
} from 'blockly/core';

import type {
Block,
BlockSvg,
Field,
FlyoutButton,
RenderedConnection,
WorkspaceSvg,
Field,
FocusableTreeTraverser,
} from 'blockly/core';

import type {Block, INavigable} from 'blockly/core';

import * as Constants from '../constants';
import type {Navigation} from '../navigation';
import {Mover} from './mover';
Expand Down Expand Up @@ -60,7 +59,7 @@

let flyoutCursor;
let curNode;
let nodeType;

Check warning on line 62 in src/actions/enter.ts

View workflow job for this annotation

GitHub Actions / Eslint check

'nodeType' is defined but never used

switch (this.navigation.getState(workspace)) {
case Constants.STATE.WORKSPACE:
Expand All @@ -72,15 +71,10 @@
return false;
}
curNode = flyoutCursor.getCurNode();
nodeType = curNode?.getType();

switch (nodeType) {
case ASTNode.types.STACK:
this.insertFromFlyout(workspace);
break;
case ASTNode.types.BUTTON:
this.triggerButtonCallback(workspace);
break;
if (curNode instanceof BlockSvg) {
this.insertFromFlyout(workspace);
} else if (curNode instanceof FlyoutButton) {
this.triggerButtonCallback(workspace);
}

return true;
Expand All @@ -102,18 +96,17 @@
if (!cursor) return;
const curNode = cursor.getCurNode();
if (!curNode) return;
const nodeType = curNode.getType();
if (nodeType === ASTNode.types.FIELD) {
(curNode.getLocation() as Field).showEditor();
} else if (nodeType === ASTNode.types.BLOCK) {
const block = curNode.getLocation() as Block;
if (!this.tryShowFullBlockFieldEditor(block)) {
if (curNode instanceof Field) {
curNode.showEditor();
} else if (curNode instanceof BlockSvg) {
if (!this.tryShowFullBlockFieldEditor(curNode)) {
showHelpHint(workspace);
}
} else if (curNode.isConnection() || nodeType === ASTNode.types.WORKSPACE) {
} else if (
curNode instanceof RenderedConnection ||
curNode instanceof WorkspaceSvg
) {
this.navigation.openToolboxOrFlyout(workspace);
} else if (nodeType === ASTNode.types.STACK) {
console.warn('Cannot mark a stack.');
}
}

Expand All @@ -135,7 +128,9 @@
Events.setGroup(true);
}

const stationaryNode = this.navigation.getFocusedASTNode(workspace);
const stationaryNode = FocusableTreeTraverser.findFocusedNode(
workspace,
) as unknown as INavigable<any>;

Check warning on line 133 in src/actions/enter.ts

View workflow job for this annotation

GitHub Actions / Eslint check

Unexpected any. Specify a different type
const newBlock = this.createNewBlock(workspace);
if (!newBlock) return;
const insertStartPoint = stationaryNode
Expand All @@ -148,8 +143,7 @@
workspace.setResizesEnabled(true);

getFocusManager().focusTree(workspace);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
workspace.getCursor()?.setCurNode(ASTNode.createBlockNode(newBlock)!);
workspace.getCursor()?.setCurNode(newBlock);
this.mover.startMove(workspace, newBlock, insertStartPoint);

const isStartBlock =
Expand Down Expand Up @@ -253,11 +247,8 @@
* containing a flyout with a button.
*/
private triggerButtonCallback(workspace: WorkspaceSvg) {
const button = this.navigation
.getFlyoutCursor(workspace)
?.getCurNode()
?.getLocation() as FlyoutButton | undefined;
if (!button) return;
const button = this.navigation.getFlyoutCursor(workspace)?.getCurNode();
if (!(button instanceof FlyoutButton)) return;

const flyoutButtonCallbacks: Map<string, (p1: FlyoutButton) => void> =
// @ts-expect-error private field access
Expand Down Expand Up @@ -310,11 +301,8 @@
return null;
}

const curBlock = this.navigation
.getFlyoutCursor(workspace)
?.getCurNode()
?.getLocation() as BlockSvg | undefined;
if (!curBlock?.isEnabled()) {
const curBlock = this.navigation.getFlyoutCursor(workspace)?.getCurNode();
if (!(curBlock instanceof BlockSvg) || !curBlock.isEnabled()) {
console.warn("Can't insert a disabled block.");
return null;
}
Expand Down
7 changes: 3 additions & 4 deletions src/actions/move.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,10 +196,9 @@ export class MoveActions {
* could be found.
*/
getCurrentBlock(workspace: WorkspaceSvg): BlockSvg | undefined {
const curNode = workspace?.getCursor()?.getCurNode();
let block = curNode?.getSourceBlock();
let block = workspace?.getCursor()?.getSourceBlock();
if (!block) return undefined;
while (block?.isShadow()) {
while (block.isShadow()) {
block = block.getParent();
if (!block) {
throw new Error(
Expand All @@ -208,6 +207,6 @@ export class MoveActions {
);
}
}
return block as BlockSvg;
return block;
}
}
Loading
Loading