Home | History | Annotate | Download | only in ui
      1 // Copyright (c) 2013 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 'use strict';
      6 
      7 /**
      8  * @fileoverview A Mouse-event abtraction that waits for
      9  *   mousedown, then watches for subsequent mousemove events
     10  *   until the next mouseup event, then waits again.
     11  *   State changes are signaled with
     12  *      'mouse-tracker-start' : mousedown and tracking
     13  *      'mouse-tracker-move' : mouse move
     14  *      'mouse-tracker-end' : mouseup and not tracking.
     15  */
     16 
     17 base.exportTo('ui', function() {
     18 
     19   /**
     20    * @constructor
     21    * @param {HTMLElement} targetElement will recv events 'mouse-tracker-start',
     22    *     'mouse-tracker-move', 'mouse-tracker-end'.
     23    */
     24   function MouseTracker(targetElement) {
     25     this.targetElement_ = targetElement;
     26 
     27     this.onMouseDown_ = this.onMouseDown_.bind(this);
     28     this.onMouseMove_ = this.onMouseMove_.bind(this);
     29     this.onMouseUp_ = this.onMouseUp_.bind(this);
     30 
     31     this.targetElement_.addEventListener('mousedown', this.onMouseDown_);
     32   }
     33 
     34   MouseTracker.prototype = {
     35 
     36     onMouseDown_: function(e) {
     37       if (e.button !== 0)
     38         return true;
     39 
     40       e = this.remakeEvent_(e, 'mouse-tracker-start');
     41       this.targetElement_.dispatchEvent(e);
     42       document.addEventListener('mousemove', this.onMouseMove_);
     43       document.addEventListener('mouseup', this.onMouseUp_);
     44       this.targetElement_.addEventListener('blur', this.onMouseUp_);
     45       this.savePreviousUserSelect_ = document.body.style['-webkit-user-select'];
     46       document.body.style['-webkit-user-select'] = 'none';
     47       e.preventDefault();
     48       return true;
     49     },
     50 
     51     onMouseMove_: function(e) {
     52       e = this.remakeEvent_(e, 'mouse-tracker-move');
     53       this.targetElement_.dispatchEvent(e);
     54     },
     55 
     56     onMouseUp_: function(e) {
     57       document.removeEventListener('mousemove', this.onMouseMove_);
     58       document.removeEventListener('mouseup', this.onMouseUp_);
     59       this.targetElement_.removeEventListener('blur', this.onMouseUp_);
     60       document.body.style['-webkit-user-select'] =
     61           this.savePreviousUserSelect_;
     62       e = this.remakeEvent_(e, 'mouse-tracker-end');
     63       this.targetElement_.dispatchEvent(e);
     64     },
     65 
     66     remakeEvent_: function(e, newType) {
     67       var remade = new base.Event(newType, true, true);
     68       remade.x = e.x;
     69       remade.y = e.y;
     70       remade.offsetX = e.offsetX;
     71       remade.offsetY = e.offsetY;
     72       remade.clientX = e.clientX;
     73       remade.clientY = e.clientY;
     74       return remade;
     75     }
     76 
     77   };
     78 
     79   return {
     80     MouseTracker: MouseTracker
     81   };
     82 });
     83