UNPKG

blockly

Version:

Blockly is a library for building visual programming editors.

289 lines 11.8 kB
/** * @license * Copyright 2024 Google LLC * SPDX-License-Identifier: Apache-2.0 */ import type { BlockSvg } from '../block_svg.js'; import type { IDragStrategy } from '../interfaces/i_draggable.js'; import { DragDisposition } from '../interfaces/i_draggable.js'; import type { RenderedConnection } from '../rendered_connection.js'; import { Coordinate } from '../utils.js'; /** Represents a valid pair of connections between the dragging block and a block on the workspace. */ interface ConnectionPair { /** A connection on the dragging stack that is compatible with neighbour. */ local: RenderedConnection; /** A nearby connection that is compatible with local. */ neighbour: RenderedConnection; } /** Represents a nearby valid connection. */ interface ConnectionCandidate extends ConnectionPair { /** The distance between the local connection and the neighbour connection. */ distance: number; } export declare class BlockDragStrategy implements IDragStrategy { private block; private workspace; /** The parent block at the start of the drag. */ private startParentConn; /** * The child block at the start of the drag. Only gets set if * `healStack` is true. */ private startChildConn; private startLoc; private connectionCandidate; private connectionPreviewer; private dragging; /** List of all connections available on the workspace. */ private allConnectionPairs; /** The current movement mode. */ private moveMode; /** Used to persist an event group when snapping is done async. */ private originalEventGroup; /** * Map from block IDs to reason(s) why it was disabled, used to restore * disabled state post-drag. */ private lastBlockDisabledReasons; protected readonly BLOCK_CONNECTION_OFFSET = 10; /** * How far in from the edges of the workspace to position newly placed blocks. */ protected readonly WORKSPACE_MARGIN = 10; constructor(block: BlockSvg); /** Returns true if the block is currently movable. False otherwise. */ isMovable(): boolean; /** * Positions a cloned block on its new workspace. * * @param oldBlock The flyout block that was cloned. * @param newBlock The new block to position. */ private positionNewBlock; /** * Returns the block to use for the current drag operation. This may create * and return a newly instantiated block when e.g. dragging from a flyout. */ protected getTargetBlock(): BlockSvg; /** * Announces a move on the ARIA live region for assistive technologies. * * @param isMoveStart Whether this announcement is for the start of a move. If false, * skip announcing the block label since it should have already been announced at the * start of the move. */ private announceMove; /** * Checks if there are multiple compatible connections for the specified side of the pair. * * @param forLocal Whether we are considering the local or neighbour side of the pair * @returns True if there are multiple compatible connections, false otherwise */ private hasMultipleCompatibleConnections; /** * Handles any setup for starting the drag, including disconnecting the block * from any parent blocks. */ startDrag(e?: PointerEvent | KeyboardEvent): import("../blockly.js").IDraggable; /** * Caches a list of all valid connection pairs between the dragging block * and any other blocks on the workspace. This is used to determine the * closest valid connection during keyboard-driven moves and to determine * the need to disambiguate between multiple compatible connections when * announcing moves to assistive technologies. */ cacheAllConnectionPairs(): void; /** * Returns an array of visible bubbles attached to the given block or its * descendants. * * @param block The block to identify open bubbles on. * @returns An array of all currently visible bubbles on the given block or * its descendants. */ private getVisibleBubbles; /** * Get whether the drag should act on a single block or a block stack. * * @param e The instigating pointer or keyboard event, if any. * @returns True if just the initial block should be dragged out, false * if all following blocks should also be dragged. */ protected shouldHealStack(e: PointerEvent | KeyboardEvent | undefined): boolean; /** * Whether or not we should disconnect the block when a drag is started. * * @param healStack Whether or not to heal the stack after disconnecting. * @returns True to disconnect the block, false otherwise. */ private shouldDisconnect; /** * Disconnects the block from any parents. If `healStack` is true and this is * a stack block, we also disconnect from any next blocks and attempt to * attach them to any parent. * * @param healStack Whether or not to heal the stack after disconnecting. */ private disconnectBlock; /** * Stores the dragging block's current parent or child connection before * unplugging. This allows us to revert the drag cleanly. In keyboard move mode, * the initial connection pair is also used as the first connection candidate. */ private storeInitialConnections; /** Fire a UI event at the start of a block drag. */ private fireDragStartEvent; /** Fire a UI event at the end of a block drag. */ private fireDragEndEvent; /** Fire a move event at the end of a block drag. */ private fireMoveEvent; /** Moves the block and updates any connection previews. */ drag(newLoc: Coordinate, e?: PointerEvent | KeyboardEvent): void; /** * Determines the offset to apply to the dragged block's position * based on the current connection candidate. * * @returns coordinates representing the offset */ private determineConnectionOffset; /** * Renders the connection preview indicator. * * @param draggingBlock The block being dragged. * @param delta How far the pointer has moved from the position * at the start of the drag, in workspace units. * @param initialCandidate If provided, a connection candidate that the * connection preview indicator will be attached to. * @returns The neighbouring connection to which the connection preview will * be attached. */ private updateConnectionPreview; /** * Returns true if the given orphan block can connect at the end of the * top block's stack or row, false otherwise. */ private orphanCanConnectAtEnd; /** * Returns true if the current candidate is better than the new candidate. * * We slightly prefer the current candidate even if it is farther away. */ private currCandidateIsBetter; /** * Returns the closest valid candidate connection, if one can be found. * * Valid neighbour connections are within the configured start radius, with a * compatible type (input, output, etc) and connection check. */ private getConnectionCandidate; /** * Returns the closest connection candidate for the given block. * * @param block The block to find a connection for. * @param delta The distance the block has traveled since dragging began. * @returns The closest available connection candidate, if any. */ private getClosestCandidate; /** * Get the radius to use when searching for a nearby valid connection. */ protected getSearchRadius(): number; /** * Returns all of the connections we might connect to blocks on the workspace. * * Includes any connections on the dragging block, and any last next * connection on the stack (if one exists). */ private getLocalConnections; /** * Cleans up any state at the end of the drag. Applies any pending * connections. */ endDrag(_e: PointerEvent | KeyboardEvent | undefined, disposition: DragDisposition): void; /** Disposes of any state at the end of the drag. */ private disposeStep; /** Connects the given candidate connections. */ private applyConnections; /** * Moves the block back to where it was at the beginning of the drag, * including reconnecting connections. */ revertDrag(): void; /** * Get the nearest valid candidate connection in traversal order. * * @param delta The distance the block has moved since this drag began. * @returns A candidate connection and radius, or null if none was found. */ findTraversalCandidate(delta: Coordinate): ConnectionCandidate | null; /** * Returns whether or not the given block is at a terminal position (start or * end) of the blocks on the workspace. This helps distinguish between a block * that is at the end of the line because all valid connections have been * visited and the proposed constrained move destination is now to drop it on * the workspace as a top-level block (in which case it will be in a terminal * position), and a block that just entered move mode as a top-level block, * and should therefore still be able to move to another connection point * even if looping is disabled. * * @param block The block to check. * @param direction The current dragging direction. * @returns True if the block is at the start or end of its possible positions * on the workspace. */ private isInTerminalPosition; /** * Converts a connection pair to a connection candidate with a default * distance of 0. */ private pairToCandidate; /** * Returns the cardinal direction that the block being dragged would have to * move in to reach the given location. * The given coordinate should differ from the current location on only one * axis. * * @param newLocation The intended destination for the block. * @returns The direction the block would need to travel to reach the new * location. */ private getDirectionToNewLocation; /** * Returns all navigable connections on the given block and its children. * Omits connections on shadow blocks, collapsed blocks, or those that are * associated with a hidden input. * * @param block The block to use as a starting point for retrieving * connections. * @returns All connections on the block and its children. */ private getAllConnections; /** * Returns a connection candidate to move the dragged block to at the start of * a drag. If the passively focused node is a connection and the dragged block * can connect to it, the connection will be returned. Otherwise, the first * compatible connection on the passively focused node's block, if any, will * be returned. Returns null if the workspace does not have passive focus. */ private getInitialCandidate; /** * Updates the current move mode based on the most recent drag-related event. */ private updateMoveMode; /** * Enables the given block and its children. * Stores the reasons each block was disabled so they can be restored. * * @param block The block to enable. */ private enableAllDraggedBlocks; /** * Re-disables the given block and its children using their original * disabled reasons. * * @param block The block to re-disable, if applicable. */ private redisableAllDraggedBlocks; } export {}; //# sourceMappingURL=block_drag_strategy.d.ts.map