@@ -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 && 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,9 +358,8 @@ 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
- toggleClass ( dragEl , options . selectedClass , ! ~ multiDragElements . indexOf ( dragEl ) ) ;
317
363
318
364
if ( ! ~ multiDragElements . indexOf ( dragEl ) ) {
319
365
multiDragElements . push ( dragEl ) ;
@@ -461,39 +507,38 @@ function MultiDragPlugin() {
461
507
} ,
462
508
463
509
destroyGlobal ( ) {
464
- this . _deselectMultiDrag ( ) ;
510
+ MultiDrag . utils . clear ( ) ;
511
+
465
512
off ( document , 'pointerup' , this . _deselectMultiDrag ) ;
466
513
off ( document , 'mouseup' , this . _deselectMultiDrag ) ;
467
514
off ( document , 'touchend' , this . _deselectMultiDrag ) ;
468
515
469
516
off ( document , 'keydown' , this . _checkKeyDown ) ;
470
517
off ( document , 'keyup' , this . _checkKeyUp ) ;
518
+
519
+ const groupMembers = findAllMembersInSortableGroup ( this . sortable ) ;
520
+
521
+ if ( groupMembers ) {
522
+ let membersIndex ;
523
+ if ( ~ ( membersIndex = groupMembers . indexOf ( this . sortable ) ) ) {
524
+ groupMembers . splice ( membersIndex , 1 ) ;
525
+ }
526
+ }
471
527
} ,
472
528
473
529
_deselectMultiDrag ( evt ) {
474
- if ( typeof dragStarted !== "undefined" && dragStarted ) return ;
475
-
476
530
// Only deselect if selection is in this sortable
477
531
if ( multiDragSortable !== this . sortable ) return ;
478
532
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
- } ) ;
533
+ if ( evt ) {
534
+ // Only deselect if left click
535
+ if ( evt . button !== 0 ) return ;
536
+
537
+ // Only deselect if target is not item in any sortable in group (including this)
538
+ if ( itemElIsInSortableGroup ( evt . target , this . sortable ) ) return ;
496
539
}
540
+
541
+ MultiDrag . utils . clear ( evt ) ;
497
542
} ,
498
543
499
544
_checkKeyDown ( evt ) {
@@ -521,7 +566,9 @@ function MultiDragPlugin() {
521
566
let sortable = el . parentNode [ expando ] ;
522
567
if ( ! sortable || ! sortable . options . multiDrag || ~ multiDragElements . indexOf ( el ) ) return ;
523
568
if ( multiDragSortable && multiDragSortable !== sortable ) {
524
- multiDragSortable . multiDrag . _deselectMultiDrag ( ) ;
569
+ if ( ! itemElIsInSortableGroup ( el , multiDragSortable ) ) {
570
+ MultiDrag . utils . clear ( ) ;
571
+ }
525
572
multiDragSortable = sortable ;
526
573
}
527
574
toggleClass ( el , sortable . options . selectedClass , true ) ;
@@ -537,6 +584,24 @@ function MultiDragPlugin() {
537
584
if ( ! sortable || ! sortable . options . multiDrag || ! ~ index ) return ;
538
585
toggleClass ( el , sortable . options . selectedClass , false ) ;
539
586
multiDragElements . splice ( index , 1 ) ;
587
+ } ,
588
+ clear ( evt ) {
589
+ if ( typeof dragStarted !== "undefined" && dragStarted ) return ;
590
+
591
+ while ( multiDragElements . length ) {
592
+ const el = multiDragElements [ 0 ] ;
593
+ const sortableEl = getParentOrHost ( el ) ;
594
+ const sortable = sortableEl [ expando ] ;
595
+ toggleClass ( el , sortable . options . selectedClass , false ) ;
596
+ multiDragElements . shift ( ) ;
597
+ dispatchEvent ( {
598
+ sortable : sortable ,
599
+ rootEl : sortableEl ,
600
+ name : 'deselect' ,
601
+ targetEl : el ,
602
+ originalEvent : evt
603
+ } ) ;
604
+ }
540
605
}
541
606
} ,
542
607
eventProperties ( ) {
@@ -546,6 +611,7 @@ function MultiDragPlugin() {
546
611
multiDragElements . forEach ( multiDragElement => {
547
612
oldIndicies . push ( {
548
613
multiDragElement,
614
+ parentElement : multiDragElement . sortableParentEl ,
549
615
index : multiDragElement . sortableIndex
550
616
} ) ;
551
617
@@ -560,9 +626,11 @@ function MultiDragPlugin() {
560
626
}
561
627
newIndicies . push ( {
562
628
multiDragElement,
629
+ parentElement : multiDragElement . sortableParentEl ,
563
630
index : newIndex
564
631
} ) ;
565
632
} ) ;
633
+
566
634
return {
567
635
items : [ ...multiDragElements ] ,
568
636
clones : [ ...multiDragClones ] ,
@@ -572,11 +640,13 @@ function MultiDragPlugin() {
572
640
} ,
573
641
optionListeners : {
574
642
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 ) ;
643
+ if ( typeof key === 'string' ) {
644
+ key = key . toLowerCase ( ) ;
645
+ if ( key === 'ctrl' ) {
646
+ key = 'Control' ;
647
+ } else if ( key . length > 1 ) {
648
+ key = key . charAt ( 0 ) . toUpperCase ( ) + key . substr ( 1 ) ;
649
+ }
580
650
}
581
651
return key ;
582
652
}
@@ -618,4 +688,15 @@ function removeMultiDragElements() {
618
688
} ) ;
619
689
}
620
690
691
+ function findAllMembersInSortableGroup ( sortable ) {
692
+ if ( ! sortable . options . group ) {
693
+ return null ;
694
+ }
695
+ return multiDragGroupMembers [ sortable . options . group . name ] || [ ] ;
696
+ }
697
+
698
+ function itemElIsInSortableGroup ( itemEl , sortable ) {
699
+ return ~ ( findAllMembersInSortableGroup ( sortable ) || [ sortable ] ) . findIndex ( ( sortable ) => closest ( itemEl , sortable . options . draggable , sortable . el , false ) ) ;
700
+ }
701
+
621
702
export default MultiDragPlugin ;
0 commit comments