@@ -17,9 +17,6 @@ const activeCapturingEventOptions = normalizePassiveListenerOptions({
1717 capture : true
1818} ) ;
1919
20- /** Handler for a pointer event callback. */
21- type PointerEventHandler = ( event : TouchEvent | MouseEvent ) => void ;
22-
2320/**
2421 * Service that keeps track of all the drag item and drop container
2522 * instances, and manages global event listeners on the `document`.
@@ -42,8 +39,8 @@ export class DragDropRegistry<I, C extends {id: string}> implements OnDestroy {
4239 private _activeDragInstances = new Set < I > ( ) ;
4340
4441 /** Keeps track of the event listeners that we've bound to the `document`. */
45- private _globalListeners = new Map < 'touchmove' | 'mousemove' | 'touchend' | 'mouseup' | 'wheel' , {
46- handler : PointerEventHandler ,
42+ private _globalListeners = new Map < string , {
43+ handler : ( event : Event ) => void ,
4744 options ?: AddEventListenerOptions | boolean
4845 } > ( ) ;
4946
@@ -87,7 +84,7 @@ export class DragDropRegistry<I, C extends {id: string}> implements OnDestroy {
8784 this . _ngZone . runOutsideAngular ( ( ) => {
8885 // The event handler has to be explicitly active,
8986 // because newer browsers make it passive by default.
90- this . _document . addEventListener ( 'touchmove' , this . _preventScrollListener ,
87+ this . _document . addEventListener ( 'touchmove' , this . _preventDefaultWhileDragging ,
9188 activeCapturingEventOptions ) ;
9289 } ) ;
9390 }
@@ -104,7 +101,7 @@ export class DragDropRegistry<I, C extends {id: string}> implements OnDestroy {
104101 this . stopDragging ( drag ) ;
105102
106103 if ( this . _dragInstances . size === 0 ) {
107- this . _document . removeEventListener ( 'touchmove' , this . _preventScrollListener ,
104+ this . _document . removeEventListener ( 'touchmove' , this . _preventDefaultWhileDragging ,
108105 activeCapturingEventOptions ) ;
109106 }
110107 }
@@ -127,19 +124,27 @@ export class DragDropRegistry<I, C extends {id: string}> implements OnDestroy {
127124 // use `preventDefault` to prevent the page from scrolling while the user is dragging.
128125 this . _globalListeners
129126 . set ( moveEvent , {
130- handler : e => this . pointerMove . next ( e ) ,
127+ handler : ( e : Event ) => this . pointerMove . next ( e as TouchEvent | MouseEvent ) ,
131128 options : activeCapturingEventOptions
132129 } )
133130 . set ( upEvent , {
134- handler : e => this . pointerUp . next ( e ) ,
131+ handler : ( e : Event ) => this . pointerUp . next ( e as TouchEvent | MouseEvent ) ,
135132 options : true
133+ } )
134+ // Preventing the default action on `mousemove` isn't enough to disable text selection
135+ // on Safari so we need to prevent the selection event as well. Alternatively this can
136+ // be done by setting `user-select: none` on the `body`, however it has causes a style
137+ // recalculation which can be expensive on pages with a lot of elements.
138+ . set ( 'selectstart' , {
139+ handler : this . _preventDefaultWhileDragging ,
140+ options : activeCapturingEventOptions
136141 } ) ;
137142
138143 // TODO(crisbeto): prevent mouse wheel scrolling while
139144 // dragging until we've set up proper scroll handling.
140145 if ( ! isTouchEvent ) {
141146 this . _globalListeners . set ( 'wheel' , {
142- handler : this . _preventScrollListener ,
147+ handler : this . _preventDefaultWhileDragging ,
143148 options : activeCapturingEventOptions
144149 } ) ;
145150 }
@@ -184,9 +189,10 @@ export class DragDropRegistry<I, C extends {id: string}> implements OnDestroy {
184189 }
185190
186191 /**
187- * Listener used to prevent `touchmove` and `wheel` events while the element is being dragged.
192+ * Event listener that will prevent the default browser action while the user is dragging.
193+ * @param event Event whose default action should be prevented.
188194 */
189- private _preventScrollListener = ( event : Event ) => {
195+ private _preventDefaultWhileDragging = ( event : Event ) => {
190196 if ( this . _activeDragInstances . size ) {
191197 event . preventDefault ( ) ;
192198 }
0 commit comments