@@ -5,6 +5,7 @@ var DragDropActionCreators = require('../actions/DragDropActionCreators'),
5
5
NativeDragDropSupport = require ( '../utils/NativeDragDropSupport' ) ,
6
6
EnterLeaveMonitor = require ( '../utils/EnterLeaveMonitor' ) ,
7
7
MemoizeBindMixin = require ( './MemoizeBindMixin' ) ,
8
+ DropEffects = require ( '../constants/DropEffects' ) ,
8
9
configureDataTransfer = require ( '../utils/configureDataTransfer' ) ,
9
10
isFileDragDropEvent = require ( '../utils/isFileDragDropEvent' ) ,
10
11
bindAll = require ( '../utils/bindAll' ) ,
@@ -13,6 +14,7 @@ var DragDropActionCreators = require('../actions/DragDropActionCreators'),
13
14
defaults = require ( 'lodash-node/modern/objects/defaults' ) ,
14
15
union = require ( 'lodash-node/modern/arrays/union' ) ,
15
16
without = require ( 'lodash-node/modern/arrays/without' ) ,
17
+ isArray = require ( 'lodash-node/modern/objects/isArray' ) ,
16
18
isObject = require ( 'lodash-node/modern/objects/isObject' ) ,
17
19
noop = require ( 'lodash-node/modern/utilities/noop' ) ;
18
20
@@ -75,6 +77,10 @@ var DefaultDropTarget = {
75
77
return true ;
76
78
} ,
77
79
80
+ getDropEffect ( allowedEffects ) {
81
+ return allowedEffects [ 0 ] ;
82
+ } ,
83
+
78
84
enter : noop ,
79
85
over : noop ,
80
86
leave : noop ,
@@ -90,7 +96,7 @@ var DragDropMixin = {
90
96
getInitialState ( ) {
91
97
var state = {
92
98
ownDraggedItemType : null ,
93
- hasDragEntered : false
99
+ currentDropEffect : null
94
100
} ;
95
101
96
102
return merge ( state , this . getStateFromDragDropStore ( ) ) ;
@@ -137,11 +143,11 @@ var DragDropMixin = {
137
143
checkDropTargetDefined ( this , type ) ;
138
144
139
145
var isDragging = this . getActiveDropTargetType ( ) === type ,
140
- hasDragEntered = this . state . hasDragEntered ;
146
+ isHovering = ! ! this . state . currentDropEffect ;
141
147
142
148
return {
143
149
isDragging : isDragging ,
144
- isHovering : isDragging && hasDragEntered
150
+ isHovering : isDragging && isHovering
145
151
} ;
146
152
} ,
147
153
@@ -191,7 +197,9 @@ var DragDropMixin = {
191
197
} ,
192
198
193
199
handleDragDropStoreChange ( ) {
194
- this . setState ( this . getStateFromDragDropStore ( ) ) ;
200
+ if ( this . isMounted ( ) ) {
201
+ this . setState ( this . getStateFromDragDropStore ( ) ) ;
202
+ }
195
203
} ,
196
204
197
205
dragSourceFor ( type ) {
@@ -221,12 +229,17 @@ var DragDropMixin = {
221
229
) ;
222
230
223
231
var dragOptions = beginDrag ( e ) ,
224
- { item } = dragOptions ;
232
+ { item, dragPreview, dragAnchors, effectsAllowed } = dragOptions ;
233
+
234
+ if ( ! effectsAllowed ) {
235
+ effectsAllowed = [ DropEffects . MOVE ] ;
236
+ }
225
237
226
- configureDataTransfer ( this . getDOMNode ( ) , e . nativeEvent , dragOptions ) ;
238
+ invariant ( isArray ( effectsAllowed ) && effectsAllowed . length > 0 , 'Expected effectsAllowed to be non-empty array' ) ;
227
239
invariant ( isObject ( item ) , 'Expected return value of beginDrag to contain "item" object' ) ;
228
240
229
- DragDropActionCreators . startDragging ( type , item ) ;
241
+ configureDataTransfer ( this . getDOMNode ( ) , e . nativeEvent , dragPreview , dragAnchors , effectsAllowed ) ;
242
+ DragDropActionCreators . startDragging ( type , item , effectsAllowed ) ;
230
243
231
244
// Delay setting own state by a tick so `getDragState(type).isDragging`
232
245
// doesn't return `true` yet. Otherwise browser will capture dragged state
@@ -245,7 +258,7 @@ var DragDropMixin = {
245
258
NativeDragDropSupport . handleDragEnd ( ) ;
246
259
247
260
var { endDrag } = this . _dragSources [ type ] ,
248
- didDrop = DragDropStore . didDrop ( ) ;
261
+ recordedDropEffect = DragDropStore . getDropEffect ( ) ;
249
262
250
263
DragDropActionCreators . endDragging ( ) ;
251
264
@@ -261,7 +274,7 @@ var DragDropMixin = {
261
274
ownDraggedItemType : null
262
275
} ) ;
263
276
264
- endDrag ( didDrop , e ) ;
277
+ endDrag ( recordedDropEffect , e ) ;
265
278
} ,
266
279
267
280
dropTargetFor ( ...types ) {
@@ -278,17 +291,6 @@ var DragDropMixin = {
278
291
} ;
279
292
} ,
280
293
281
- handleDragOver ( types , e ) {
282
- if ( ! this . isAnyDropTargetActive ( types ) ) {
283
- return ;
284
- }
285
-
286
- e . preventDefault ( ) ;
287
-
288
- var { over } = this . _dropTargets [ this . state . draggedItemType ] ;
289
- over ( this . state . draggedItem , e ) ;
290
- } ,
291
-
292
294
handleDragEnter ( types , e ) {
293
295
if ( ! this . isAnyDropTargetActive ( types ) ) {
294
296
return ;
@@ -298,14 +300,40 @@ var DragDropMixin = {
298
300
return ;
299
301
}
300
302
303
+ var { enter, getDropEffect } = this . _dropTargets [ this . state . draggedItemType ] ,
304
+ effectsAllowed = DragDropStore . getEffectsAllowed ( ) ,
305
+ dropEffect = getDropEffect ( effectsAllowed ) ;
306
+
307
+ if ( dropEffect && ! isFileDragDropEvent ( e ) ) {
308
+ invariant (
309
+ effectsAllowed . indexOf ( dropEffect ) > - 1 ,
310
+ 'Effect %s supplied by drop target is not one of the effects allowed by drag source: %s' ,
311
+ dropEffect ,
312
+ effectsAllowed . join ( ', ' )
313
+ ) ;
314
+ }
315
+
301
316
this . setState ( {
302
- hasDragEntered : true
317
+ currentDropEffect : dropEffect
303
318
} ) ;
304
319
305
- var { enter } = this . _dropTargets [ this . state . draggedItemType ] ;
306
320
enter ( this . state . draggedItem , e ) ;
307
321
} ,
308
322
323
+ handleDragOver ( types , e ) {
324
+ if ( ! this . isAnyDropTargetActive ( types ) ) {
325
+ return ;
326
+ }
327
+
328
+ e . preventDefault ( ) ;
329
+
330
+ var { over, getDropEffect } = this . _dropTargets [ this . state . draggedItemType ] ;
331
+ over ( this . state . draggedItem , e ) ;
332
+
333
+ // Don't use `none` because this will prevent browser from firing `dragend`
334
+ NativeDragDropSupport . handleDragOver ( e , this . state . currentDropEffect || 'move' ) ;
335
+ } ,
336
+
309
337
handleDragLeave ( types , e ) {
310
338
if ( ! this . isAnyDropTargetActive ( types ) ) {
311
339
return ;
@@ -316,7 +344,7 @@ var DragDropMixin = {
316
344
}
317
345
318
346
this . setState ( {
319
- hasDragEntered : false
347
+ currentDropEffect : null
320
348
} ) ;
321
349
322
350
var { leave } = this . _dropTargets [ this . state . draggedItemType ] ;
@@ -331,7 +359,9 @@ var DragDropMixin = {
331
359
e . preventDefault ( ) ;
332
360
333
361
var item = this . state . draggedItem ,
334
- { acceptDrop } = this . _dropTargets [ this . state . draggedItemType ] ;
362
+ { acceptDrop } = this . _dropTargets [ this . state . draggedItemType ] ,
363
+ { currentDropEffect } = this . state ,
364
+ recordedDropEffect = DragDropStore . getDropEffect ( ) ;
335
365
336
366
if ( isFileDragDropEvent ( e ) ) {
337
367
// We don't know file list until the `drop` event,
@@ -343,13 +373,15 @@ var DragDropMixin = {
343
373
344
374
this . _monitor . reset ( ) ;
345
375
376
+ if ( ! recordedDropEffect && currentDropEffect ) {
377
+ DragDropActionCreators . recordDrop ( currentDropEffect ) ;
378
+ }
379
+
346
380
this . setState ( {
347
- hasDragEntered : false
381
+ currentDropEffect : null
348
382
} ) ;
349
383
350
- if ( acceptDrop ( item , e ) !== false ) {
351
- DragDropActionCreators . recordDrop ( ) ;
352
- }
384
+ acceptDrop ( item , e , recordedDropEffect ) ;
353
385
}
354
386
} ;
355
387
0 commit comments