Rewrite AndroidSyncSettings to be significantly simpler.
[chromium-blink-merge.git] / remoting / webapp / app_remoting / js / drag_and_drop.js
blobdbe68d5e29ebfda3ef9c58cf36498a722ca54c7f
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.
5 /**
6 * @fileoverview
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.
11 'use strict';
13 /** @suppress {duplicate} */
14 var remoting = remoting || {};
16 /**
17 * @constructor
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) {
26 /**
27 * @private
29 this.element_ = element;
31 /**
32 * @private
34 this.dragUpdate_ = dragUpdate;
36 /**
37 * @private
39 this.dragStart_ = opt_dragStart;
41 /**
42 * @private
44 this.dragEnd_ = opt_dragEnd;
46 /**
47 * @type {number}
48 * @private
50 this.previousDeltaX_ = 0;
52 /**
53 * @type {number}
54 * @private
56 this.previousDeltaY_ = 0;
58 /**
59 * @type {boolean}
61 this.seenNonZeroDelta_ = false;
63 /**
64 * @type {function(Event):void}
65 * @private
67 this.callOnMouseUp_ = this.onMouseUp_.bind(this);
69 /**
70 * @type {function(Event):void}
71 * @private
73 this.callOnMouseMove_ = this.onMouseMove_.bind(this);
75 element.addEventListener('mousedown', this.onMouseDown_.bind(this), false);
78 /**
79 * @param {Event} event
81 remoting.DragAndDrop.prototype.onMouseDown_ = function(event) {
82 if (event.button != 0) {
83 return;
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_) {
92 this.dragStart_();
96 /**
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
116 * @return {number}
118 var adjustDelta = function(previous, current) {
119 var THRESHOLD = 100; // Based on observed values.
120 if (Math.abs(previous < THRESHOLD) && Math.abs(current) >= THRESHOLD) {
121 return 0;
123 return current;
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();
139 if (this.dragEnd_) {
140 this.dragEnd_();