UNPKG

react-dnd

Version:
149 lines (148 loc) 5.34 kB
import wrapConnectorHooks from './wrapConnectorHooks'; import { isRef } from '../utils/isRef'; import shallowEqual from 'shallowequal'; export class SourceConnector { constructor(backend) { this.backend = backend; this.hooks = wrapConnectorHooks({ dragSource: (node, options) => { this.dragSourceOptions = options || null; if (isRef(node)) { this.dragSourceRef = node; } else { this.dragSourceNode = node; } this.reconnectDragSource(); }, dragPreview: (node, options) => { this.dragPreviewOptions = options || null; if (isRef(node)) { this.dragPreviewRef = node; } else { this.dragPreviewNode = node; } this.reconnectDragPreview(); }, }); this.handlerId = null; // The drop target may either be attached via ref or connect function this.dragSourceRef = null; this.dragSourceOptionsInternal = null; // The drag preview may either be attached via ref or connect function this.dragPreviewRef = null; this.dragPreviewOptionsInternal = null; this.lastConnectedHandlerId = null; this.lastConnectedDragSource = null; this.lastConnectedDragSourceOptions = null; this.lastConnectedDragPreview = null; this.lastConnectedDragPreviewOptions = null; } receiveHandlerId(newHandlerId) { if (this.handlerId === newHandlerId) { return; } this.handlerId = newHandlerId; this.reconnect(); } get connectTarget() { return this.dragSource; } get dragSourceOptions() { return this.dragSourceOptionsInternal; } set dragSourceOptions(options) { this.dragSourceOptionsInternal = options; } get dragPreviewOptions() { return this.dragPreviewOptionsInternal; } set dragPreviewOptions(options) { this.dragPreviewOptionsInternal = options; } reconnect() { this.reconnectDragSource(); this.reconnectDragPreview(); } reconnectDragSource() { // if nothing has changed then don't resubscribe const didChange = this.didHandlerIdChange() || this.didConnectedDragSourceChange() || this.didDragSourceOptionsChange(); if (didChange) { this.disconnectDragSource(); } const dragSource = this.dragSource; if (!this.handlerId) { return; } if (!dragSource) { this.lastConnectedDragSource = dragSource; return; } if (didChange) { this.lastConnectedHandlerId = this.handlerId; this.lastConnectedDragSource = dragSource; this.lastConnectedDragSourceOptions = this.dragSourceOptions; this.dragSourceUnsubscribe = this.backend.connectDragSource(this.handlerId, dragSource, this.dragSourceOptions); } } reconnectDragPreview() { // if nothing has changed then don't resubscribe const didChange = this.didHandlerIdChange() || this.didConnectedDragPreviewChange() || this.didDragPreviewOptionsChange(); if (didChange) { this.disconnectDragPreview(); } const dragPreview = this.dragPreview; if (!this.handlerId || !dragPreview) { return; } if (didChange) { this.lastConnectedHandlerId = this.handlerId; this.lastConnectedDragPreview = dragPreview; this.lastConnectedDragPreviewOptions = this.dragPreviewOptions; this.dragPreviewUnsubscribe = this.backend.connectDragPreview(this.handlerId, dragPreview, this.dragPreviewOptions); } } didHandlerIdChange() { return this.lastConnectedHandlerId !== this.handlerId; } didConnectedDragSourceChange() { return this.lastConnectedDragSource !== this.dragSource; } didConnectedDragPreviewChange() { return this.lastConnectedDragPreview !== this.dragPreview; } didDragSourceOptionsChange() { return !shallowEqual(this.lastConnectedDragSourceOptions, this.dragSourceOptions); } didDragPreviewOptionsChange() { return !shallowEqual(this.lastConnectedDragPreviewOptions, this.dragPreviewOptions); } disconnectDragSource() { if (this.dragSourceUnsubscribe) { this.dragSourceUnsubscribe(); this.dragSourceUnsubscribe = undefined; this.dragPreviewNode = null; this.dragPreviewRef = null; } } disconnectDragPreview() { if (this.dragPreviewUnsubscribe) { this.dragPreviewUnsubscribe(); this.dragPreviewUnsubscribe = undefined; this.dragPreviewNode = null; this.dragPreviewRef = null; } } get dragSource() { return (this.dragSourceNode || (this.dragSourceRef && this.dragSourceRef.current)); } get dragPreview() { return (this.dragPreviewNode || (this.dragPreviewRef && this.dragPreviewRef.current)); } }