1010'use strict' ;
1111
1212var mouseOffset = require ( 'mouse-event-offset' ) ;
13+ var hasHover = require ( 'has-hover' ) ;
1314
1415var Plotly = require ( '../../plotly' ) ;
1516var Lib = require ( '../../lib' ) ;
@@ -29,6 +30,13 @@ dragElement.unhoverRaw = unhover.raw;
2930/**
3031 * Abstracts click & drag interactions
3132 *
33+ * During the interaction, a "coverSlip" element - a transparent
34+ * div covering the whole page - is created, which has two key effects:
35+ * - Lets you drag beyond the boundaries of the plot itself without
36+ * dropping (but if you drag all the way out of the browser window the
37+ * interaction will end)
38+ * - Freezes the cursor: whatever mouse cursor the drag element had when the
39+ * interaction started gets copied to the coverSlip for use until mouseup
3240 *
3341 * @param {object } options with keys:
3442 * element (required) the DOM element to drag
@@ -57,6 +65,7 @@ dragElement.init = function init(options) {
5765 startY ,
5866 newMouseDownTime ,
5967 cursor ,
68+ dragCover ,
6069 initialTarget ;
6170
6271 if ( ! gd . _mouseDownTime ) gd . _mouseDownTime = 0 ;
@@ -89,17 +98,22 @@ dragElement.init = function init(options) {
8998
9099 if ( options . prepFn ) options . prepFn ( e , startX , startY ) ;
91100
101+ if ( hasHover ) {
102+ dragCover = coverSlip ( ) ;
103+ dragCover . style . cursor = window . getComputedStyle ( options . element ) . cursor ;
104+ }
105+ else {
106+ // document acts as a dragcover for mobile, bc we can't create dragcover dynamically
107+ dragCover = document ;
108+ cursor = window . getComputedStyle ( document . documentElement ) . cursor ;
109+ document . documentElement . style . cursor = window . getComputedStyle ( options . element ) . cursor ;
110+ }
92111
93- // document acts as a dragcover for mobile, bc we can't create dragcover dynamically
94- document . addEventListener ( 'mousemove' , onMove ) ;
95- document . addEventListener ( 'mouseup' , onDone ) ;
96- document . addEventListener ( 'mouseout' , onDone ) ;
97- document . addEventListener ( 'touchmove' , onMove ) ;
98- document . addEventListener ( 'touchend' , onDone ) ;
99-
100- cursor = window . getComputedStyle ( document . documentElement ) . cursor ;
101- document . documentElement . style . cursor = window . getComputedStyle ( options . element ) . cursor ;
102-
112+ dragCover . addEventListener ( 'mousemove' , onMove ) ;
113+ dragCover . addEventListener ( 'mouseup' , onDone ) ;
114+ dragCover . addEventListener ( 'mouseout' , onDone ) ;
115+ dragCover . addEventListener ( 'touchmove' , onMove ) ;
116+ dragCover . addEventListener ( 'touchend' , onDone ) ;
103117
104118 return Lib . pauseEvent ( e ) ;
105119 }
@@ -123,14 +137,17 @@ dragElement.init = function init(options) {
123137 }
124138
125139 function onDone ( e ) {
126- document . removeEventListener ( 'mousemove' , onMove ) ;
127- document . removeEventListener ( 'mouseup' , onDone ) ;
128- document . removeEventListener ( 'mouseout' , onDone ) ;
129- document . removeEventListener ( 'touchmove' , onMove ) ;
130- document . removeEventListener ( 'touchend' , onDone ) ;
131-
132- if ( cursor ) {
133- document . documentElement . style . cursor = cursor ;
140+ dragCover . removeEventListener ( 'mousemove' , onMove ) ;
141+ dragCover . removeEventListener ( 'mouseup' , onDone ) ;
142+ dragCover . removeEventListener ( 'mouseout' , onDone ) ;
143+ dragCover . removeEventListener ( 'touchmove' , onMove ) ;
144+ dragCover . removeEventListener ( 'touchend' , onDone ) ;
145+
146+ if ( hasHover ) {
147+ Lib . removeElement ( dragCover ) ;
148+ }
149+ else if ( cursor ) {
150+ dragCover . documentElement . style . cursor = cursor ;
134151 cursor = null ;
135152 }
136153
0 commit comments