fix(handles): reconnect for connectionMode=loose #4459
This commit is contained in:
@@ -282,16 +282,12 @@ function isValidHandle(
|
|||||||
|
|
||||||
result.isValid = isValid && isValidConnection(connection);
|
result.isValid = isValid && isValidConnection(connection);
|
||||||
|
|
||||||
if (handleLookup) {
|
const toHandle = handleLookup?.get(`${handleNodeId}-${handleType}-${handleId}`);
|
||||||
const toHandle = handleLookup.find(
|
|
||||||
(h) => h.id === handleId && h.nodeId === handleNodeId && h.type === handleType
|
|
||||||
);
|
|
||||||
|
|
||||||
if (toHandle) {
|
if (toHandle) {
|
||||||
result.toHandle = {
|
result.toHandle = {
|
||||||
...toHandle,
|
...toHandle,
|
||||||
};
|
};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ export type IsValidParams = {
|
|||||||
doc: Document | ShadowRoot;
|
doc: Document | ShadowRoot;
|
||||||
lib: string;
|
lib: string;
|
||||||
flowId: string | null;
|
flowId: string | null;
|
||||||
handleLookup?: Handle[];
|
handleLookup?: Map<string, Handle>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type XYHandleInstance = {
|
export type XYHandleInstance = {
|
||||||
|
|||||||
@@ -29,11 +29,15 @@ function getHandles(
|
|||||||
return [handles, excludedHandle];
|
return [handles, excludedHandle];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getClosestHandle(pos: XYPosition, connectionRadius: number, handles: Handle[]): Handle | null {
|
export function getClosestHandle(
|
||||||
|
pos: XYPosition,
|
||||||
|
connectionRadius: number,
|
||||||
|
handleLookup: Map<string, Handle>
|
||||||
|
): Handle | null {
|
||||||
let closestHandles: Handle[] = [];
|
let closestHandles: Handle[] = [];
|
||||||
let minDistance = Infinity;
|
let minDistance = Infinity;
|
||||||
|
|
||||||
for (const handle of handles) {
|
for (const handle of handleLookup.values()) {
|
||||||
const distance = Math.sqrt(Math.pow(handle.x - pos.x, 2) + Math.pow(handle.y - pos.y, 2));
|
const distance = Math.sqrt(Math.pow(handle.x - pos.x, 2) + Math.pow(handle.y - pos.y, 2));
|
||||||
if (distance <= connectionRadius) {
|
if (distance <= connectionRadius) {
|
||||||
if (distance < minDistance) {
|
if (distance < minDistance) {
|
||||||
@@ -68,21 +72,38 @@ export function getHandleLookup({
|
|||||||
nodeId,
|
nodeId,
|
||||||
handleId,
|
handleId,
|
||||||
handleType,
|
handleType,
|
||||||
}: GetHandleLookupParams): [Handle[], Handle] {
|
}: GetHandleLookupParams): [Map<string, Handle>, Handle] {
|
||||||
const connectionHandles: Handle[] = [];
|
const connectionHandles: Map<string, Handle> = new Map();
|
||||||
const currentHandle = { nodeId, handleId, handleType };
|
const currentHandle = { nodeId, handleId, handleType };
|
||||||
let excludedHandle: Handle | null = null;
|
let matchingHandle: Handle | null = null;
|
||||||
|
|
||||||
for (const node of nodeLookup.values()) {
|
for (const node of nodeLookup.values()) {
|
||||||
if (node.internals.handleBounds) {
|
if (node.internals.handleBounds) {
|
||||||
const [sourceHandles, excludedSource] = getHandles(node, node.internals.handleBounds, 'source', currentHandle);
|
const [sourceHandles, excludedSource] = getHandles(node, node.internals.handleBounds, 'source', currentHandle);
|
||||||
const [targetHandles, excludedTarget] = getHandles(node, node.internals.handleBounds, 'target', currentHandle);
|
const [targetHandles, excludedTarget] = getHandles(node, node.internals.handleBounds, 'target', currentHandle);
|
||||||
excludedHandle = excludedHandle ? excludedHandle : excludedSource ?? excludedTarget;
|
|
||||||
connectionHandles.push(...sourceHandles, ...targetHandles);
|
matchingHandle = matchingHandle ? matchingHandle : excludedSource ?? excludedTarget;
|
||||||
|
|
||||||
|
[...sourceHandles, ...targetHandles].forEach((handle) =>
|
||||||
|
connectionHandles.set(`${handle.nodeId}-${handle.type}-${handle.id}`, handle)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return [connectionHandles, excludedHandle!];
|
// if the user only works with handles that are type="source" + connectionMode="loose"
|
||||||
|
// it happens that we can't find a matching handle. The reason for this is, that the
|
||||||
|
// edge don't know about the handles and always assumes that there is source and a target.
|
||||||
|
// In this case we need to find the matching handle by switching the handleType
|
||||||
|
if (!matchingHandle) {
|
||||||
|
const node = nodeLookup.get(nodeId);
|
||||||
|
if (node?.internals.handleBounds) {
|
||||||
|
currentHandle.handleType = handleType === 'source' ? 'target' : 'source';
|
||||||
|
const [, excluded] = getHandles(node, node.internals.handleBounds, currentHandle.handleType, currentHandle);
|
||||||
|
matchingHandle = excluded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [connectionHandles, matchingHandle!];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getHandleType(
|
export function getHandleType(
|
||||||
|
|||||||
Reference in New Issue
Block a user