| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 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. | |
| 10 */ | |
| 11 'use strict'; | |
| 12 | |
| 13 /** @suppress {duplicate} */ | |
| 14 var remoting = remoting || {}; | |
| 15 | |
| 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. | |
| 23 */ | |
| 24 remoting.DragAndDrop = function(element, dragUpdate, | |
| 25 opt_dragStart, opt_dragEnd) { | |
| 26 /** @private */ | |
| 27 this.element_ = element; | |
| 28 | |
| 29 /** @private */ | |
| 30 this.dragUpdate_ = dragUpdate; | |
| 31 | |
| 32 /** @private */ | |
| 33 this.dragStart_ = opt_dragStart; | |
| 34 | |
| 35 /** @private */ | |
| 36 this.dragEnd_ = opt_dragEnd; | |
| 37 | |
| 38 /** @private {number} */ | |
| 39 this.previousDeltaX_ = 0; | |
| 40 | |
| 41 /** @private {number} */ | |
| 42 this.previousDeltaY_ = 0; | |
| 43 | |
| 44 /** @type {boolean} */ | |
| 45 this.seenNonZeroDelta_ = false; | |
| 46 | |
| 47 /** @private {function(Event):void} */ | |
| 48 this.callOnMouseUp_ = this.onMouseUp_.bind(this); | |
| 49 | |
| 50 /** @private {function(Event):void} */ | |
| 51 this.callOnMouseMove_ = this.onMouseMove_.bind(this); | |
| 52 | |
| 53 element.addEventListener('mousedown', this.onMouseDown_.bind(this), false); | |
| 54 }; | |
| 55 | |
| 56 /** | |
| 57 * @param {Event} event | |
| 58 */ | |
| 59 remoting.DragAndDrop.prototype.onMouseDown_ = function(event) { | |
| 60 if (event.button != 0) { | |
| 61 return; | |
| 62 } | |
| 63 this.previousDeltaX_ = 0; | |
| 64 this.previousDeltaY_ = 0; | |
| 65 this.seenNonZeroDelta_ = false; | |
| 66 this.element_.addEventListener('mousemove', this.callOnMouseMove_, false); | |
| 67 this.element_.addEventListener('mouseup', this.callOnMouseUp_, false); | |
| 68 this.element_.requestPointerLock(); | |
| 69 if (this.dragStart_) { | |
| 70 this.dragStart_(); | |
| 71 } | |
| 72 }; | |
| 73 | |
| 74 /** | |
| 75 * TODO(jamiewalch): Remove the workarounds in this method once the pointer-lock | |
| 76 * API is fixed (crbug.com/419562). | |
| 77 * | |
| 78 * @param {Event} event | |
| 79 */ | |
| 80 remoting.DragAndDrop.prototype.onMouseMove_ = function(event) { | |
| 81 // Ignore the first non-zero delta. A click event will generate a bogus | |
| 82 // mousemove event, even if the mouse doesn't move. | |
| 83 if (!this.seenNonZeroDelta_ && | |
| 84 (event.movementX != 0 || event.movementY != 0)) { | |
| 85 this.seenNonZeroDelta_ = true; | |
| 86 } | |
| 87 | |
| 88 /** | |
| 89 * The mouse lock API is buggy when used with shaped windows, and occasionally | |
| 90 * generates single, large deltas that must be filtered out. | |
| 91 * | |
| 92 * @param {number} previous | |
| 93 * @param {number} current | |
| 94 * @return {number} | |
| 95 */ | |
| 96 var adjustDelta = function(previous, current) { | |
| 97 var THRESHOLD = 100; // Based on observed values. | |
| 98 if (Math.abs(previous < THRESHOLD) && Math.abs(current) >= THRESHOLD) { | |
| 99 return 0; | |
| 100 } | |
| 101 return current; | |
| 102 }; | |
| 103 this.previousDeltaX_ = adjustDelta(this.previousDeltaX_, event.movementX); | |
| 104 this.previousDeltaY_ = adjustDelta(this.previousDeltaY_, event.movementY); | |
| 105 if (this.previousDeltaX_ != 0 || this.previousDeltaY_ != 0) { | |
| 106 this.dragUpdate_(this.previousDeltaX_, this.previousDeltaY_); | |
| 107 } | |
| 108 }; | |
| 109 | |
| 110 /** | |
| 111 * @param {Event} event | |
| 112 */ | |
| 113 remoting.DragAndDrop.prototype.onMouseUp_ = function(event) { | |
| 114 this.element_.removeEventListener('mousemove', this.callOnMouseMove_, false); | |
| 115 this.element_.removeEventListener('mouseup', this.callOnMouseUp_, false); | |
| 116 document.exitPointerLock(); | |
| 117 if (this.dragEnd_) { | |
| 118 this.dragEnd_(); | |
| 119 } | |
| 120 }; | |
| OLD | NEW |