11import { isFunction } from 'lodash' ;
22
33import { CoreEventHandlers , CreateHandlerOptions } from './CoreEventHandlers' ;
4+ import { Positioner } from './Positioner' ;
45import { createShadow } from './createShadow' ;
56
6- import { Indicator , NodeId , NodeTree , Node } from '../interfaces' ;
7-
8- type DraggedElement = NodeId [ ] | NodeTree ;
7+ import { Indicator , NodeId , DragTarget } from '../interfaces' ;
98
109export type DefaultEventHandlersOptions = {
1110 isMultiSelectEnabled : ( e : MouseEvent ) => boolean ;
@@ -18,10 +17,14 @@ export class DefaultEventHandlers<O = {}> extends CoreEventHandlers<
1817 DefaultEventHandlersOptions & O
1918> {
2019 static draggedElementShadow : HTMLElement ;
21- static draggedElement : DraggedElement ;
22- static indicator : Indicator = null ;
20+ dragTarget : DragTarget ;
21+ positioner : Positioner | null = null ;
2322 currentSelectedElementIds = [ ] ;
2423
24+ onDisable ( ) {
25+ this . options . store . actions . clearEvents ( ) ;
26+ }
27+
2528 handlers ( ) {
2629 const store = this . options . store ;
2730
@@ -108,7 +111,6 @@ export class DefaultEventHandlers<O = {}> extends CoreEventHandlers<
108111 } ) ;
109112
110113 return ( ) => {
111- store . actions . setNodeEvent ( 'selected' , null ) ;
112114 unbindOnMouseDown ( ) ;
113115 unbindOnClick ( ) ;
114116 } ;
@@ -124,50 +126,41 @@ export class DefaultEventHandlers<O = {}> extends CoreEventHandlers<
124126 ) ;
125127
126128 return ( ) => {
127- store . actions . setNodeEvent ( 'hovered' , null ) ;
128129 unbindMouseover ( ) ;
129130 } ;
130131 } ,
131132 drop : ( el : HTMLElement , targetId : NodeId ) => {
132133 const unbindDragOver = this . addCraftEventListener (
133134 el ,
134135 'dragover' ,
135- ( e ) => {
136- e . craft . stopPropagation ( ) ;
137- e . preventDefault ( ) ;
138- }
139- ) ;
140-
141- const unbindDragEnter = this . addCraftEventListener (
142- el ,
143- 'dragenter' ,
144136 ( e ) => {
145137 e . craft . stopPropagation ( ) ;
146138 e . preventDefault ( ) ;
147139
148- const draggedElement = DefaultEventHandlers . draggedElement ;
149- if ( ! draggedElement ) {
140+ if ( ! this . positioner ) {
150141 return ;
151142 }
152143
153- let node = ( draggedElement as unknown ) as Node ;
154-
155- if ( ( draggedElement as NodeTree ) . rootNodeId ) {
156- const nodeTree = draggedElement as NodeTree ;
157- node = nodeTree . nodes [ nodeTree . rootNodeId ] ;
158- }
159-
160- const { clientX : x , clientY : y } = e ;
161- const indicator = store . query . getDropPlaceholder ( node , targetId , {
162- x,
163- y,
164- } ) ;
144+ const indicator = this . positioner . computeIndicator (
145+ targetId ,
146+ e . clientX ,
147+ e . clientY
148+ ) ;
165149
166150 if ( ! indicator ) {
167151 return ;
168152 }
153+
169154 store . actions . setIndicator ( indicator ) ;
170- DefaultEventHandlers . indicator = indicator ;
155+ }
156+ ) ;
157+
158+ const unbindDragEnter = this . addCraftEventListener (
159+ el ,
160+ 'dragenter' ,
161+ ( e ) => {
162+ e . craft . stopPropagation ( ) ;
163+ e . preventDefault ( ) ;
171164 }
172165 ) ;
173166
@@ -203,18 +196,36 @@ export class DefaultEventHandlers<O = {}> extends CoreEventHandlers<
203196 query . node ( id ) . get ( ) . dom ,
204197 selectedDOMs
205198 ) ;
206- DefaultEventHandlers . draggedElement = selectedElementIds ;
199+ this . dragTarget = {
200+ type : 'existing' ,
201+ nodes : selectedElementIds ,
202+ } ;
203+
204+ this . positioner = new Positioner (
205+ this . options . store ,
206+ this . dragTarget
207+ ) ;
207208 }
208209 ) ;
209210
210211 const unbindDragEnd = this . addCraftEventListener ( el , 'dragend' , ( e ) => {
211212 e . craft . stopPropagation ( ) ;
212- const onDropElement = ( draggedElement , placement ) => {
213+
214+ this . dropElement ( ( dragTarget , indicator ) => {
215+ if ( dragTarget . type === 'new' ) {
216+ return ;
217+ }
218+
213219 const index =
214- placement . index + ( placement . where === 'after' ? 1 : 0 ) ;
215- store . actions . move ( draggedElement , placement . parent . id , index ) ;
216- } ;
217- this . dropElement ( onDropElement ) ;
220+ indicator . placement . index +
221+ ( indicator . placement . where === 'after' ? 1 : 0 ) ;
222+
223+ store . actions . move (
224+ dragTarget . nodes ,
225+ indicator . placement . parent . id ,
226+ index
227+ ) ;
228+ } ) ;
218229 } ) ;
219230
220231 return ( ) => {
@@ -240,30 +251,41 @@ export class DefaultEventHandlers<O = {}> extends CoreEventHandlers<
240251 . toNodeTree ( ) ;
241252
242253 const dom = e . currentTarget as HTMLElement ;
243-
244254 DefaultEventHandlers . draggedElementShadow = createShadow ( e , dom , [
245- dom ,
255+ el ,
246256 ] ) ;
247- DefaultEventHandlers . draggedElement = tree ;
257+ this . dragTarget = {
258+ type : 'new' ,
259+ tree,
260+ } ;
261+
262+ this . positioner = new Positioner (
263+ this . options . store ,
264+ this . dragTarget
265+ ) ;
248266 }
249267 ) ;
250268
251269 const unbindDragEnd = this . addCraftEventListener ( el , 'dragend' , ( e ) => {
252270 e . craft . stopPropagation ( ) ;
253- const onDropElement = ( draggedElement , placement ) => {
271+ this . dropElement ( ( dragTarget , indicator ) => {
272+ if ( dragTarget . type === 'existing' ) {
273+ return ;
274+ }
275+
254276 const index =
255- placement . index + ( placement . where === 'after' ? 1 : 0 ) ;
277+ indicator . placement . index +
278+ ( indicator . placement . where === 'after' ? 1 : 0 ) ;
256279 store . actions . addNodeTree (
257- draggedElement ,
258- placement . parent . id ,
280+ dragTarget . tree ,
281+ indicator . placement . parent . id ,
259282 index
260283 ) ;
261284
262285 if ( options && isFunction ( options . onCreate ) ) {
263- options . onCreate ( draggedElement ) ;
286+ options . onCreate ( dragTarget . tree ) ;
264287 }
265- } ;
266- this . dropElement ( onDropElement ) ;
288+ } ) ;
267289 } ) ;
268290
269291 return ( ) => {
@@ -276,32 +298,33 @@ export class DefaultEventHandlers<O = {}> extends CoreEventHandlers<
276298 }
277299
278300 private dropElement (
279- onDropNode : (
280- draggedElement : DraggedElement ,
281- placement : Indicator [ 'placement' ]
282- ) => void
301+ onDropNode : ( dragTarget : DragTarget , placement : Indicator ) => void
283302 ) {
284303 const store = this . options . store ;
285304
286- const {
287- draggedElement,
288- draggedElementShadow,
289- indicator,
290- } = DefaultEventHandlers ;
291- if ( draggedElement && indicator && ! indicator . error ) {
292- const { placement } = indicator ;
293- onDropNode ( draggedElement , placement ) ;
305+ if ( ! this . positioner ) {
306+ return ;
307+ }
308+
309+ const { draggedElementShadow } = DefaultEventHandlers ;
310+
311+ const indicator = this . positioner . getIndicator ( ) ;
312+
313+ if ( this . dragTarget && indicator && ! indicator . error ) {
314+ onDropNode ( this . dragTarget , indicator ) ;
294315 }
295316
296317 if ( draggedElementShadow ) {
297318 draggedElementShadow . parentNode . removeChild ( draggedElementShadow ) ;
298319 DefaultEventHandlers . draggedElementShadow = null ;
299320 }
300321
301- DefaultEventHandlers . draggedElement = null ;
302- DefaultEventHandlers . indicator = null ;
322+ this . dragTarget = null ;
303323
304324 store . actions . setIndicator ( null ) ;
305325 store . actions . setNodeEvent ( 'dragged' , null ) ;
326+ this . positioner . cleanup ( ) ;
327+
328+ this . positioner = null ;
306329 }
307330}
0 commit comments