1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 * Provide support for drag-and-drop operations in shaped windows. The
8 * standard API doesn't work because no "dragover" events are generated
9 * if the mouse moves outside the window region.
13 /** @suppress {duplicate} */
14 var remoting
= remoting
|| {};
18 * @param {Element} element The element to register for drag and drop.
19 * @param {function(number, number):void} dragUpdate Callback to receive the
20 * X and Y deltas as the element is dragged.
21 * @param {function():void=} opt_dragStart Initiation callback.
22 * @param {function():void=} opt_dragEnd Completion callback.
24 remoting
.DragAndDrop = function(element
, dragUpdate
,
25 opt_dragStart
, opt_dragEnd
) {
29 this.element_
= element
;
34 this.dragUpdate_
= dragUpdate
;
39 this.dragStart_
= opt_dragStart
;
44 this.dragEnd_
= opt_dragEnd
;
50 this.previousDeltaX_
= 0;
56 this.previousDeltaY_
= 0;
61 this.seenNonZeroDelta_
= false;
64 * @type {function(Event):void}
67 this.callOnMouseUp_
= this.onMouseUp_
.bind(this);
70 * @type {function(Event):void}
73 this.callOnMouseMove_
= this.onMouseMove_
.bind(this);
75 element
.addEventListener('mousedown', this.onMouseDown_
.bind(this), false);
79 * @param {Event} event
81 remoting
.DragAndDrop
.prototype.onMouseDown_ = function(event
) {
82 if (event
.button
!= 0) {
85 this.previousDeltaX_
= 0;
86 this.previousDeltaY_
= 0;
87 this.seenNonZeroDelta_
= false;
88 this.element_
.addEventListener('mousemove', this.callOnMouseMove_
, false);
89 this.element_
.addEventListener('mouseup', this.callOnMouseUp_
, false);
90 this.element_
.requestPointerLock();
91 if (this.dragStart_
) {
97 * TODO(jamiewalch): Remove the workarounds in this method once the pointer-lock
98 * API is fixed (crbug.com/419562).
100 * @param {Event} event
102 remoting
.DragAndDrop
.prototype.onMouseMove_ = function(event
) {
103 // Ignore the first non-zero delta. A click event will generate a bogus
104 // mousemove event, even if the mouse doesn't move.
105 if (!this.seenNonZeroDelta_
&&
106 (event
.movementX
!= 0 || event
.movementY
!= 0)) {
107 this.seenNonZeroDelta_
= true;
111 * The mouse lock API is buggy when used with shaped windows, and occasionally
112 * generates single, large deltas that must be filtered out.
114 * @param {number} previous
115 * @param {number} current
118 var adjustDelta = function(previous
, current
) {
119 var THRESHOLD
= 100; // Based on observed values.
120 if (Math
.abs(previous
< THRESHOLD
) && Math
.abs(current
) >= THRESHOLD
) {
125 this.previousDeltaX_
= adjustDelta(this.previousDeltaX_
, event
.movementX
);
126 this.previousDeltaY_
= adjustDelta(this.previousDeltaY_
, event
.movementY
);
127 if (this.previousDeltaX_
!= 0 || this.previousDeltaY_
!= 0) {
128 this.dragUpdate_(this.previousDeltaX_
, this.previousDeltaY_
);
133 * @param {Event} event
135 remoting
.DragAndDrop
.prototype.onMouseUp_ = function(event
) {
136 this.element_
.removeEventListener('mousemove', this.callOnMouseMove_
, false);
137 this.element_
.removeEventListener('mouseup', this.callOnMouseUp_
, false);
138 document
.exitPointerLock();