Blame view

天文台pc/tianwentai-ui/node_modules/react-dnd/src/internals/TargetConnector.ts 3.11 KB
bc518174   王天杨   提交两个项目文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
  import { shallowEqual } from '@react-dnd/shallowequal'
  import type { Backend, Identifier, Unsubscribe } from 'dnd-core'
  import type { RefObject } from 'react'
  
  import type { DropTargetOptions } from '../types/index.js'
  import { isRef } from './isRef.js'
  import type { Connector } from './SourceConnector.js'
  import { wrapConnectorHooks } from './wrapConnectorHooks.js'
  
  export class TargetConnector implements Connector {
  	public hooks = wrapConnectorHooks({
  		dropTarget: (node: any, options: DropTargetOptions) => {
  			this.clearDropTarget()
  			this.dropTargetOptions = options
  			if (isRef(node)) {
  				this.dropTargetRef = node
  			} else {
  				this.dropTargetNode = node
  			}
  			this.reconnect()
  		},
  	})
  
  	private handlerId: Identifier | null = null
  	// The drop target may either be attached via ref or connect function
  	private dropTargetRef: RefObject<any> | null = null
  	private dropTargetNode: any
  	private dropTargetOptionsInternal: DropTargetOptions | null = null
  	private unsubscribeDropTarget: Unsubscribe | undefined
  
  	private lastConnectedHandlerId: Identifier | null = null
  	private lastConnectedDropTarget: any = null
  	private lastConnectedDropTargetOptions: DropTargetOptions | null = null
  	private readonly backend: Backend
  
  	public constructor(backend: Backend) {
  		this.backend = backend
  	}
  
  	public get connectTarget(): any {
  		return this.dropTarget
  	}
  
  	public reconnect(): void {
  		// if nothing has changed then don't resubscribe
  		const didChange =
  			this.didHandlerIdChange() ||
  			this.didDropTargetChange() ||
  			this.didOptionsChange()
  
  		if (didChange) {
  			this.disconnectDropTarget()
  		}
  
  		const dropTarget = this.dropTarget
  		if (!this.handlerId) {
  			return
  		}
  		if (!dropTarget) {
  			this.lastConnectedDropTarget = dropTarget
  			return
  		}
  
  		if (didChange) {
  			this.lastConnectedHandlerId = this.handlerId
  			this.lastConnectedDropTarget = dropTarget
  			this.lastConnectedDropTargetOptions = this.dropTargetOptions
  
  			this.unsubscribeDropTarget = this.backend.connectDropTarget(
  				this.handlerId,
  				dropTarget,
  				this.dropTargetOptions,
  			)
  		}
  	}
  
  	public receiveHandlerId(newHandlerId: Identifier | null): void {
  		if (newHandlerId === this.handlerId) {
  			return
  		}
  
  		this.handlerId = newHandlerId
  		this.reconnect()
  	}
  
  	public get dropTargetOptions(): DropTargetOptions {
  		return this.dropTargetOptionsInternal
  	}
  	public set dropTargetOptions(options: DropTargetOptions) {
  		this.dropTargetOptionsInternal = options
  	}
  
  	private didHandlerIdChange(): boolean {
  		return this.lastConnectedHandlerId !== this.handlerId
  	}
  
  	private didDropTargetChange(): boolean {
  		return this.lastConnectedDropTarget !== this.dropTarget
  	}
  
  	private didOptionsChange(): boolean {
  		return !shallowEqual(
  			this.lastConnectedDropTargetOptions,
  			this.dropTargetOptions,
  		)
  	}
  
  	public disconnectDropTarget() {
  		if (this.unsubscribeDropTarget) {
  			this.unsubscribeDropTarget()
  			this.unsubscribeDropTarget = undefined
  		}
  	}
  
  	private get dropTarget() {
  		return (
  			this.dropTargetNode || (this.dropTargetRef && this.dropTargetRef.current)
  		)
  	}
  
  	private clearDropTarget() {
  		this.dropTargetRef = null
  		this.dropTargetNode = null
  	}
  }