@@ -10,7 +10,8 @@ import {
10
10
setRect ,
11
11
unsetRect ,
12
12
matrix ,
13
- expando
13
+ expando ,
14
+ getParentOrHost ,
14
15
} from '../../src/utils.js' ;
15
16
16
17
import dispatchEvent from '../../src/EventDispatcher.js' ;
@@ -19,6 +20,7 @@ let multiDragElements = [],
19
20
multiDragClones = [ ] ,
20
21
lastMultiDragSelect , // for selection with modifier key down (SHIFT)
21
22
multiDragSortable ,
23
+ multiDragGroupMembers = { } ,
22
24
initialFolding = false , // Initial multi-drag fold when drag started
23
25
folding = false , // Folding any other time
24
26
dragStarted = false ,
@@ -44,6 +46,14 @@ function MultiDragPlugin() {
44
46
}
45
47
}
46
48
49
+ if ( sortable . options . group ) {
50
+ const group = typeof sortable . options . group === 'string' ? { name : sortable . options . group } : sortable . options . group ;
51
+ if ( multiDragGroupMembers [ group . name ] === undefined ) {
52
+ multiDragGroupMembers [ group . name ] = [ ] ;
53
+ }
54
+ multiDragGroupMembers [ group . name ] . push ( sortable ) ;
55
+ }
56
+
47
57
on ( document , 'keydown' , this . _checkKeyDown ) ;
48
58
on ( document , 'keyup' , this . _checkKeyUp ) ;
49
59
@@ -69,7 +79,6 @@ function MultiDragPlugin() {
69
79
multiDragKeyDown : false ,
70
80
isMultiDrag : false ,
71
81
72
-
73
82
delayStartGlobal ( { dragEl : dragged } ) {
74
83
dragEl = dragged ;
75
84
} ,
@@ -84,6 +93,7 @@ function MultiDragPlugin() {
84
93
multiDragClones . push ( clone ( multiDragElements [ i ] ) ) ;
85
94
86
95
multiDragClones [ i ] . sortableIndex = multiDragElements [ i ] . sortableIndex ;
96
+ multiDragClones [ i ] . sortableParentEl = multiDragElements [ i ] . sortableParentEl ;
87
97
88
98
multiDragClones [ i ] . draggable = false ;
89
99
multiDragClones [ i ] . style [ 'will-change' ] = '' ;
@@ -136,11 +146,12 @@ function MultiDragPlugin() {
136
146
137
147
dragStartGlobal ( { sortable } ) {
138
148
if ( ! this . isMultiDrag && multiDragSortable ) {
139
- multiDragSortable . multiDrag . _deselectMultiDrag ( ) ;
149
+ MultiDrag . utils . clear ( ) ;
140
150
}
141
151
142
152
multiDragElements . forEach ( multiDragElement => {
143
153
multiDragElement . sortableIndex = index ( multiDragElement ) ;
154
+ multiDragElement . sortableParentEl = getParentOrHost ( multiDragElement ) ;
144
155
} ) ;
145
156
146
157
// Sort multi-drag elements
@@ -197,10 +208,46 @@ function MultiDragPlugin() {
197
208
} ) ;
198
209
} ,
199
210
200
- dragOver ( { target, completed, cancel } ) {
211
+ dragOver ( { target, completed, cancel, originalEvent } ) {
201
212
if ( folding && ~ multiDragElements . indexOf ( target ) ) {
202
213
completed ( false ) ;
203
214
cancel ( ) ;
215
+ return ;
216
+ }
217
+
218
+ const toSortable = target . parentNode [ expando ] ;
219
+
220
+ if ( ! toSortable || multiDragElements . length === 0 ) {
221
+ return ;
222
+ }
223
+
224
+ let checkPut ;
225
+
226
+ if ( toSortable . options . group ) {
227
+ checkPut = toSortable . options . group . checkPut ;
228
+ }
229
+
230
+ const forbiddenMove = ~ multiDragElements . findIndex ( ( el ) => {
231
+ if ( ! el . sortableParentEl ) {
232
+ return false ;
233
+ }
234
+
235
+ const fromSortable = el . sortableParentEl [ expando ] ;
236
+
237
+ if ( fromSortable && fromSortable . options . group && ! fromSortable . options . group . checkPull ( toSortable , fromSortable , el , originalEvent ) ) {
238
+ return true ;
239
+ }
240
+
241
+ if ( checkPut && ! checkPut ( toSortable , fromSortable , el , originalEvent ) ) {
242
+ return true ;
243
+ }
244
+
245
+ return false ;
246
+ } ) ;
247
+
248
+ if ( forbiddenMove ) {
249
+ completed ( false ) ;
250
+ cancel ( ) ;
204
251
}
205
252
} ,
206
253
@@ -311,7 +358,7 @@ function MultiDragPlugin() {
311
358
// Multi-drag selection
312
359
if ( ! dragStarted ) {
313
360
if ( options . multiDragKey && ! this . multiDragKeyDown ) {
314
- this . _deselectMultiDrag ( ) ;
361
+ MultiDrag . utils . clear ( ) ;
315
362
}
316
363
toggleClass ( dragEl , options . selectedClass , ! ~ multiDragElements . indexOf ( dragEl ) ) ;
317
364
@@ -461,39 +508,38 @@ function MultiDragPlugin() {
461
508
} ,
462
509
463
510
destroyGlobal ( ) {
464
- this . _deselectMultiDrag ( ) ;
511
+ MultiDrag . utils . clear ( ) ;
512
+
465
513
off ( document , 'pointerup' , this . _deselectMultiDrag ) ;
466
514
off ( document , 'mouseup' , this . _deselectMultiDrag ) ;
467
515
off ( document , 'touchend' , this . _deselectMultiDrag ) ;
468
516
469
517
off ( document , 'keydown' , this . _checkKeyDown ) ;
470
518
off ( document , 'keyup' , this . _checkKeyUp ) ;
519
+
520
+ const groupMembers = findAllMembersInSortableGroup ( this . sortable ) ;
521
+
522
+ if ( groupMembers ) {
523
+ let membersIndex ;
524
+ if ( ~ ( membersIndex = groupMembers . indexOf ( this . sortable ) ) ) {
525
+ groupMembers . splice ( membersIndex , 1 ) ;
526
+ }
527
+ }
471
528
} ,
472
529
473
530
_deselectMultiDrag ( evt ) {
474
- if ( typeof dragStarted !== "undefined" && dragStarted ) return ;
475
-
476
531
// Only deselect if selection is in this sortable
477
532
if ( multiDragSortable !== this . sortable ) return ;
478
533
479
- // Only deselect if target is not item in this sortable
480
- if ( evt && closest ( evt . target , this . options . draggable , this . sortable . el , false ) ) return ;
481
-
482
- // Only deselect if left click
483
- if ( evt && evt . button !== 0 ) return ;
484
-
485
- while ( multiDragElements . length ) {
486
- let el = multiDragElements [ 0 ] ;
487
- toggleClass ( el , this . options . selectedClass , false ) ;
488
- multiDragElements . shift ( ) ;
489
- dispatchEvent ( {
490
- sortable : this . sortable ,
491
- rootEl : this . sortable . el ,
492
- name : 'deselect' ,
493
- targetEl : el ,
494
- originalEvent : evt
495
- } ) ;
534
+ if ( evt ) {
535
+ // Only deselect if left click
536
+ if ( evt . button !== 0 ) return ;
537
+
538
+ // Only deselect if target is not item in any sortable in group (including this)
539
+ if ( itemElIsInSortableGroup ( evt . target , this . sortable ) ) return ;
496
540
}
541
+
542
+ MultiDrag . utils . clear ( evt ) ;
497
543
} ,
498
544
499
545
_checkKeyDown ( evt ) {
@@ -521,7 +567,9 @@ function MultiDragPlugin() {
521
567
let sortable = el . parentNode [ expando ] ;
522
568
if ( ! sortable || ! sortable . options . multiDrag || ~ multiDragElements . indexOf ( el ) ) return ;
523
569
if ( multiDragSortable && multiDragSortable !== sortable ) {
524
- multiDragSortable . multiDrag . _deselectMultiDrag ( ) ;
570
+ if ( ! itemElIsInSortableGroup ( el , multiDragSortable ) ) {
571
+ MultiDrag . utils . clear ( ) ;
572
+ }
525
573
multiDragSortable = sortable ;
526
574
}
527
575
toggleClass ( el , sortable . options . selectedClass , true ) ;
@@ -537,6 +585,24 @@ function MultiDragPlugin() {
537
585
if ( ! sortable || ! sortable . options . multiDrag || ! ~ index ) return ;
538
586
toggleClass ( el , sortable . options . selectedClass , false ) ;
539
587
multiDragElements . splice ( index , 1 ) ;
588
+ } ,
589
+ clear ( evt ) {
590
+ if ( typeof dragStarted !== "undefined" && dragStarted ) return ;
591
+
592
+ while ( multiDragElements . length ) {
593
+ const el = multiDragElements [ 0 ] ;
594
+ const sortableEl = getParentOrHost ( el ) ;
595
+ const sortable = sortableEl [ expando ] ;
596
+ toggleClass ( el , sortable . options . selectedClass , false ) ;
597
+ multiDragElements . shift ( ) ;
598
+ dispatchEvent ( {
599
+ sortable : sortable ,
600
+ rootEl : sortableEl ,
601
+ name : 'deselect' ,
602
+ targetEl : el ,
603
+ originalEvent : evt
604
+ } ) ;
605
+ }
540
606
}
541
607
} ,
542
608
eventProperties ( ) {
@@ -546,6 +612,7 @@ function MultiDragPlugin() {
546
612
multiDragElements . forEach ( multiDragElement => {
547
613
oldIndicies . push ( {
548
614
multiDragElement,
615
+ parentElement : multiDragElement . sortableParentEl ,
549
616
index : multiDragElement . sortableIndex
550
617
} ) ;
551
618
@@ -560,9 +627,11 @@ function MultiDragPlugin() {
560
627
}
561
628
newIndicies . push ( {
562
629
multiDragElement,
630
+ parentElement : multiDragElement . sortableParentEl ,
563
631
index : newIndex
564
632
} ) ;
565
633
} ) ;
634
+
566
635
return {
567
636
items : [ ...multiDragElements ] ,
568
637
clones : [ ...multiDragClones ] ,
@@ -572,11 +641,13 @@ function MultiDragPlugin() {
572
641
} ,
573
642
optionListeners : {
574
643
multiDragKey ( key ) {
575
- key = key . toLowerCase ( ) ;
576
- if ( key === 'ctrl' ) {
577
- key = 'Control' ;
578
- } else if ( key . length > 1 ) {
579
- key = key . charAt ( 0 ) . toUpperCase ( ) + key . substr ( 1 ) ;
644
+ if ( typeof key === 'string' ) {
645
+ key = key . toLowerCase ( ) ;
646
+ if ( key === 'ctrl' ) {
647
+ key = 'Control' ;
648
+ } else if ( key . length > 1 ) {
649
+ key = key . charAt ( 0 ) . toUpperCase ( ) + key . substr ( 1 ) ;
650
+ }
580
651
}
581
652
return key ;
582
653
}
@@ -618,4 +689,15 @@ function removeMultiDragElements() {
618
689
} ) ;
619
690
}
620
691
692
+ function findAllMembersInSortableGroup ( sortable ) {
693
+ if ( ! sortable . options . group ) {
694
+ return null ;
695
+ }
696
+ return multiDragGroupMembers [ sortable . options . group . name ] || [ ] ;
697
+ }
698
+
699
+ function itemElIsInSortableGroup ( itemEl , sortable ) {
700
+ return ~ ( findAllMembersInSortableGroup ( sortable ) || [ sortable ] ) . findIndex ( ( sortable ) => closest ( itemEl , sortable . options . draggable , sortable . el , false ) ) ;
701
+ }
702
+
621
703
export default MultiDragPlugin ;
0 commit comments