Skip to content
Merged
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
18 changes: 15 additions & 3 deletions src/actions/mover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,15 +218,27 @@ export class Mover {
/**
* Get the source block for the cursor location, or undefined if no
* source block can be found.
* If the cursor is on a shadow block, walks up the tree until it finds
* a non-shadow block to drag.
*
* @param workspace The workspace to inspect for a cursor.
* @returns The source block, or undefined if no appropriate block
* could be found.
*/
protected getCurrentBlock(workspace: WorkspaceSvg): BlockSvg | undefined {
const cursor = workspace?.getCursor();
const curNode = cursor?.getCurNode();
return (curNode?.getSourceBlock() as BlockSvg) ?? undefined;
const curNode = workspace?.getCursor()?.getCurNode();
let block = curNode?.getSourceBlock();
if (!block) return undefined;
while (block && block.isShadow()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Because we check !block before and in the loop, this test can just be block.isShadow(). Makes it a bit clearer that block is always defined after the loop.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can return null from getParent. It'll be an error (see below), but still possible in the type system.

block = block.getParent();
if (!block) {
throw new Error(
'Tried to drag a shadow block with no parent. ' +
'Shadow blocks should always have parents.',
);
}
}
return block as BlockSvg;
}

/**
Expand Down